Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
8688bd2d
authored
Apr 10, 2019
by
eguven
Committed by
Oliver Woodman
Apr 13, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Rename DownloadState to Download
PiperOrigin-RevId: 242839480
parent
f0cd144b
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
767 additions
and
818 deletions
demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadState.java → library/core/src/main/java/com/google/android/exoplayer2/offline/Download.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadStateCursor.java → library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadCursor.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndexUtil.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloadIndexTest.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateBuilder.java → library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadBuilder.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadIndexUtilTest.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadTest.java
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationUtil.java
testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/TestDownloadManagerListener.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java
View file @
8688bd2d
...
...
@@ -16,9 +16,9 @@
package
com
.
google
.
android
.
exoplayer2
.
demo
;
import
android.app.Notification
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadService
;
import
com.google.android.exoplayer2.offline.DownloadState
;
import
com.google.android.exoplayer2.scheduler.PlatformScheduler
;
import
com.google.android.exoplayer2.ui.DownloadNotificationHelper
;
import
com.google.android.exoplayer2.util.NotificationUtil
;
...
...
@@ -61,26 +61,26 @@ public class DemoDownloadService extends DownloadService {
}
@Override
protected
Notification
getForegroundNotification
(
Download
State
[]
downloadState
s
)
{
protected
Notification
getForegroundNotification
(
Download
[]
download
s
)
{
return
notificationHelper
.
buildProgressNotification
(
R
.
drawable
.
ic_download
,
/* contentIntent= */
null
,
/* message= */
null
,
download
State
s
);
R
.
drawable
.
ic_download
,
/* contentIntent= */
null
,
/* message= */
null
,
downloads
);
}
@Override
protected
void
onDownload
StateChanged
(
DownloadState
downloadState
)
{
protected
void
onDownload
Changed
(
Download
download
)
{
Notification
notification
;
if
(
download
State
.
state
==
DownloadState
.
STATE_COMPLETED
)
{
if
(
download
.
state
==
Download
.
STATE_COMPLETED
)
{
notification
=
notificationHelper
.
buildDownloadCompletedNotification
(
R
.
drawable
.
ic_download_done
,
/* contentIntent= */
null
,
Util
.
fromUtf8Bytes
(
download
State
.
action
.
data
));
}
else
if
(
download
State
.
state
==
DownloadState
.
STATE_FAILED
)
{
Util
.
fromUtf8Bytes
(
download
.
action
.
data
));
}
else
if
(
download
.
state
==
Download
.
STATE_FAILED
)
{
notification
=
notificationHelper
.
buildDownloadFailedNotification
(
R
.
drawable
.
ic_download_done
,
/* contentIntent= */
null
,
Util
.
fromUtf8Bytes
(
download
State
.
action
.
data
));
Util
.
fromUtf8Bytes
(
download
.
action
.
data
));
}
else
{
return
;
}
...
...
demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java
View file @
8688bd2d
...
...
@@ -25,12 +25,12 @@ import com.google.android.exoplayer2.C;
import
com.google.android.exoplayer2.RenderersFactory
;
import
com.google.android.exoplayer2.offline.ActionFile
;
import
com.google.android.exoplayer2.offline.DefaultDownloadIndex
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.DownloadAction
;
import
com.google.android.exoplayer2.offline.DownloadCursor
;
import
com.google.android.exoplayer2.offline.DownloadHelper
;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadService
;
import
com.google.android.exoplayer2.offline.DownloadState
;
import
com.google.android.exoplayer2.offline.DownloadStateCursor
;
import
com.google.android.exoplayer2.offline.StreamKey
;
import
com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo
;
import
com.google.android.exoplayer2.upstream.DataSource
;
...
...
@@ -63,7 +63,7 @@ public class DownloadTracker implements DownloadManager.Listener {
private
final
Context
context
;
private
final
DataSource
.
Factory
dataSourceFactory
;
private
final
CopyOnWriteArraySet
<
Listener
>
listeners
;
private
final
HashMap
<
Uri
,
Download
State
>
downloadState
s
;
private
final
HashMap
<
Uri
,
Download
>
download
s
;
private
final
DefaultDownloadIndex
downloadIndex
;
@Nullable
private
StartDownloadDialogHelper
startDownloadDialogHelper
;
...
...
@@ -74,7 +74,7 @@ public class DownloadTracker implements DownloadManager.Listener {
this
.
dataSourceFactory
=
dataSourceFactory
;
this
.
downloadIndex
=
downloadIndex
;
listeners
=
new
CopyOnWriteArraySet
<>();
download
State
s
=
new
HashMap
<>();
downloads
=
new
HashMap
<>();
loadDownloads
();
}
...
...
@@ -87,15 +87,15 @@ public class DownloadTracker implements DownloadManager.Listener {
}
public
boolean
isDownloaded
(
Uri
uri
)
{
Download
State
downloadState
=
downloadState
s
.
get
(
uri
);
return
download
State
!=
null
&&
downloadState
.
state
!=
DownloadState
.
STATE_FAILED
;
Download
download
=
download
s
.
get
(
uri
);
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
;
}
@SuppressWarnings
(
"unchecked"
)
public
List
<
StreamKey
>
getOfflineStreamKeys
(
Uri
uri
)
{
Download
State
downloadState
=
downloadState
s
.
get
(
uri
);
return
download
State
!=
null
&&
downloadState
.
state
!=
DownloadState
.
STATE_FAILED
?
download
State
.
action
.
streamKeys
Download
download
=
download
s
.
get
(
uri
);
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
?
download
.
action
.
streamKeys
:
Collections
.
emptyList
();
}
...
...
@@ -105,10 +105,10 @@ public class DownloadTracker implements DownloadManager.Listener {
Uri
uri
,
String
extension
,
RenderersFactory
renderersFactory
)
{
Download
State
downloadState
=
downloadState
s
.
get
(
uri
);
if
(
download
State
!=
null
)
{
Download
download
=
download
s
.
get
(
uri
);
if
(
download
!=
null
)
{
DownloadService
.
startWithRemoveDownload
(
context
,
DemoDownloadService
.
class
,
download
State
.
action
.
id
,
/* foreground= */
false
);
context
,
DemoDownloadService
.
class
,
download
.
action
.
id
,
/* foreground= */
false
);
}
else
{
if
(
startDownloadDialogHelper
!=
null
)
{
startDownloadDialogHelper
.
release
();
...
...
@@ -122,16 +122,16 @@ public class DownloadTracker implements DownloadManager.Listener {
// DownloadManager.Listener
@Override
public
void
onDownload
StateChanged
(
DownloadManager
downloadManager
,
DownloadState
downloadState
)
{
download
States
.
put
(
downloadState
.
action
.
uri
,
downloadState
);
public
void
onDownload
Changed
(
DownloadManager
downloadManager
,
Download
download
)
{
download
s
.
put
(
download
.
action
.
uri
,
download
);
for
(
Listener
listener
:
listeners
)
{
listener
.
onDownloadsChanged
();
}
}
@Override
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
State
downloadState
)
{
download
States
.
remove
(
downloadState
.
action
.
uri
);
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
download
)
{
download
s
.
remove
(
download
.
action
.
uri
);
for
(
Listener
listener
:
listeners
)
{
listener
.
onDownloadsChanged
();
}
...
...
@@ -140,10 +140,10 @@ public class DownloadTracker implements DownloadManager.Listener {
// Internal methods
private
void
loadDownloads
()
{
try
(
Download
StateCursor
loadedDownloadStates
=
downloadIndex
.
getDownloadState
s
())
{
while
(
loadedDownload
State
s
.
moveToNext
())
{
Download
State
downloadState
=
loadedDownloadStates
.
getDownloadState
();
download
States
.
put
(
downloadState
.
action
.
uri
,
downloadState
);
try
(
Download
Cursor
loadedDownloads
=
downloadIndex
.
getDownload
s
())
{
while
(
loadedDownloads
.
moveToNext
())
{
Download
download
=
loadedDownloads
.
getDownload
();
download
s
.
put
(
download
.
action
.
uri
,
download
);
}
}
catch
(
IOException
e
)
{
Log
.
w
(
TAG
,
"Failed to query download states"
,
e
);
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java
View file @
8688bd2d
...
...
@@ -33,7 +33,7 @@ import java.util.ArrayList;
import
java.util.List
;
/**
* A {@link DownloadIndex} which uses SQLite to persist {@link Download
State
}s.
* A {@link DownloadIndex} which uses SQLite to persist {@link Download}s.
*
* <p class="caution">Database access may take a long time, do not call methods of this class from
* the application main thread.
...
...
@@ -88,7 +88,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private
static
final
String
WHERE_ID_EQUALS
=
COLUMN_ID
+
" = ?"
;
private
static
final
String
WHERE_STATE_TERMINAL
=
getStateQuery
(
Download
State
.
STATE_COMPLETED
,
DownloadState
.
STATE_FAILED
);
getStateQuery
(
Download
.
STATE_COMPLETED
,
Download
.
STATE_FAILED
);
private
static
final
String
[]
COLUMNS
=
new
String
[]
{
...
...
@@ -153,8 +153,8 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private
boolean
initialized
;
/**
* Creates a DefaultDownloadIndex which stores the {@link Download
State}s on a SQLite database
*
provided
by {@code databaseProvider}.
* Creates a DefaultDownloadIndex which stores the {@link Download
}s on a SQLite database provided
* by {@code databaseProvider}.
*
* @param databaseProvider A DatabaseProvider which provides the database which will be used to
* store DownloadStatus table.
...
...
@@ -165,52 +165,51 @@ public final class DefaultDownloadIndex implements DownloadIndex {
@Override
@Nullable
public
Download
State
getDownloadState
(
String
id
)
throws
DatabaseIOException
{
public
Download
getDownload
(
String
id
)
throws
DatabaseIOException
{
ensureInitialized
();
try
(
Cursor
cursor
=
getCursor
(
WHERE_ID_EQUALS
,
new
String
[]
{
id
}))
{
if
(
cursor
.
getCount
()
==
0
)
{
return
null
;
}
cursor
.
moveToNext
();
return
getDownload
State
ForCurrentRow
(
cursor
);
return
getDownloadForCurrentRow
(
cursor
);
}
catch
(
SQLiteException
e
)
{
throw
new
DatabaseIOException
(
e
);
}
}
@Override
public
DownloadStateCursor
getDownloadStates
(
@DownloadState
.
State
int
...
states
)
throws
DatabaseIOException
{
public
DownloadCursor
getDownloads
(
@Download
.
State
int
...
states
)
throws
DatabaseIOException
{
ensureInitialized
();
Cursor
cursor
=
getCursor
(
getStateQuery
(
states
),
/* selectionArgs= */
null
);
return
new
Download
State
CursorImpl
(
cursor
);
return
new
DownloadCursorImpl
(
cursor
);
}
/**
* Adds or replaces a {@link Download
State
}.
* Adds or replaces a {@link Download}.
*
* @param download
State The {@link DownloadState
} to be added.
* @param download
The {@link Download
} to be added.
* @throws DatabaseIOException If an error occurs setting the state.
*/
public
void
putDownload
State
(
DownloadState
downloadState
)
throws
DatabaseIOException
{
public
void
putDownload
(
Download
download
)
throws
DatabaseIOException
{
ensureInitialized
();
ContentValues
values
=
new
ContentValues
();
values
.
put
(
COLUMN_ID
,
download
State
.
action
.
id
);
values
.
put
(
COLUMN_TYPE
,
download
State
.
action
.
type
);
values
.
put
(
COLUMN_URI
,
download
State
.
action
.
uri
.
toString
());
values
.
put
(
COLUMN_STREAM_KEYS
,
encodeStreamKeys
(
download
State
.
action
.
streamKeys
));
values
.
put
(
COLUMN_CUSTOM_CACHE_KEY
,
download
State
.
action
.
customCacheKey
);
values
.
put
(
COLUMN_DATA
,
download
State
.
action
.
data
);
values
.
put
(
COLUMN_STATE
,
download
State
.
state
);
values
.
put
(
COLUMN_DOWNLOAD_PERCENTAGE
,
download
State
.
getDownloadPercentage
());
values
.
put
(
COLUMN_DOWNLOADED_BYTES
,
download
State
.
getDownloadedBytes
());
values
.
put
(
COLUMN_TOTAL_BYTES
,
download
State
.
getTotalBytes
());
values
.
put
(
COLUMN_FAILURE_REASON
,
download
State
.
failureReason
);
values
.
put
(
COLUMN_ID
,
download
.
action
.
id
);
values
.
put
(
COLUMN_TYPE
,
download
.
action
.
type
);
values
.
put
(
COLUMN_URI
,
download
.
action
.
uri
.
toString
());
values
.
put
(
COLUMN_STREAM_KEYS
,
encodeStreamKeys
(
download
.
action
.
streamKeys
));
values
.
put
(
COLUMN_CUSTOM_CACHE_KEY
,
download
.
action
.
customCacheKey
);
values
.
put
(
COLUMN_DATA
,
download
.
action
.
data
);
values
.
put
(
COLUMN_STATE
,
download
.
state
);
values
.
put
(
COLUMN_DOWNLOAD_PERCENTAGE
,
download
.
getDownloadPercentage
());
values
.
put
(
COLUMN_DOWNLOADED_BYTES
,
download
.
getDownloadedBytes
());
values
.
put
(
COLUMN_TOTAL_BYTES
,
download
.
getTotalBytes
());
values
.
put
(
COLUMN_FAILURE_REASON
,
download
.
failureReason
);
values
.
put
(
COLUMN_STOP_FLAGS
,
0
);
values
.
put
(
COLUMN_NOT_MET_REQUIREMENTS
,
0
);
values
.
put
(
COLUMN_MANUAL_STOP_REASON
,
download
State
.
manualStopReason
);
values
.
put
(
COLUMN_START_TIME_MS
,
download
State
.
startTimeMs
);
values
.
put
(
COLUMN_UPDATE_TIME_MS
,
download
State
.
updateTimeMs
);
values
.
put
(
COLUMN_MANUAL_STOP_REASON
,
download
.
manualStopReason
);
values
.
put
(
COLUMN_START_TIME_MS
,
download
.
startTimeMs
);
values
.
put
(
COLUMN_UPDATE_TIME_MS
,
download
.
updateTimeMs
);
try
{
SQLiteDatabase
writableDatabase
=
databaseProvider
.
getWritableDatabase
();
writableDatabase
.
replaceOrThrow
(
TABLE_NAME
,
/* nullColumnHack= */
null
,
values
);
...
...
@@ -220,12 +219,12 @@ public final class DefaultDownloadIndex implements DownloadIndex {
}
/**
* Removes the {@link Download
State
} with the given {@code id}.
* Removes the {@link Download} with the given {@code id}.
*
* @param id ID of a {@link Download
State
}.
* @param id ID of a {@link Download}.
* @throws DatabaseIOException If an error occurs removing the state.
*/
public
void
removeDownload
State
(
String
id
)
throws
DatabaseIOException
{
public
void
removeDownload
(
String
id
)
throws
DatabaseIOException
{
ensureInitialized
();
try
{
databaseProvider
.
getWritableDatabase
().
delete
(
TABLE_NAME
,
WHERE_ID_EQUALS
,
new
String
[]
{
id
});
...
...
@@ -236,7 +235,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
/**
* Sets the manual stop reason of the downloads in a terminal state ({@link
* Download
State#STATE_COMPLETED}, {@link DownloadState
#STATE_FAILED}).
* Download
#STATE_COMPLETED}, {@link Download
#STATE_FAILED}).
*
* @param manualStopReason The manual stop reason.
* @throws DatabaseIOException If an error occurs updating the state.
...
...
@@ -255,12 +254,12 @@ public final class DefaultDownloadIndex implements DownloadIndex {
/**
* Sets the manual stop reason of the download with the given {@code id} in a terminal state
* ({@link Download
State#STATE_COMPLETED}, {@link DownloadState
#STATE_FAILED}).
* ({@link Download
#STATE_COMPLETED}, {@link Download
#STATE_FAILED}).
*
* <p>If there's no {@link Download
State} with the given {@code id} or it isn't in a terminal
*
state,
then nothing happens.
* <p>If there's no {@link Download
} with the given {@code id} or it isn't in a terminal state,
* then nothing happens.
*
* @param id ID of a {@link Download
State
}.
* @param id ID of a {@link Download}.
* @param manualStopReason The manual stop reason.
* @throws DatabaseIOException If an error occurs updating the state.
*/
...
...
@@ -326,7 +325,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
}
}
private
static
String
getStateQuery
(
@Download
State
.
State
int
...
states
)
{
private
static
String
getStateQuery
(
@Download
.
State
int
...
states
)
{
if
(
states
.
length
==
0
)
{
return
TRUE
;
}
...
...
@@ -342,7 +341,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
return
selectionBuilder
.
toString
();
}
private
static
Download
State
getDownloadState
ForCurrentRow
(
Cursor
cursor
)
{
private
static
Download
getDownload
ForCurrentRow
(
Cursor
cursor
)
{
DownloadAction
action
=
new
DownloadAction
(
cursor
.
getString
(
COLUMN_INDEX_ID
),
...
...
@@ -355,7 +354,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
cachingCounters
.
alreadyCachedBytes
=
cursor
.
getLong
(
COLUMN_INDEX_DOWNLOADED_BYTES
);
cachingCounters
.
contentLength
=
cursor
.
getLong
(
COLUMN_INDEX_TOTAL_BYTES
);
cachingCounters
.
percentage
=
cursor
.
getFloat
(
COLUMN_INDEX_DOWNLOAD_PERCENTAGE
);
return
new
Download
State
(
return
new
Download
(
action
,
cursor
.
getInt
(
COLUMN_INDEX_STATE
),
cursor
.
getInt
(
COLUMN_INDEX_FAILURE_REASON
),
...
...
@@ -401,17 +400,17 @@ public final class DefaultDownloadIndex implements DownloadIndex {
return
streamKeys
;
}
private
static
final
class
Download
StateCursorImpl
implements
DownloadState
Cursor
{
private
static
final
class
Download
CursorImpl
implements
Download
Cursor
{
private
final
Cursor
cursor
;
private
Download
State
CursorImpl
(
Cursor
cursor
)
{
private
DownloadCursorImpl
(
Cursor
cursor
)
{
this
.
cursor
=
cursor
;
}
@Override
public
Download
State
getDownloadState
()
{
return
getDownload
State
ForCurrentRow
(
cursor
);
public
Download
getDownload
()
{
return
getDownloadForCurrentRow
(
cursor
);
}
@Override
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/Download
State
.java
→
library/core/src/main/java/com/google/android/exoplayer2/offline/Download.java
View file @
8688bd2d
...
...
@@ -24,7 +24,7 @@ import java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy
;
/** Represents state of a download. */
public
final
class
Download
State
{
public
final
class
Download
{
/**
* Download states. One of {@link #STATE_QUEUED}, {@link #STATE_STOPPED}, {@link
...
...
@@ -128,15 +128,15 @@ public final class DownloadState {
/*package*/
CachingCounters
counters
;
/**
* Creates a {@link Download
State
} using a {@link DownloadAction}.
* Creates a {@link Download} using a {@link DownloadAction}.
*
* @param action The {@link DownloadAction}.
*/
public
Download
State
(
DownloadAction
action
)
{
public
Download
(
DownloadAction
action
)
{
this
(
action
,
System
.
currentTimeMillis
());
}
private
Download
State
(
DownloadAction
action
,
long
currentTimeMs
)
{
private
Download
(
DownloadAction
action
,
long
currentTimeMs
)
{
this
(
action
,
/* state= */
STATE_QUEUED
,
...
...
@@ -147,7 +147,7 @@ public final class DownloadState {
new
CachingCounters
());
}
/* package */
Download
State
(
/* package */
Download
(
DownloadAction
action
,
@State
int
state
,
@FailureReason
int
failureReason
,
...
...
@@ -170,15 +170,15 @@ public final class DownloadState {
}
/**
* Merges the given {@link DownloadAction} and creates a new {@link Download
State}. The action
*
must
have the same id and type.
* Merges the given {@link DownloadAction} and creates a new {@link Download
}. The action must
* have the same id and type.
*
* @param newAction The {@link DownloadAction} to be merged.
* @param canStart Whether the download is eligible to be started.
* @return A new {@link Download
State
}.
* @return A new {@link Download}.
*/
public
Download
State
copyWithMergedAction
(
DownloadAction
newAction
,
boolean
canStart
)
{
return
new
Download
State
(
public
Download
copyWithMergedAction
(
DownloadAction
newAction
,
boolean
canStart
)
{
return
new
Download
(
action
.
copyWithMergedAction
(
newAction
),
getNextState
(
state
,
canStart
&&
manualStopReason
==
0
),
FAILURE_REASON_NONE
,
...
...
@@ -193,8 +193,8 @@ public final class DownloadState {
*
* @param state The {@link State}.
*/
public
Download
State
copyWithState
(
@State
int
state
)
{
return
new
Download
State
(
public
Download
copyWithState
(
@State
int
state
)
{
return
new
Download
(
action
,
state
,
FAILURE_REASON_NONE
,
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/Download
State
Cursor.java
→
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadCursor.java
View file @
8688bd2d
...
...
@@ -18,19 +18,19 @@ package com.google.android.exoplayer2.offline;
import
java.io.Closeable
;
/** Provides random read-write access to the result set returned by a database query. */
public
interface
Download
State
Cursor
extends
Closeable
{
public
interface
DownloadCursor
extends
Closeable
{
/** Returns the
DownloadState
at the current position. */
Download
State
getDownloadState
();
/** Returns the
download
at the current position. */
Download
getDownload
();
/** Returns the numbers of
DownloadState
s in the cursor. */
/** Returns the numbers of
download
s in the cursor. */
int
getCount
();
/**
* Returns the current position of the cursor in the
DownloadState set. The value is zero-based.
*
When the DownloadState set is first returned the cursor will be at positon -1, which is before
*
the first DownloadState. After the last DownloadState is returned another call to next() will
*
leave the cursor past
the last entry, at a position of count().
* Returns the current position of the cursor in the
download set. The value is zero-based. When
*
the download set is first returned the cursor will be at positon -1, which is before the first
*
download. After the last download is returned another call to next() will leave the cursor past
* the last entry, at a position of count().
*
* @return the current cursor position.
*/
...
...
@@ -49,7 +49,7 @@ public interface DownloadStateCursor extends Closeable {
boolean
moveToPosition
(
int
position
);
/**
* Move the cursor to the first
DownloadState
.
* Move the cursor to the first
download
.
*
* <p>This method will return false if the cursor is empty.
*
...
...
@@ -60,7 +60,7 @@ public interface DownloadStateCursor extends Closeable {
}
/**
* Move the cursor to the last
DownloadState
.
* Move the cursor to the last
download
.
*
* <p>This method will return false if the cursor is empty.
*
...
...
@@ -71,7 +71,7 @@ public interface DownloadStateCursor extends Closeable {
}
/**
* Move the cursor to the next
DownloadState
.
* Move the cursor to the next
download
.
*
* <p>This method will return false if the cursor is already past the last entry in the result
* set.
...
...
@@ -83,7 +83,7 @@ public interface DownloadStateCursor extends Closeable {
}
/**
* Move the cursor to the previous
DownloadState
.
* Move the cursor to the previous
download
.
*
* <p>This method will return false if the cursor is already before the first entry in the result
* set.
...
...
@@ -94,18 +94,18 @@ public interface DownloadStateCursor extends Closeable {
return
moveToPosition
(
getPosition
()
-
1
);
}
/** Returns whether the cursor is pointing to the first
DownloadState
. */
/** Returns whether the cursor is pointing to the first
download
. */
default
boolean
isFirst
()
{
return
getPosition
()
==
0
&&
getCount
()
!=
0
;
}
/** Returns whether the cursor is pointing to the last
DownloadState
. */
/** Returns whether the cursor is pointing to the last
download
. */
default
boolean
isLast
()
{
int
count
=
getCount
();
return
getPosition
()
==
(
count
-
1
)
&&
count
!=
0
;
}
/** Returns whether the cursor is pointing to the position before the first
DownloadState
. */
/** Returns whether the cursor is pointing to the position before the first
download
. */
default
boolean
isBeforeFirst
()
{
if
(
getCount
()
==
0
)
{
return
true
;
...
...
@@ -113,7 +113,7 @@ public interface DownloadStateCursor extends Closeable {
return
getPosition
()
==
-
1
;
}
/** Returns whether the cursor is pointing to the position after the last
DownloadState
. */
/** Returns whether the cursor is pointing to the position after the last
download
. */
default
boolean
isAfterLast
()
{
if
(
getCount
()
==
0
)
{
return
true
;
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndex.java
View file @
8688bd2d
...
...
@@ -18,27 +18,26 @@ package com.google.android.exoplayer2.offline;
import
androidx.annotation.Nullable
;
import
java.io.IOException
;
/** Persists {@link Download
State
}s. */
/** Persists {@link Download}s. */
public
interface
DownloadIndex
{
/**
* Returns the {@link Download
State
} with the given {@code id}, or null.
* Returns the {@link Download} with the given {@code id}, or null.
*
* @param id ID of a {@link Download
State
}.
* @return The {@link Download
State} with the given {@code id}, or null if a download state with
*
this
id doesn't exist.
* @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.
* @throws IOException If an error occurs reading the state.
*/
@Nullable
Download
State
getDownloadState
(
String
id
)
throws
IOException
;
Download
getDownload
(
String
id
)
throws
IOException
;
/**
* Returns a {@link Download
StateCursor} to {@link DownloadState
}s with the given {@code states}.
* Returns a {@link Download
Cursor} to {@link Download
}s with the given {@code states}.
*
* @param states Returns only the {@link Download
State
}s with this states. If empty, returns all.
* @return A cursor to {@link Download
State
}s with the given {@code states}.
* @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.
*/
DownloadStateCursor
getDownloadStates
(
@DownloadState
.
State
int
...
states
)
throws
IOException
;
DownloadCursor
getDownloads
(
@Download
.
State
int
...
states
)
throws
IOException
;
}
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadIndexUtil.java
View file @
8688bd2d
...
...
@@ -69,12 +69,12 @@ public final class DownloadIndexUtil {
*/
/* package */
static
void
mergeAction
(
DownloadAction
action
,
DefaultDownloadIndex
downloadIndex
)
throws
IOException
{
Download
State
downloadState
=
downloadIndex
.
getDownloadState
(
action
.
id
);
if
(
download
State
!=
null
)
{
download
State
=
downloadState
.
copyWithMergedAction
(
action
,
/* canStart= */
true
);
Download
download
=
downloadIndex
.
getDownload
(
action
.
id
);
if
(
download
!=
null
)
{
download
=
download
.
copyWithMergedAction
(
action
,
/* canStart= */
true
);
}
else
{
download
State
=
new
DownloadState
(
action
);
download
=
new
Download
(
action
);
}
downloadIndex
.
putDownload
State
(
downloadState
);
downloadIndex
.
putDownload
(
download
);
}
}
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java
View file @
8688bd2d
...
...
@@ -15,17 +15,17 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
offline
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
FAILURE_REASON_NONE
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
FAILURE_REASON_UNKNOWN
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
MANUAL_STOP_REASON_NONE
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
MANUAL_STOP_REASON_UNDEFINED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_COMPLETED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_DOWNLOADING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_FAILED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_QUEUED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_REMOVING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_RESTARTING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
State
.
STATE_STOPPED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
FAILURE_REASON_NONE
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
FAILURE_REASON_UNKNOWN
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
MANUAL_STOP_REASON_NONE
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
MANUAL_STOP_REASON_UNDEFINED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_COMPLETED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_DOWNLOADING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_FAILED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_QUEUED
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_REMOVING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_RESTARTING
;
import
static
com
.
google
.
android
.
exoplayer2
.
offline
.
Download
.
STATE_STOPPED
;
import
android.content.Context
;
import
android.os.Handler
;
...
...
@@ -74,18 +74,17 @@ public final class DownloadManager {
* Called when the state of a download changes.
*
* @param downloadManager The reporting instance.
* @param download
State
The state of the download.
* @param download The state of the download.
*/
default
void
onDownloadStateChanged
(
DownloadManager
downloadManager
,
DownloadState
downloadState
)
{}
default
void
onDownloadChanged
(
DownloadManager
downloadManager
,
Download
download
)
{}
/**
* Called when a download is removed.
*
* @param downloadManager The reporting instance.
* @param download
State
The last state of the download before it was removed.
* @param download The last state of the download before it was removed.
*/
default
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
State
downloadState
)
{}
default
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
download
)
{}
/**
* Called when there is no active download left.
...
...
@@ -160,11 +159,11 @@ public final class DownloadManager {
// Collections that are accessed on the main thread.
private
final
CopyOnWriteArraySet
<
Listener
>
listeners
;
private
final
ArrayList
<
Download
State
>
downloadState
s
;
private
final
ArrayList
<
Download
>
download
s
;
// Collections that are accessed on the internal thread.
private
final
ArrayList
<
Download
>
download
s
;
private
final
HashMap
<
Download
,
DownloadThread
>
activeDownloads
;
private
final
ArrayList
<
Download
Internal
>
downloadInternal
s
;
private
final
HashMap
<
Download
Internal
,
DownloadThread
>
activeDownloads
;
// Mutable fields that are accessed on the main thread.
private
int
pendingMessages
;
...
...
@@ -246,8 +245,8 @@ public final class DownloadManager {
this
.
minRetryCount
=
minRetryCount
;
manualStopReason
=
MANUAL_STOP_REASON_UNDEFINED
;
downloadInternals
=
new
ArrayList
<>();
downloads
=
new
ArrayList
<>();
downloadStates
=
new
ArrayList
<>();
activeDownloads
=
new
HashMap
<>();
listeners
=
new
CopyOnWriteArraySet
<>();
releaseLock
=
new
Object
();
...
...
@@ -285,12 +284,12 @@ public final class DownloadManager {
/** Returns the number of downloads. */
public
int
getDownloadCount
()
{
return
download
State
s
.
size
();
return
downloads
.
size
();
}
/** Returns the states of all current downloads. */
public
Download
State
[]
getAllDownloadState
s
()
{
return
download
States
.
toArray
(
new
DownloadState
[
0
]);
public
Download
[]
getAllDownload
s
()
{
return
download
s
.
toArray
(
new
Download
[
0
]);
}
/** Returns the requirements needed to be met to start downloads. */
...
...
@@ -347,9 +346,9 @@ public final class DownloadManager {
* Sets a manual stop reason for all downloads.
*
* @param manualStopReason An application defined stop reason. Value {@value
* Download
State
#MANUAL_STOP_REASON_NONE} is not allowed and value {@value
* Download
State
#MANUAL_STOP_REASON_UNDEFINED} is reserved for {@link
* Download
State
#MANUAL_STOP_REASON_UNDEFINED}.
* Download#MANUAL_STOP_REASON_NONE} is not allowed and value {@value
* Download#MANUAL_STOP_REASON_UNDEFINED} is reserved for {@link
* Download#MANUAL_STOP_REASON_UNDEFINED}.
*/
public
void
stopDownloads
(
int
manualStopReason
)
{
Assertions
.
checkArgument
(
manualStopReason
!=
MANUAL_STOP_REASON_NONE
);
...
...
@@ -382,9 +381,9 @@ public final class DownloadManager {
*
* @param id The unique content id of the download to be stopped.
* @param manualStopReason An application defined stop reason. Value {@value
* Download
State
#MANUAL_STOP_REASON_NONE} is not allowed and value {@value
* Download
State
#MANUAL_STOP_REASON_UNDEFINED} is reserved for {@link
* Download
State
#MANUAL_STOP_REASON_UNDEFINED}.
* Download#MANUAL_STOP_REASON_NONE} is not allowed and value {@value
* Download#MANUAL_STOP_REASON_UNDEFINED} is reserved for {@link
* Download#MANUAL_STOP_REASON_UNDEFINED}.
*/
public
void
stopDownload
(
String
id
,
int
manualStopReason
)
{
Assertions
.
checkArgument
(
manualStopReason
!=
MANUAL_STOP_REASON_NONE
);
...
...
@@ -439,7 +438,7 @@ public final class DownloadManager {
pendingMessages
=
0
;
activeDownloadCount
=
0
;
initialized
=
false
;
download
State
s
.
clear
();
downloads
.
clear
();
}
}
...
...
@@ -469,15 +468,15 @@ public final class DownloadManager {
private
boolean
handleMainMessage
(
Message
message
)
{
switch
(
message
.
what
)
{
case
MSG_INITIALIZED:
List
<
Download
State
>
downloadStates
=
(
List
<
DownloadState
>)
message
.
obj
;
onInitialized
(
download
State
s
);
List
<
Download
>
downloads
=
(
List
<
Download
>)
message
.
obj
;
onInitialized
(
downloads
);
break
;
case
MSG_DOWNLOAD_STATE_CHANGED:
Download
State
state
=
(
DownloadState
)
message
.
obj
;
onDownload
State
Changed
(
state
);
Download
state
=
(
Download
)
message
.
obj
;
onDownloadChanged
(
state
);
break
;
case
MSG_DOWNLOAD_REMOVED:
state
=
(
Download
State
)
message
.
obj
;
state
=
(
Download
)
message
.
obj
;
onDownloadRemoved
(
state
);
break
;
case
MSG_PROCESSED:
...
...
@@ -493,34 +492,34 @@ public final class DownloadManager {
// TODO: Merge these three events into a single MSG_STATE_CHANGE that can carry all updates. This
// allows updating idle at the same point as the downloads that can be queried changes.
private
void
onInitialized
(
List
<
Download
State
>
downloadState
s
)
{
private
void
onInitialized
(
List
<
Download
>
download
s
)
{
initialized
=
true
;
this
.
download
States
.
addAll
(
downloadState
s
);
this
.
download
s
.
addAll
(
download
s
);
for
(
Listener
listener
:
listeners
)
{
listener
.
onInitialized
(
DownloadManager
.
this
);
}
}
private
void
onDownload
StateChanged
(
DownloadState
downloadState
)
{
int
download
StateIndex
=
getDownloadStateIndex
(
downloadState
.
action
.
id
);
if
(
download
State
.
state
==
STATE_COMPLETED
||
downloadState
.
state
==
STATE_FAILED
)
{
if
(
download
State
Index
!=
C
.
INDEX_UNSET
)
{
download
States
.
remove
(
downloadState
Index
);
private
void
onDownload
Changed
(
Download
download
)
{
int
download
Index
=
getDownloadIndex
(
download
.
action
.
id
);
if
(
download
.
state
==
STATE_COMPLETED
||
download
.
state
==
STATE_FAILED
)
{
if
(
downloadIndex
!=
C
.
INDEX_UNSET
)
{
download
s
.
remove
(
download
Index
);
}
}
else
if
(
download
State
Index
!=
C
.
INDEX_UNSET
)
{
download
States
.
set
(
downloadStateIndex
,
downloadState
);
}
else
if
(
downloadIndex
!=
C
.
INDEX_UNSET
)
{
download
s
.
set
(
downloadIndex
,
download
);
}
else
{
download
States
.
add
(
downloadState
);
download
s
.
add
(
download
);
}
for
(
Listener
listener
:
listeners
)
{
listener
.
onDownload
StateChanged
(
this
,
downloadState
);
listener
.
onDownload
Changed
(
this
,
download
);
}
}
private
void
onDownloadRemoved
(
Download
State
downloadState
)
{
download
States
.
remove
(
getDownloadStateIndex
(
downloadState
.
action
.
id
));
private
void
onDownloadRemoved
(
Download
download
)
{
download
s
.
remove
(
getDownloadIndex
(
download
.
action
.
id
));
for
(
Listener
listener
:
listeners
)
{
listener
.
onDownloadRemoved
(
this
,
download
State
);
listener
.
onDownloadRemoved
(
this
,
download
);
}
}
...
...
@@ -534,9 +533,9 @@ public final class DownloadManager {
}
}
private
int
getDownload
State
Index
(
String
id
)
{
for
(
int
i
=
0
;
i
<
download
State
s
.
size
();
i
++)
{
if
(
download
State
s
.
get
(
i
).
action
.
id
.
equals
(
id
))
{
private
int
getDownloadIndex
(
String
id
)
{
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
if
(
downloads
.
get
(
i
).
action
.
id
.
equals
(
id
))
{
return
i
;
}
}
...
...
@@ -588,16 +587,16 @@ public final class DownloadManager {
private
void
setManualStopReasonInternal
(
@Nullable
String
id
,
int
manualStopReason
)
{
if
(
id
!=
null
)
{
Download
download
=
getDownload
(
id
);
if
(
download
!=
null
)
{
logd
(
"download manual stop reason is set to : "
+
manualStopReason
,
download
);
download
.
setManualStopReason
(
manualStopReason
);
Download
Internal
downloadInternal
=
getDownload
(
id
);
if
(
download
Internal
!=
null
)
{
logd
(
"download manual stop reason is set to : "
+
manualStopReason
,
download
Internal
);
download
Internal
.
setManualStopReason
(
manualStopReason
);
return
;
}
}
else
{
this
.
manualStopReason
=
manualStopReason
;
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
downloads
.
get
(
i
).
setManualStopReason
(
manualStopReason
);
for
(
int
i
=
0
;
i
<
download
Internal
s
.
size
();
i
++)
{
download
Internal
s
.
get
(
i
).
setManualStopReason
(
manualStopReason
);
}
}
try
{
...
...
@@ -612,60 +611,59 @@ public final class DownloadManager {
}
private
void
addDownloadInternal
(
DownloadAction
action
)
{
Download
download
=
getDownload
(
action
.
id
);
if
(
download
!=
null
)
{
download
.
addAction
(
action
);
logd
(
"Action is added to existing download"
,
download
);
Download
Internal
downloadInternal
=
getDownload
(
action
.
id
);
if
(
download
Internal
!=
null
)
{
download
Internal
.
addAction
(
action
);
logd
(
"Action is added to existing download"
,
download
Internal
);
}
else
{
Download
State
downloadState
=
loadDownloadState
(
action
.
id
);
if
(
download
State
==
null
)
{
download
State
=
new
DownloadState
(
action
);
Download
download
=
loadDownload
(
action
.
id
);
if
(
download
==
null
)
{
download
=
new
Download
(
action
);
logd
(
"Download state is created for "
+
action
.
id
);
}
else
{
downloadState
=
downloadState
.
copyWithMergedAction
(
action
,
/* canStart= */
notMetRequirements
==
0
);
download
=
download
.
copyWithMergedAction
(
action
,
/* canStart= */
notMetRequirements
==
0
);
logd
(
"Download state is loaded for "
+
action
.
id
);
}
addDownloadForState
(
download
State
);
addDownloadForState
(
download
);
}
}
private
void
removeDownloadInternal
(
String
id
)
{
Download
download
=
getDownload
(
id
);
if
(
download
!=
null
)
{
download
.
remove
();
Download
Internal
downloadInternal
=
getDownload
(
id
);
if
(
download
Internal
!=
null
)
{
download
Internal
.
remove
();
}
else
{
Download
State
downloadState
=
loadDownloadState
(
id
);
if
(
download
State
!=
null
)
{
addDownloadForState
(
download
State
.
copyWithState
(
STATE_REMOVING
));
Download
download
=
loadDownload
(
id
);
if
(
download
!=
null
)
{
addDownloadForState
(
download
.
copyWithState
(
STATE_REMOVING
));
}
else
{
logd
(
"Can't remove download. No download with id: "
+
id
);
}
}
}
private
void
onDownload
StateChangedInternal
(
Download
download
,
DownloadState
downloadState
)
{
logd
(
"Download state is changed"
,
download
);
private
void
onDownload
ChangedInternal
(
DownloadInternal
downloadInternal
,
Download
download
)
{
logd
(
"Download state is changed"
,
download
Internal
);
try
{
downloadIndex
.
putDownload
State
(
downloadState
);
downloadIndex
.
putDownload
(
download
);
}
catch
(
DatabaseIOException
e
)
{
Log
.
e
(
TAG
,
"Failed to update index"
,
e
);
}
if
(
download
.
state
==
STATE_COMPLETED
||
download
.
state
==
STATE_FAILED
)
{
download
s
.
remove
(
download
);
if
(
download
Internal
.
state
==
STATE_COMPLETED
||
downloadInternal
.
state
==
STATE_FAILED
)
{
download
Internals
.
remove
(
downloadInternal
);
}
mainHandler
.
obtainMessage
(
MSG_DOWNLOAD_STATE_CHANGED
,
download
State
).
sendToTarget
();
mainHandler
.
obtainMessage
(
MSG_DOWNLOAD_STATE_CHANGED
,
download
).
sendToTarget
();
}
private
void
onDownloadRemovedInternal
(
Download
download
,
DownloadState
downloadState
)
{
logd
(
"Download is removed"
,
download
);
private
void
onDownloadRemovedInternal
(
Download
Internal
downloadInternal
,
Download
download
)
{
logd
(
"Download is removed"
,
download
Internal
);
try
{
downloadIndex
.
removeDownload
State
(
downloadState
.
action
.
id
);
downloadIndex
.
removeDownload
(
download
.
action
.
id
);
}
catch
(
DatabaseIOException
e
)
{
Log
.
e
(
TAG
,
"Failed to remove from index"
,
e
);
}
download
s
.
remove
(
download
);
mainHandler
.
obtainMessage
(
MSG_DOWNLOAD_REMOVED
,
download
State
).
sendToTarget
();
download
Internals
.
remove
(
downloadInternal
);
mainHandler
.
obtainMessage
(
MSG_DOWNLOAD_REMOVED
,
download
).
sendToTarget
();
}
private
void
setNotMetRequirementsInternal
(
...
...
@@ -675,25 +673,25 @@ public final class DownloadManager {
}
this
.
notMetRequirements
=
notMetRequirements
;
logdFlags
(
"Not met requirements are changed"
,
notMetRequirements
);
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
downloads
.
get
(
i
).
setNotMetRequirements
(
notMetRequirements
);
for
(
int
i
=
0
;
i
<
download
Internal
s
.
size
();
i
++)
{
download
Internal
s
.
get
(
i
).
setNotMetRequirements
(
notMetRequirements
);
}
}
@Nullable
private
Download
getDownload
(
String
id
)
{
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
Download
download
=
download
s
.
get
(
i
);
if
(
download
.
getId
().
equals
(
id
))
{
return
download
;
private
Download
Internal
getDownload
(
String
id
)
{
for
(
int
i
=
0
;
i
<
download
Internal
s
.
size
();
i
++)
{
Download
Internal
downloadInternal
=
downloadInternal
s
.
get
(
i
);
if
(
download
Internal
.
getId
().
equals
(
id
))
{
return
download
Internal
;
}
}
return
null
;
}
private
Download
State
loadDownloadState
(
String
id
)
{
private
Download
loadDownload
(
String
id
)
{
try
{
return
downloadIndex
.
getDownload
State
(
id
);
return
downloadIndex
.
getDownload
(
id
);
}
catch
(
DatabaseIOException
e
)
{
Log
.
e
(
TAG
,
"loadDownload failed"
,
e
);
}
...
...
@@ -702,33 +700,34 @@ public final class DownloadManager {
private
void
initializeInternal
(
int
notMetRequirements
)
{
this
.
notMetRequirements
=
notMetRequirements
;
ArrayList
<
Download
State
>
loadedStates
=
new
ArrayList
<>();
try
(
Download
State
Cursor
cursor
=
downloadIndex
.
getDownload
State
s
(
ArrayList
<
Download
>
loadedStates
=
new
ArrayList
<>();
try
(
DownloadCursor
cursor
=
downloadIndex
.
getDownloads
(
STATE_QUEUED
,
STATE_STOPPED
,
STATE_DOWNLOADING
,
STATE_REMOVING
,
STATE_RESTARTING
))
{
while
(
cursor
.
moveToNext
())
{
loadedStates
.
add
(
cursor
.
getDownload
State
());
loadedStates
.
add
(
cursor
.
getDownload
());
}
logd
(
"Download states are loaded."
);
}
catch
(
Throwable
e
)
{
Log
.
e
(
TAG
,
"Download state loading failed."
,
e
);
loadedStates
.
clear
();
}
for
(
Download
State
downloadState
:
loadedStates
)
{
addDownloadForState
(
download
State
);
for
(
Download
download
:
loadedStates
)
{
addDownloadForState
(
download
);
}
logd
(
"Downloads are created."
);
mainHandler
.
obtainMessage
(
MSG_INITIALIZED
,
loadedStates
).
sendToTarget
();
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
downloads
.
get
(
i
).
start
();
for
(
int
i
=
0
;
i
<
download
Internal
s
.
size
();
i
++)
{
download
Internal
s
.
get
(
i
).
start
();
}
}
private
void
addDownloadForState
(
DownloadState
downloadState
)
{
Download
download
=
new
Download
(
this
,
downloadState
,
notMetRequirements
,
manualStopReason
);
downloads
.
add
(
download
);
logd
(
"Download is added"
,
download
);
download
.
initialize
();
private
void
addDownloadForState
(
Download
download
)
{
DownloadInternal
downloadInternal
=
new
DownloadInternal
(
this
,
download
,
notMetRequirements
,
manualStopReason
);
downloadInternals
.
add
(
downloadInternal
);
logd
(
"Download is added"
,
downloadInternal
);
downloadInternal
.
initialize
();
}
private
static
void
logd
(
String
message
)
{
...
...
@@ -737,9 +736,9 @@ public final class DownloadManager {
}
}
private
static
void
logd
(
String
message
,
Download
download
)
{
private
static
void
logd
(
String
message
,
Download
Internal
downloadInternal
)
{
if
(
DEBUG
)
{
logd
(
message
+
": "
+
download
);
logd
(
message
+
": "
+
download
Internal
);
}
}
...
...
@@ -750,39 +749,39 @@ public final class DownloadManager {
}
@StartThreadResults
private
int
startDownloadThread
(
Download
download
)
{
if
(
activeDownloads
.
containsKey
(
download
))
{
if
(
stopDownloadThread
(
download
))
{
private
int
startDownloadThread
(
Download
Internal
downloadInternal
)
{
if
(
activeDownloads
.
containsKey
(
download
Internal
))
{
if
(
stopDownloadThread
(
download
Internal
))
{
return
START_THREAD_WAIT_DOWNLOAD_CANCELLATION
;
}
return
START_THREAD_WAIT_REMOVAL_TO_FINISH
;
}
if
(!
download
.
isInRemoveState
())
{
if
(!
download
Internal
.
isInRemoveState
())
{
if
(
simultaneousDownloads
==
maxSimultaneousDownloads
)
{
return
START_THREAD_TOO_MANY_DOWNLOADS
;
}
simultaneousDownloads
++;
}
DownloadThread
downloadThread
=
new
DownloadThread
(
download
);
activeDownloads
.
put
(
download
,
downloadThread
);
download
.
setCounters
(
downloadThread
.
downloader
.
getCounters
());
logd
(
"Download is started"
,
download
);
DownloadThread
downloadThread
=
new
DownloadThread
(
download
Internal
);
activeDownloads
.
put
(
download
Internal
,
downloadThread
);
download
Internal
.
setCounters
(
downloadThread
.
downloader
.
getCounters
());
logd
(
"Download is started"
,
download
Internal
);
return
START_THREAD_SUCCEEDED
;
}
private
boolean
stopDownloadThread
(
Download
download
)
{
DownloadThread
downloadThread
=
activeDownloads
.
get
(
download
);
private
boolean
stopDownloadThread
(
Download
Internal
downloadInternal
)
{
DownloadThread
downloadThread
=
activeDownloads
.
get
(
download
Internal
);
if
(
downloadThread
!=
null
&&
!
downloadThread
.
isRemoveThread
)
{
downloadThread
.
cancel
();
logd
(
"Download is cancelled"
,
download
);
logd
(
"Download is cancelled"
,
download
Internal
);
return
true
;
}
return
false
;
}
private
void
releaseInternal
()
{
for
(
Download
download
:
activeDownloads
.
keySet
())
{
stopDownloadThread
(
download
);
for
(
Download
Internal
downloadInternal
:
activeDownloads
.
keySet
())
{
stopDownloadThread
(
download
Internal
);
}
internalThread
.
quit
();
synchronized
(
releaseLock
)
{
...
...
@@ -792,56 +791,55 @@ public final class DownloadManager {
}
private
void
onDownloadThreadStoppedInternal
(
DownloadThread
downloadThread
)
{
Download
download
=
downloadThread
.
download
;
logd
(
"Download is stopped"
,
download
);
activeDownloads
.
remove
(
download
);
Download
Internal
downloadInternal
=
downloadThread
.
downloadInternal
;
logd
(
"Download is stopped"
,
download
Internal
);
activeDownloads
.
remove
(
download
Internal
);
boolean
tryToStartDownloads
=
false
;
if
(!
downloadThread
.
isRemoveThread
)
{
// If maxSimultaneousDownloads was hit, there might be a download waiting for a slot.
tryToStartDownloads
=
simultaneousDownloads
==
maxSimultaneousDownloads
;
simultaneousDownloads
--;
}
download
.
onDownloadThreadStopped
(
downloadThread
.
isCanceled
,
downloadThread
.
finalError
);
download
Internal
.
onDownloadThreadStopped
(
downloadThread
.
isCanceled
,
downloadThread
.
finalError
);
if
(
tryToStartDownloads
)
{
for
(
int
i
=
0
;
simultaneousDownloads
<
maxSimultaneousDownloads
&&
i
<
downloads
.
size
();
simultaneousDownloads
<
maxSimultaneousDownloads
&&
i
<
download
Internal
s
.
size
();
i
++)
{
downloads
.
get
(
i
).
start
();
download
Internal
s
.
get
(
i
).
start
();
}
}
}
private
static
final
class
Download
{
private
static
final
class
Download
Internal
{
private
final
DownloadManager
downloadManager
;
private
Download
State
downloadState
;
@Download
State
.
State
private
int
state
;
@MonotonicNonNull
@Download
State
.
FailureReason
private
int
failureReason
;
private
Download
download
;
@Download
.
State
private
int
state
;
@MonotonicNonNull
@Download
.
FailureReason
private
int
failureReason
;
@Requirements
.
RequirementFlags
private
int
notMetRequirements
;
private
int
manualStopReason
;
private
Download
(
private
Download
Internal
(
DownloadManager
downloadManager
,
Download
State
downloadState
,
Download
download
,
@Requirements
.
RequirementFlags
int
notMetRequirements
,
int
manualStopReason
)
{
this
.
downloadManager
=
downloadManager
;
this
.
download
State
=
downloadState
;
this
.
download
=
download
;
this
.
notMetRequirements
=
notMetRequirements
;
this
.
manualStopReason
=
manualStopReason
;
}
private
void
initialize
()
{
initialize
(
download
State
.
state
);
initialize
(
download
.
state
);
}
public
String
getId
()
{
return
download
State
.
action
.
id
;
return
download
.
action
.
id
;
}
public
void
addAction
(
DownloadAction
newAction
)
{
downloadState
=
downloadState
.
copyWithMergedAction
(
newAction
,
/* canStart= */
notMetRequirements
==
0
);
download
=
download
.
copyWithMergedAction
(
newAction
,
/* canStart= */
notMetRequirements
==
0
);
initialize
();
}
...
...
@@ -849,17 +847,17 @@ public final class DownloadManager {
initialize
(
STATE_REMOVING
);
}
public
Download
State
getUpdatedDownloadState
()
{
download
State
=
new
Download
State
(
download
State
.
action
,
public
Download
getUpdatedDownload
()
{
download
=
new
Download
(
download
.
action
,
state
,
state
!=
STATE_FAILED
?
FAILURE_REASON_NONE
:
failureReason
,
manualStopReason
,
download
State
.
startTimeMs
,
download
.
startTimeMs
,
/* updateTimeMs= */
System
.
currentTimeMillis
(),
download
State
.
counters
);
return
download
State
;
download
.
counters
);
return
download
;
}
public
boolean
isIdle
()
{
...
...
@@ -868,7 +866,7 @@ public final class DownloadManager {
@Override
public
String
toString
()
{
return
getId
()
+
' '
+
Download
State
.
getStateString
(
state
);
return
getId
()
+
' '
+
Download
.
getStateString
(
state
);
}
public
void
start
()
{
...
...
@@ -894,11 +892,11 @@ public final class DownloadManager {
}
public
void
setCounters
(
CachingCounters
counters
)
{
download
State
.
setCounters
(
counters
);
download
.
setCounters
(
counters
);
}
private
void
updateStopState
()
{
Download
State
oldDownloadState
=
downloadState
;
Download
oldDownload
=
download
;
if
(
canStart
())
{
if
(
state
==
STATE_STOPPED
)
{
startOrQueue
();
...
...
@@ -909,8 +907,8 @@ public final class DownloadManager {
setState
(
STATE_STOPPED
);
}
}
if
(
oldDownload
State
==
downloadState
)
{
downloadManager
.
onDownload
StateChangedInternal
(
this
,
getUpdatedDownloadState
());
if
(
oldDownload
==
download
)
{
downloadManager
.
onDownload
ChangedInternal
(
this
,
getUpdatedDownload
());
}
}
...
...
@@ -926,7 +924,7 @@ public final class DownloadManager {
setState
(
STATE_STOPPED
);
}
if
(
state
==
initialState
)
{
downloadManager
.
onDownload
StateChangedInternal
(
this
,
getUpdatedDownloadState
());
downloadManager
.
onDownload
ChangedInternal
(
this
,
getUpdatedDownload
());
}
}
...
...
@@ -945,10 +943,10 @@ public final class DownloadManager {
}
}
private
void
setState
(
@Download
State
.
State
int
newState
)
{
private
void
setState
(
@Download
.
State
int
newState
)
{
if
(
state
!=
newState
)
{
state
=
newState
;
downloadManager
.
onDownload
StateChangedInternal
(
this
,
getUpdatedDownloadState
());
downloadManager
.
onDownload
ChangedInternal
(
this
,
getUpdatedDownload
());
}
}
...
...
@@ -959,12 +957,12 @@ public final class DownloadManager {
if
(
isCanceled
)
{
downloadManager
.
startDownloadThread
(
this
);
}
else
if
(
state
==
STATE_REMOVING
)
{
downloadManager
.
onDownloadRemovedInternal
(
this
,
getUpdatedDownload
State
());
downloadManager
.
onDownloadRemovedInternal
(
this
,
getUpdatedDownload
());
}
else
if
(
state
==
STATE_RESTARTING
)
{
initialize
(
STATE_QUEUED
);
}
else
{
// STATE_DOWNLOADING
if
(
error
!=
null
)
{
Log
.
e
(
TAG
,
"Download failed: "
+
download
State
.
action
.
id
,
error
);
Log
.
e
(
TAG
,
"Download failed: "
+
download
.
action
.
id
,
error
);
failureReason
=
FAILURE_REASON_UNKNOWN
;
setState
(
STATE_FAILED
);
}
else
{
...
...
@@ -976,17 +974,17 @@ public final class DownloadManager {
private
class
DownloadThread
extends
Thread
{
private
final
Download
download
;
private
final
Download
Internal
downloadInternal
;
private
final
Downloader
downloader
;
private
final
boolean
isRemoveThread
;
private
volatile
boolean
isCanceled
;
private
Throwable
finalError
;
private
DownloadThread
(
Download
download
)
{
this
.
download
=
download
;
this
.
downloader
=
downloaderFactory
.
createDownloader
(
download
.
downloadState
.
action
);
this
.
isRemoveThread
=
download
.
isInRemoveState
();
private
DownloadThread
(
Download
Internal
downloadInternal
)
{
this
.
download
Internal
=
downloadInternal
;
this
.
downloader
=
downloaderFactory
.
createDownloader
(
download
Internal
.
download
.
action
);
this
.
isRemoveThread
=
download
Internal
.
isInRemoveState
();
start
();
}
...
...
@@ -1000,7 +998,7 @@ public final class DownloadManager {
@Override
public
void
run
()
{
logd
(
"Download started"
,
download
);
logd
(
"Download started"
,
download
Internal
);
try
{
if
(
isRemoveThread
)
{
downloader
.
remove
();
...
...
@@ -1015,14 +1013,14 @@ public final class DownloadManager {
if
(!
isCanceled
)
{
long
downloadedBytes
=
downloader
.
getDownloadedBytes
();
if
(
downloadedBytes
!=
errorPosition
)
{
logd
(
"Reset error count. downloadedBytes = "
+
downloadedBytes
,
download
);
logd
(
"Reset error count. downloadedBytes = "
+
downloadedBytes
,
download
Internal
);
errorPosition
=
downloadedBytes
;
errorCount
=
0
;
}
if
(++
errorCount
>
minRetryCount
)
{
throw
e
;
}
logd
(
"Download error. Retry "
+
errorCount
,
download
);
logd
(
"Download error. Retry "
+
errorCount
,
download
Internal
);
Thread
.
sleep
(
getRetryDelayMillis
(
errorCount
));
}
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java
View file @
8688bd2d
...
...
@@ -79,8 +79,8 @@ public abstract class DownloadService extends Service {
* <li>{@link #KEY_CONTENT_ID} - The content id of a single download to stop. If omitted, all of
* the current downloads will be stopped.
* <li>{@link #KEY_STOP_REASON} - An application provided reason for stopping the download or
* downloads. Must not be {@link Download
State#MANUAL_STOP_REASON_NONE}. If omitted, the
*
stop reason will be {@link DownloadState
#MANUAL_STOP_REASON_UNDEFINED}.
* downloads. Must not be {@link Download
#MANUAL_STOP_REASON_NONE}. If omitted, the stop
*
reason will be {@link Download
#MANUAL_STOP_REASON_UNDEFINED}.
* <li>{@link #KEY_FOREGROUND} - See {@link #KEY_FOREGROUND}.
* </ul>
*/
...
...
@@ -405,8 +405,7 @@ public abstract class DownloadService extends Service {
break
;
case
ACTION_STOP:
contentId
=
intent
.
getStringExtra
(
KEY_CONTENT_ID
);
int
stopReason
=
intent
.
getIntExtra
(
KEY_STOP_REASON
,
DownloadState
.
MANUAL_STOP_REASON_UNDEFINED
);
int
stopReason
=
intent
.
getIntExtra
(
KEY_STOP_REASON
,
Download
.
MANUAL_STOP_REASON_UNDEFINED
);
if
(
contentId
==
null
)
{
downloadManager
.
stopDownloads
(
stopReason
);
}
else
{
...
...
@@ -477,7 +476,7 @@ public abstract class DownloadService extends Service {
* downloads. The periodic update interval can be set using {@link #DownloadService(int, long)}.
*
* <p>On API level 26 and above, this method may also be called just before the service stops,
* with an empty {@code download
State
s} array. The returned notification is used to satisfy system
* with an empty {@code downloads} array. The returned notification is used to satisfy system
* requirements for foreground services.
*
* <p>Download services that do not wish to run in the foreground should be created by setting the
...
...
@@ -485,35 +484,35 @@ public abstract class DownloadService extends Service {
* #FOREGROUND_NOTIFICATION_ID_NONE}. This method will not be called in this case, meaning it can
* be implemented to throw {@link UnsupportedOperationException}.
*
* @param download
State
s The states of all current downloads.
* @param downloads The states of all current downloads.
* @return The foreground notification to display.
*/
protected
abstract
Notification
getForegroundNotification
(
Download
State
[]
downloadState
s
);
protected
abstract
Notification
getForegroundNotification
(
Download
[]
download
s
);
/**
* Called when the state of a download changes. The default implementation is a no-op.
*
* @param download
State
The new state of the download.
* @param download The new state of the download.
*/
protected
void
onDownload
StateChanged
(
DownloadState
downloadState
)
{
protected
void
onDownload
Changed
(
Download
download
)
{
// Do nothing.
}
/**
* Called when a download is removed. The default implementation is a no-op.
*
* @param download
State
The last state of the download before it was removed.
* @param download The last state of the download before it was removed.
*/
protected
void
onDownloadRemoved
(
Download
State
downloadState
)
{
protected
void
onDownloadRemoved
(
Download
download
)
{
// Do nothing.
}
private
void
notifyDownload
StateChange
(
DownloadState
downloadState
)
{
onDownload
StateChanged
(
downloadState
);
private
void
notifyDownload
Change
(
Download
download
)
{
onDownload
Changed
(
download
);
if
(
foregroundNotificationUpdater
!=
null
)
{
if
(
download
State
.
state
==
DownloadState
.
STATE_DOWNLOADING
||
download
State
.
state
==
DownloadState
.
STATE_REMOVING
||
download
State
.
state
==
DownloadState
.
STATE_RESTARTING
)
{
if
(
download
.
state
==
Download
.
STATE_DOWNLOADING
||
download
.
state
==
Download
.
STATE_REMOVING
||
download
.
state
==
Download
.
STATE_RESTARTING
)
{
foregroundNotificationUpdater
.
startPeriodicUpdates
();
}
else
{
foregroundNotificationUpdater
.
update
();
...
...
@@ -521,8 +520,8 @@ public abstract class DownloadService extends Service {
}
}
private
void
notifyDownloadRemoved
(
Download
State
downloadState
)
{
onDownloadRemoved
(
download
State
);
private
void
notifyDownloadRemoved
(
Download
download
)
{
onDownloadRemoved
(
download
);
if
(
foregroundNotificationUpdater
!=
null
)
{
foregroundNotificationUpdater
.
update
();
}
...
...
@@ -582,8 +581,8 @@ public abstract class DownloadService extends Service {
}
public
void
update
()
{
Download
State
[]
downloadStates
=
downloadManager
.
getAllDownloadState
s
();
startForeground
(
notificationId
,
getForegroundNotification
(
download
State
s
));
Download
[]
downloads
=
downloadManager
.
getAllDownload
s
();
startForeground
(
notificationId
,
getForegroundNotification
(
downloads
));
notificationDisplayed
=
true
;
if
(
periodicUpdatesStarted
)
{
handler
.
removeCallbacks
(
this
);
...
...
@@ -641,17 +640,16 @@ public abstract class DownloadService extends Service {
}
@Override
public
void
onDownloadStateChanged
(
DownloadManager
downloadManager
,
DownloadState
downloadState
)
{
public
void
onDownloadChanged
(
DownloadManager
downloadManager
,
Download
download
)
{
if
(
downloadService
!=
null
)
{
downloadService
.
notifyDownload
StateChange
(
downloadState
);
downloadService
.
notifyDownload
Change
(
download
);
}
}
@Override
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
State
downloadState
)
{
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
download
)
{
if
(
downloadService
!=
null
)
{
downloadService
.
notifyDownloadRemoved
(
download
State
);
downloadService
.
notifyDownloadRemoved
(
download
);
}
}
...
...
library/core/src/test/java/com/google/android/exoplayer2/offline/DefaultDownloadIndexTest.java
View file @
8688bd2d
...
...
@@ -48,39 +48,37 @@ public class DefaultDownloadIndexTest {
}
@Test
public
void
getDownload
State
_nonExistingId_returnsNull
()
throws
DatabaseIOException
{
assertThat
(
downloadIndex
.
getDownload
State
(
"non existing id"
)).
isNull
();
public
void
getDownload_nonExistingId_returnsNull
()
throws
DatabaseIOException
{
assertThat
(
downloadIndex
.
getDownload
(
"non existing id"
)).
isNull
();
}
@Test
public
void
addAndGetDownloadState_nonExistingId_returnsTheSameDownloadState
()
throws
DatabaseIOException
{
public
void
addAndGetDownload_nonExistingId_returnsTheSameDownload
()
throws
DatabaseIOException
{
String
id
=
"id"
;
Download
State
downloadState
=
new
DownloadState
Builder
(
id
).
build
();
Download
download
=
new
Download
Builder
(
id
).
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
downloadIndex
.
putDownload
(
download
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
StateTest
.
assertEqual
(
readDownloadState
,
downloadState
);
Download
Test
.
assertEqual
(
readDownload
,
download
);
}
@Test
public
void
addAndGetDownloadState_existingId_returnsUpdatedDownloadState
()
throws
DatabaseIOException
{
public
void
addAndGetDownload_existingId_returnsUpdatedDownload
()
throws
DatabaseIOException
{
String
id
=
"id"
;
Download
StateBuilder
downloadStateBuilder
=
new
DownloadState
Builder
(
id
);
downloadIndex
.
putDownload
State
(
downloadState
Builder
.
build
());
Download
Builder
downloadBuilder
=
new
Download
Builder
(
id
);
downloadIndex
.
putDownload
(
download
Builder
.
build
());
Download
State
downloadState
=
download
State
Builder
Download
download
=
downloadBuilder
.
setType
(
"different type"
)
.
setUri
(
"different uri"
)
.
setCacheKey
(
"different cacheKey"
)
.
setState
(
Download
State
.
STATE_FAILED
)
.
setState
(
Download
.
STATE_FAILED
)
.
setDownloadPercentage
(
50
)
.
setDownloadedBytes
(
200
)
.
setTotalBytes
(
400
)
.
setFailureReason
(
Download
State
.
FAILURE_REASON_UNKNOWN
)
.
setFailureReason
(
Download
.
FAILURE_REASON_UNKNOWN
)
.
setManualStopReason
(
0x12345678
)
.
setStartTimeMs
(
10
)
.
setUpdateTimeMs
(
20
)
...
...
@@ -89,108 +87,94 @@ public class DefaultDownloadIndexTest {
new
StreamKey
(
/* periodIndex= */
3
,
/* groupIndex= */
4
,
/* trackIndex= */
5
))
.
setCustomMetadata
(
new
byte
[]
{
0
,
1
,
2
,
3
,
7
,
8
,
9
,
10
})
.
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
downloadIndex
.
putDownload
(
download
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
assertThat
(
readDownload
State
).
isNotNull
();
Download
StateTest
.
assertEqual
(
readDownloadState
,
downloadState
);
assertThat
(
readDownload
).
isNotNull
();
Download
Test
.
assertEqual
(
readDownload
,
download
);
}
@Test
public
void
releaseAndRecreateDownloadIndex_returnsTheSameDownloadState
()
throws
DatabaseIOException
{
public
void
releaseAndRecreateDownloadIndex_returnsTheSameDownload
()
throws
DatabaseIOException
{
String
id
=
"id"
;
Download
State
downloadState
=
new
DownloadState
Builder
(
id
).
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
Download
download
=
new
Download
Builder
(
id
).
build
();
downloadIndex
.
putDownload
(
download
);
downloadIndex
=
new
DefaultDownloadIndex
(
databaseProvider
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
assertThat
(
readDownload
State
).
isNotNull
();
Download
StateTest
.
assertEqual
(
readDownloadState
,
downloadState
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
assertThat
(
readDownload
).
isNotNull
();
Download
Test
.
assertEqual
(
readDownload
,
download
);
}
@Test
public
void
removeDownload
State
_nonExistingId_doesNotFail
()
throws
DatabaseIOException
{
downloadIndex
.
removeDownload
State
(
"non existing id"
);
public
void
removeDownload_nonExistingId_doesNotFail
()
throws
DatabaseIOException
{
downloadIndex
.
removeDownload
(
"non existing id"
);
}
@Test
public
void
removeDownloadState_existingId_getDownloadStateReturnsNull
()
throws
DatabaseIOException
{
public
void
removeDownload_existingId_getDownloadReturnsNull
()
throws
DatabaseIOException
{
String
id
=
"id"
;
Download
State
downloadState
=
new
DownloadState
Builder
(
id
).
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
downloadIndex
.
removeDownload
State
(
id
);
Download
download
=
new
Download
Builder
(
id
).
build
();
downloadIndex
.
putDownload
(
download
);
downloadIndex
.
removeDownload
(
id
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
assertThat
(
readDownload
State
).
isNull
();
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
assertThat
(
readDownload
).
isNull
();
}
@Test
public
void
getDownload
State
s_emptyDownloadIndex_returnsEmptyArray
()
throws
DatabaseIOException
{
assertThat
(
downloadIndex
.
getDownload
State
s
().
getCount
()).
isEqualTo
(
0
);
public
void
getDownloads_emptyDownloadIndex_returnsEmptyArray
()
throws
DatabaseIOException
{
assertThat
(
downloadIndex
.
getDownloads
().
getCount
()).
isEqualTo
(
0
);
}
@Test
public
void
getDownload
State
s_noState_returnsAllDownloadStatusSortedByStartTime
()
public
void
getDownloads_noState_returnsAllDownloadStatusSortedByStartTime
()
throws
DatabaseIOException
{
DownloadState
downloadState1
=
new
DownloadStateBuilder
(
"id1"
).
setStartTimeMs
(
1
).
build
();
downloadIndex
.
putDownloadState
(
downloadState1
);
DownloadState
downloadState2
=
new
DownloadStateBuilder
(
"id2"
).
setStartTimeMs
(
0
).
build
();
downloadIndex
.
putDownloadState
(
downloadState2
);
DownloadStateCursor
cursor
=
downloadIndex
.
getDownloadStates
();
Download
download1
=
new
DownloadBuilder
(
"id1"
).
setStartTimeMs
(
1
).
build
();
downloadIndex
.
putDownload
(
download1
);
Download
download2
=
new
DownloadBuilder
(
"id2"
).
setStartTimeMs
(
0
).
build
();
downloadIndex
.
putDownload
(
download2
);
try
(
DownloadCursor
cursor
=
downloadIndex
.
getDownloads
())
{
assertThat
(
cursor
.
getCount
()).
isEqualTo
(
2
);
cursor
.
moveToNext
();
DownloadStateTest
.
assertEqual
(
cursor
.
getDownloadState
(),
downloadState
2
);
DownloadTest
.
assertEqual
(
cursor
.
getDownload
(),
download
2
);
cursor
.
moveToNext
();
DownloadStateTest
.
assertEqual
(
cursor
.
getDownloadState
(),
downloadState
1
);
cursor
.
close
();
DownloadTest
.
assertEqual
(
cursor
.
getDownload
(),
download
1
);
}
}
@Test
public
void
getDownload
State
s_withStates_returnsAllDownloadStatusWithTheSameStates
()
public
void
getDownloads_withStates_returnsAllDownloadStatusWithTheSameStates
()
throws
DatabaseIOException
{
DownloadState
downloadState1
=
new
DownloadStateBuilder
(
"id1"
)
.
setStartTimeMs
(
0
)
.
setState
(
DownloadState
.
STATE_REMOVING
)
.
build
();
downloadIndex
.
putDownloadState
(
downloadState1
);
DownloadState
downloadState2
=
new
DownloadStateBuilder
(
"id2"
)
.
setStartTimeMs
(
1
)
.
setState
(
DownloadState
.
STATE_STOPPED
)
.
build
();
downloadIndex
.
putDownloadState
(
downloadState2
);
DownloadState
downloadState3
=
new
DownloadStateBuilder
(
"id3"
)
.
setStartTimeMs
(
2
)
.
setState
(
DownloadState
.
STATE_COMPLETED
)
.
build
();
downloadIndex
.
putDownloadState
(
downloadState3
);
DownloadStateCursor
cursor
=
downloadIndex
.
getDownloadStates
(
DownloadState
.
STATE_REMOVING
,
DownloadState
.
STATE_COMPLETED
);
Download
download1
=
new
DownloadBuilder
(
"id1"
).
setStartTimeMs
(
0
).
setState
(
Download
.
STATE_REMOVING
).
build
();
downloadIndex
.
putDownload
(
download1
);
Download
download2
=
new
DownloadBuilder
(
"id2"
).
setStartTimeMs
(
1
).
setState
(
Download
.
STATE_STOPPED
).
build
();
downloadIndex
.
putDownload
(
download2
);
Download
download3
=
new
DownloadBuilder
(
"id3"
).
setStartTimeMs
(
2
).
setState
(
Download
.
STATE_COMPLETED
).
build
();
downloadIndex
.
putDownload
(
download3
);
try
(
DownloadCursor
cursor
=
downloadIndex
.
getDownloads
(
Download
.
STATE_REMOVING
,
Download
.
STATE_COMPLETED
))
{
assertThat
(
cursor
.
getCount
()).
isEqualTo
(
2
);
cursor
.
moveToNext
();
DownloadStateTest
.
assertEqual
(
cursor
.
getDownloadState
(),
downloadState
1
);
DownloadTest
.
assertEqual
(
cursor
.
getDownload
(),
download
1
);
cursor
.
moveToNext
();
DownloadStateTest
.
assertEqual
(
cursor
.
getDownloadState
(),
downloadState
3
);
cursor
.
close
();
DownloadTest
.
assertEqual
(
cursor
.
getDownload
(),
download
3
);
}
}
@Test
public
void
putDownload
State
_setsVersion
()
throws
DatabaseIOException
{
public
void
putDownload_setsVersion
()
throws
DatabaseIOException
{
SQLiteDatabase
readableDatabase
=
databaseProvider
.
getReadableDatabase
();
assertThat
(
VersionTable
.
getVersion
(
readableDatabase
,
VersionTable
.
FEATURE_OFFLINE
,
INSTANCE_UID
))
.
isEqualTo
(
VersionTable
.
VERSION_UNSET
);
downloadIndex
.
putDownload
State
(
new
DownloadState
Builder
(
"id1"
).
build
());
downloadIndex
.
putDownload
(
new
Download
Builder
(
"id1"
).
build
());
assertThat
(
VersionTable
.
getVersion
(
readableDatabase
,
VersionTable
.
FEATURE_OFFLINE
,
INSTANCE_UID
))
...
...
@@ -199,9 +183,9 @@ public class DefaultDownloadIndexTest {
@Test
public
void
downloadIndex_versionDowngradeWipesData
()
throws
DatabaseIOException
{
Download
State
downloadState1
=
new
DownloadState
Builder
(
"id1"
).
build
();
downloadIndex
.
putDownload
State
(
downloadState
1
);
Download
StateCursor
cursor
=
downloadIndex
.
getDownloadState
s
();
Download
download1
=
new
Download
Builder
(
"id1"
).
build
();
downloadIndex
.
putDownload
(
download
1
);
Download
Cursor
cursor
=
downloadIndex
.
getDownload
s
();
assertThat
(
cursor
.
getCount
()).
isEqualTo
(
1
);
cursor
.
close
();
...
...
@@ -211,7 +195,7 @@ public class DefaultDownloadIndexTest {
downloadIndex
=
new
DefaultDownloadIndex
(
databaseProvider
);
cursor
=
downloadIndex
.
getDownload
State
s
();
cursor
=
downloadIndex
.
getDownloads
();
assertThat
(
cursor
.
getCount
()).
isEqualTo
(
0
);
cursor
.
close
();
assertThat
(
...
...
@@ -222,105 +206,97 @@ public class DefaultDownloadIndexTest {
@Test
public
void
setManualStopReason_setReasonToNone
()
throws
Exception
{
String
id
=
"id"
;
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
id
)
.
setState
(
DownloadState
.
STATE_COMPLETED
)
.
setManualStopReason
(
0x12345678
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
downloadIndex
.
putDownloadState
(
downloadState
);
downloadIndex
.
setManualStopReason
(
DownloadState
.
MANUAL_STOP_REASON_NONE
);
DownloadState
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setManualStopReason
(
DownloadState
.
MANUAL_STOP_REASON_NONE
).
build
();
DownloadStateTest
.
assertEqual
(
readDownloadState
,
expectedDownloadState
);
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
id
).
setState
(
Download
.
STATE_COMPLETED
).
setManualStopReason
(
0x12345678
);
Download
download
=
downloadBuilder
.
build
();
downloadIndex
.
putDownload
(
download
);
downloadIndex
.
setManualStopReason
(
Download
.
MANUAL_STOP_REASON_NONE
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
expectedDownload
=
downloadBuilder
.
setManualStopReason
(
Download
.
MANUAL_STOP_REASON_NONE
).
build
();
DownloadTest
.
assertEqual
(
readDownload
,
expectedDownload
);
}
@Test
public
void
setManualStopReason_setReason
()
throws
Exception
{
String
id
=
"id"
;
Download
StateBuilder
downloadState
Builder
=
new
Download
State
Builder
(
id
)
.
setState
(
Download
State
.
STATE_FAILED
)
.
setFailureReason
(
Download
State
.
FAILURE_REASON_UNKNOWN
);
Download
State
downloadState
=
downloadState
Builder
.
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
Download
Builder
download
Builder
=
new
DownloadBuilder
(
id
)
.
setState
(
Download
.
STATE_FAILED
)
.
setFailureReason
(
Download
.
FAILURE_REASON_UNKNOWN
);
Download
download
=
download
Builder
.
build
();
downloadIndex
.
putDownload
(
download
);
int
manualStopReason
=
0x12345678
;
downloadIndex
.
setManualStopReason
(
manualStopReason
);
DownloadState
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setManualStopReason
(
manualStopReason
).
build
();
DownloadStateTest
.
assertEqual
(
readDownloadState
,
expectedDownloadState
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
expectedDownload
=
downloadBuilder
.
setManualStopReason
(
manualStopReason
).
build
();
DownloadTest
.
assertEqual
(
readDownload
,
expectedDownload
);
}
@Test
public
void
setManualStopReason_notTerminalState_doesNotSetManualStopReason
()
throws
Exception
{
String
id
=
"id"
;
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
id
).
setState
(
DownloadState
.
STATE_DOWNLOADING
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
downloadIndex
.
putDownloadState
(
downloadState
);
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
id
).
setState
(
Download
.
STATE_DOWNLOADING
);
Download
download
=
downloadBuilder
.
build
();
downloadIndex
.
putDownload
(
download
);
int
notMetRequirements
=
0x12345678
;
downloadIndex
.
setManualStopReason
(
notMetRequirements
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
Download
StateTest
.
assertEqual
(
readDownloadState
,
downloadState
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
Test
.
assertEqual
(
readDownload
,
download
);
}
@Test
public
void
setSingleDownloadManualStopReason_setReasonToNone
()
throws
Exception
{
String
id
=
"id"
;
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
id
)
.
setState
(
DownloadState
.
STATE_COMPLETED
)
.
setManualStopReason
(
0x12345678
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
downloadIndex
.
putDownloadState
(
downloadState
);
downloadIndex
.
setManualStopReason
(
id
,
DownloadState
.
MANUAL_STOP_REASON_NONE
);
DownloadState
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setManualStopReason
(
DownloadState
.
MANUAL_STOP_REASON_NONE
).
build
();
DownloadStateTest
.
assertEqual
(
readDownloadState
,
expectedDownloadState
);
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
id
).
setState
(
Download
.
STATE_COMPLETED
).
setManualStopReason
(
0x12345678
);
Download
download
=
downloadBuilder
.
build
();
downloadIndex
.
putDownload
(
download
);
downloadIndex
.
setManualStopReason
(
id
,
Download
.
MANUAL_STOP_REASON_NONE
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
expectedDownload
=
downloadBuilder
.
setManualStopReason
(
Download
.
MANUAL_STOP_REASON_NONE
).
build
();
DownloadTest
.
assertEqual
(
readDownload
,
expectedDownload
);
}
@Test
public
void
setSingleDownloadManualStopReason_setReason
()
throws
Exception
{
String
id
=
"id"
;
Download
StateBuilder
downloadState
Builder
=
new
Download
State
Builder
(
id
)
.
setState
(
Download
State
.
STATE_FAILED
)
.
setFailureReason
(
Download
State
.
FAILURE_REASON_UNKNOWN
);
Download
State
downloadState
=
downloadState
Builder
.
build
();
downloadIndex
.
putDownload
State
(
downloadState
);
Download
Builder
download
Builder
=
new
DownloadBuilder
(
id
)
.
setState
(
Download
.
STATE_FAILED
)
.
setFailureReason
(
Download
.
FAILURE_REASON_UNKNOWN
);
Download
download
=
download
Builder
.
build
();
downloadIndex
.
putDownload
(
download
);
int
manualStopReason
=
0x12345678
;
downloadIndex
.
setManualStopReason
(
id
,
manualStopReason
);
DownloadState
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setManualStopReason
(
manualStopReason
).
build
();
DownloadStateTest
.
assertEqual
(
readDownloadState
,
expectedDownloadState
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
expectedDownload
=
downloadBuilder
.
setManualStopReason
(
manualStopReason
).
build
();
DownloadTest
.
assertEqual
(
readDownload
,
expectedDownload
);
}
@Test
public
void
setSingleDownloadManualStopReason_notTerminalState_doesNotSetManualStopReason
()
throws
Exception
{
String
id
=
"id"
;
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
id
).
setState
(
DownloadState
.
STATE_DOWNLOADING
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
downloadIndex
.
putDownloadState
(
downloadState
);
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
id
).
setState
(
Download
.
STATE_DOWNLOADING
);
Download
download
=
downloadBuilder
.
build
();
downloadIndex
.
putDownload
(
download
);
int
notMetRequirements
=
0x12345678
;
downloadIndex
.
setManualStopReason
(
id
,
notMetRequirements
);
Download
State
readDownloadState
=
downloadIndex
.
getDownloadState
(
id
);
Download
StateTest
.
assertEqual
(
readDownloadState
,
downloadState
);
Download
readDownload
=
downloadIndex
.
getDownload
(
id
);
Download
Test
.
assertEqual
(
readDownload
,
download
);
}
}
library/core/src/test/java/com/google/android/exoplayer2/offline/Download
State
Builder.java
→
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadBuilder.java
View file @
8688bd2d
...
...
@@ -23,13 +23,13 @@ import java.util.Collections;
import
java.util.List
;
/**
* Builder for
DownloadState
.
* Builder for
{@link Download}
.
*
* <p>Defines default values for each field (except {@code id}) to facilitate
DownloadState creation
*
for tests. Tests must avoid depending on the default values but explicitly set tested parameters
* during test initialization.
* <p>Defines default values for each field (except {@code id}) to facilitate
{@link Download}
*
creation for tests. Tests must avoid depending on the default values but explicitly set tested
*
parameters
during test initialization.
*/
class
Download
State
Builder
{
class
DownloadBuilder
{
private
final
CachingCounters
counters
;
private
String
id
;
private
String
type
;
...
...
@@ -43,15 +43,15 @@ class DownloadStateBuilder {
private
List
<
StreamKey
>
streamKeys
;
private
byte
[]
customMetadata
;
Download
State
Builder
(
String
id
)
{
DownloadBuilder
(
String
id
)
{
this
(
id
,
"type"
,
Uri
.
parse
(
"uri"
),
/* cacheKey= */
null
,
new
byte
[
0
],
Collections
.
emptyList
());
}
Download
State
Builder
(
DownloadAction
action
)
{
DownloadBuilder
(
DownloadAction
action
)
{
this
(
action
.
id
,
action
.
type
,
action
.
uri
,
action
.
customCacheKey
,
action
.
data
,
action
.
streamKeys
);
}
Download
State
Builder
(
DownloadBuilder
(
String
id
,
String
type
,
Uri
uri
,
...
...
@@ -62,8 +62,8 @@ class DownloadStateBuilder {
this
.
type
=
type
;
this
.
uri
=
uri
;
this
.
cacheKey
=
cacheKey
;
this
.
state
=
Download
State
.
STATE_QUEUED
;
this
.
failureReason
=
Download
State
.
FAILURE_REASON_NONE
;
this
.
state
=
Download
.
STATE_QUEUED
;
this
.
failureReason
=
Download
.
FAILURE_REASON_NONE
;
this
.
startTimeMs
=
(
long
)
0
;
this
.
updateTimeMs
=
(
long
)
0
;
this
.
streamKeys
=
streamKeys
;
...
...
@@ -71,90 +71,84 @@ class DownloadStateBuilder {
this
.
counters
=
new
CachingCounters
();
}
public
Download
State
Builder
setId
(
String
id
)
{
public
DownloadBuilder
setId
(
String
id
)
{
this
.
id
=
id
;
return
this
;
}
public
Download
State
Builder
setType
(
String
type
)
{
public
DownloadBuilder
setType
(
String
type
)
{
this
.
type
=
type
;
return
this
;
}
public
Download
State
Builder
setUri
(
String
uri
)
{
public
DownloadBuilder
setUri
(
String
uri
)
{
this
.
uri
=
Uri
.
parse
(
uri
);
return
this
;
}
public
Download
State
Builder
setUri
(
Uri
uri
)
{
public
DownloadBuilder
setUri
(
Uri
uri
)
{
this
.
uri
=
uri
;
return
this
;
}
public
Download
State
Builder
setCacheKey
(
@Nullable
String
cacheKey
)
{
public
DownloadBuilder
setCacheKey
(
@Nullable
String
cacheKey
)
{
this
.
cacheKey
=
cacheKey
;
return
this
;
}
public
Download
State
Builder
setState
(
int
state
)
{
public
DownloadBuilder
setState
(
int
state
)
{
this
.
state
=
state
;
return
this
;
}
public
Download
State
Builder
setDownloadPercentage
(
float
downloadPercentage
)
{
public
DownloadBuilder
setDownloadPercentage
(
float
downloadPercentage
)
{
counters
.
percentage
=
downloadPercentage
;
return
this
;
}
public
Download
State
Builder
setDownloadedBytes
(
long
downloadedBytes
)
{
public
DownloadBuilder
setDownloadedBytes
(
long
downloadedBytes
)
{
counters
.
alreadyCachedBytes
=
downloadedBytes
;
return
this
;
}
public
Download
State
Builder
setTotalBytes
(
long
totalBytes
)
{
public
DownloadBuilder
setTotalBytes
(
long
totalBytes
)
{
counters
.
contentLength
=
totalBytes
;
return
this
;
}
public
Download
State
Builder
setFailureReason
(
int
failureReason
)
{
public
DownloadBuilder
setFailureReason
(
int
failureReason
)
{
this
.
failureReason
=
failureReason
;
return
this
;
}
public
Download
State
Builder
setManualStopReason
(
int
manualStopReason
)
{
public
DownloadBuilder
setManualStopReason
(
int
manualStopReason
)
{
this
.
manualStopReason
=
manualStopReason
;
return
this
;
}
public
Download
State
Builder
setStartTimeMs
(
long
startTimeMs
)
{
public
DownloadBuilder
setStartTimeMs
(
long
startTimeMs
)
{
this
.
startTimeMs
=
startTimeMs
;
return
this
;
}
public
Download
State
Builder
setUpdateTimeMs
(
long
updateTimeMs
)
{
public
DownloadBuilder
setUpdateTimeMs
(
long
updateTimeMs
)
{
this
.
updateTimeMs
=
updateTimeMs
;
return
this
;
}
public
Download
State
Builder
setStreamKeys
(
StreamKey
...
streamKeys
)
{
public
DownloadBuilder
setStreamKeys
(
StreamKey
...
streamKeys
)
{
this
.
streamKeys
=
Arrays
.
asList
(
streamKeys
);
return
this
;
}
public
Download
State
Builder
setCustomMetadata
(
byte
[]
customMetadata
)
{
public
DownloadBuilder
setCustomMetadata
(
byte
[]
customMetadata
)
{
this
.
customMetadata
=
customMetadata
;
return
this
;
}
public
Download
State
build
()
{
public
Download
build
()
{
DownloadAction
action
=
new
DownloadAction
(
id
,
type
,
uri
,
streamKeys
,
cacheKey
,
customMetadata
);
return
new
DownloadState
(
action
,
state
,
failureReason
,
manualStopReason
,
startTimeMs
,
updateTimeMs
,
counters
);
return
new
Download
(
action
,
state
,
failureReason
,
manualStopReason
,
startTimeMs
,
updateTimeMs
,
counters
);
}
}
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadIndexUtilTest.java
View file @
8688bd2d
...
...
@@ -56,7 +56,7 @@ public class DownloadIndexUtilTest {
}
@Test
public
void
addAction_nonExistingDownload
State_createsNewDownloadState
()
throws
IOException
{
public
void
addAction_nonExistingDownload
_createsNewDownload
()
throws
IOException
{
byte
[]
data
=
new
byte
[]
{
1
,
2
,
3
,
4
};
DownloadAction
action
=
new
DownloadAction
(
...
...
@@ -71,11 +71,11 @@ public class DownloadIndexUtilTest {
DownloadIndexUtil
.
mergeAction
(
action
,
downloadIndex
);
assertDownloadIndexContainsAction
(
action
,
Download
State
.
STATE_QUEUED
);
assertDownloadIndexContainsAction
(
action
,
Download
.
STATE_QUEUED
);
}
@Test
public
void
addAction_existingDownload
State_createsMergedDownloadState
()
throws
IOException
{
public
void
addAction_existingDownload
_createsMergedDownload
()
throws
IOException
{
StreamKey
streamKey1
=
new
StreamKey
(
/* periodIndex= */
3
,
/* groupIndex= */
4
,
/* trackIndex= */
5
);
StreamKey
streamKey2
=
...
...
@@ -100,18 +100,18 @@ public class DownloadIndexUtilTest {
DownloadIndexUtil
.
mergeAction
(
action2
,
downloadIndex
);
Download
State
downloadState
=
downloadIndex
.
getDownloadState
(
action2
.
id
);
assertThat
(
download
State
).
isNotNull
();
assertThat
(
download
State
.
action
.
type
).
isEqualTo
(
action2
.
type
);
assertThat
(
download
State
.
action
.
customCacheKey
).
isEqualTo
(
action2
.
customCacheKey
);
assertThat
(
download
State
.
action
.
data
).
isEqualTo
(
action2
.
data
);
assertThat
(
download
State
.
action
.
uri
).
isEqualTo
(
action2
.
uri
);
assertThat
(
download
State
.
action
.
streamKeys
).
containsExactly
(
streamKey1
,
streamKey2
);
assertThat
(
download
State
.
state
).
isEqualTo
(
DownloadState
.
STATE_QUEUED
);
Download
download
=
downloadIndex
.
getDownload
(
action2
.
id
);
assertThat
(
download
).
isNotNull
();
assertThat
(
download
.
action
.
type
).
isEqualTo
(
action2
.
type
);
assertThat
(
download
.
action
.
customCacheKey
).
isEqualTo
(
action2
.
customCacheKey
);
assertThat
(
download
.
action
.
data
).
isEqualTo
(
action2
.
data
);
assertThat
(
download
.
action
.
uri
).
isEqualTo
(
action2
.
uri
);
assertThat
(
download
.
action
.
streamKeys
).
containsExactly
(
streamKey1
,
streamKey2
);
assertThat
(
download
.
state
).
isEqualTo
(
Download
.
STATE_QUEUED
);
}
@Test
public
void
upgradeActionFile_createsDownload
State
s
()
throws
IOException
{
public
void
upgradeActionFile_createsDownloads
()
throws
IOException
{
// Copy the test asset to a file.
byte
[]
actionFileBytes
=
TestUtil
.
getByteArray
(
...
...
@@ -144,15 +144,15 @@ public class DownloadIndexUtilTest {
ActionFile
actionFile
=
new
ActionFile
(
tempFile
);
DownloadIndexUtil
.
mergeActionFile
(
actionFile
,
/* downloadIdProvider= */
null
,
downloadIndex
);
assertDownloadIndexContainsAction
(
expectedAction1
,
Download
State
.
STATE_QUEUED
);
assertDownloadIndexContainsAction
(
expectedAction2
,
Download
State
.
STATE_QUEUED
);
assertDownloadIndexContainsAction
(
expectedAction1
,
Download
.
STATE_QUEUED
);
assertDownloadIndexContainsAction
(
expectedAction2
,
Download
.
STATE_QUEUED
);
}
private
void
assertDownloadIndexContainsAction
(
DownloadAction
action
,
int
state
)
throws
IOException
{
Download
State
downloadState
=
downloadIndex
.
getDownloadState
(
action
.
id
);
assertThat
(
download
State
.
action
).
isEqualTo
(
action
);
assertThat
(
download
State
.
state
).
isEqualTo
(
state
);
Download
download
=
downloadIndex
.
getDownload
(
action
.
id
);
assertThat
(
download
.
action
).
isEqualTo
(
action
);
assertThat
(
download
.
state
).
isEqualTo
(
state
);
}
@SuppressWarnings
(
"unchecked"
)
...
...
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java
View file @
8688bd2d
...
...
@@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import
android.net.Uri
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.offline.Download
State
.State
;
import
com.google.android.exoplayer2.offline.Download.State
;
import
com.google.android.exoplayer2.scheduler.Requirements
;
import
com.google.android.exoplayer2.testutil.DummyMainThread
;
import
com.google.android.exoplayer2.testutil.DummyMainThread.TestRunnable
;
...
...
@@ -343,7 +343,7 @@ public class DownloadManagerTest {
TaskWrapper
task3
=
new
DownloadRunner
(
uri3
).
postDownloadAction
().
postRemoveAction
().
getTask
();
task3
.
assertRemoving
();
Download
State
[]
states
=
downloadManager
.
getAllDownloadState
s
();
Download
[]
states
=
downloadManager
.
getAllDownload
s
();
assertThat
(
states
).
hasLength
(
3
);
String
[]
taskIds
=
{
task1
.
taskId
,
task2
.
taskId
,
task3
.
taskId
};
...
...
@@ -554,27 +554,27 @@ public class DownloadManagerTest {
}
private
TaskWrapper
assertDownloading
()
{
return
assertState
(
Download
State
.
STATE_DOWNLOADING
);
return
assertState
(
Download
.
STATE_DOWNLOADING
);
}
private
TaskWrapper
assertCompleted
()
{
return
assertState
(
Download
State
.
STATE_COMPLETED
);
return
assertState
(
Download
.
STATE_COMPLETED
);
}
private
TaskWrapper
assertRemoving
()
{
return
assertState
(
Download
State
.
STATE_REMOVING
);
return
assertState
(
Download
.
STATE_REMOVING
);
}
private
TaskWrapper
assertFailed
()
{
return
assertState
(
Download
State
.
STATE_FAILED
);
return
assertState
(
Download
.
STATE_FAILED
);
}
private
TaskWrapper
assertQueued
()
{
return
assertState
(
Download
State
.
STATE_QUEUED
);
return
assertState
(
Download
.
STATE_QUEUED
);
}
private
TaskWrapper
assertStopped
()
{
return
assertState
(
Download
State
.
STATE_STOPPED
);
return
assertState
(
Download
.
STATE_STOPPED
);
}
private
TaskWrapper
assertState
(
@State
int
expectedState
)
{
...
...
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java
deleted
100644 → 0
View file @
f0cd144b
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
offline
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
junit
.
Assert
.
fail
;
import
android.net.Uri
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit tests for {@link DownloadState}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
DownloadStateTest
{
private
Uri
testUri
;
@Before
public
void
setUp
()
throws
Exception
{
testUri
=
Uri
.
parse
(
"https://www.test.com/download1"
);
}
@Test
public
void
mergeAction_actionHaveDifferentType_throwsException
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadState
downloadState
=
new
DownloadStateBuilder
(
downloadAction
)
.
setType
(
downloadAction
.
type
+
"_different"
)
.
setState
(
DownloadState
.
STATE_QUEUED
)
.
build
();
try
{
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
fail
();
}
catch
(
Exception
e
)
{
// Expected.
}
}
@Test
public
void
mergeAction_actionHaveDifferentId_throwsException
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadState
downloadState
=
new
DownloadStateBuilder
(
downloadAction
)
.
setId
(
downloadAction
.
id
+
"_different"
)
.
setState
(
DownloadState
.
STATE_QUEUED
)
.
build
();
try
{
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
fail
();
}
catch
(
Exception
e
)
{
// Expected.
}
}
@Test
public
void
mergeAction_actionsWithSameIdAndType_doesNotFail
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
).
setState
(
DownloadState
.
STATE_QUEUED
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
}
@Test
public
void
mergeAction_actionHaveDifferentUri_downloadStateUriIsUpdated
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setUri
(
downloadAction
.
uri
+
"_different"
)
.
setState
(
DownloadState
.
STATE_QUEUED
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setUri
(
downloadAction
.
uri
).
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
@Test
public
void
mergeAction_actionHaveDifferentData_downloadStateDataIsUpdated
()
{
DownloadAction
downloadAction
=
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Collections
.
emptyList
(),
/* customCacheKey= */
null
,
/* data= */
new
byte
[]
{
1
,
2
,
3
,
4
});
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setState
(
DownloadState
.
STATE_QUEUED
)
.
setCustomMetadata
(
new
byte
[
0
]);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setCustomMetadata
(
downloadAction
.
data
).
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
@Test
public
void
mergeAction_removingDownloadDownloadAction_stateBecomesRestarting
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
).
setState
(
DownloadState
.
STATE_REMOVING
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setState
(
DownloadState
.
STATE_RESTARTING
).
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
@Test
public
void
mergeAction_failedDownloadDownloadAction_stateBecomesQueued
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setState
(
DownloadState
.
STATE_FAILED
)
.
setFailureReason
(
DownloadState
.
FAILURE_REASON_UNKNOWN
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setState
(
DownloadState
.
STATE_QUEUED
)
.
setFailureReason
(
DownloadState
.
FAILURE_REASON_NONE
)
.
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
@Test
public
void
mergeAction_stoppedDownloadDownloadAction_stateStaysStopped
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setState
(
DownloadState
.
STATE_STOPPED
)
.
setManualStopReason
(
DownloadState
.
MANUAL_STOP_REASON_UNDEFINED
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
assertEqual
(
mergedDownloadState
,
downloadState
);
}
@Test
public
void
mergeAction_manualStopReasonSetButNotInStoppedState_stateBecomesStopped
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setState
(
DownloadState
.
STATE_COMPLETED
)
.
setManualStopReason
(
DownloadState
.
MANUAL_STOP_REASON_UNDEFINED
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setState
(
DownloadState
.
STATE_STOPPED
).
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
@Test
public
void
mergeAction_returnsMergedKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{
streamKey1
,
streamKey2
};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_returnsUniqueKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey1Copy
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
,
streamKey1Copy
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{
streamKey1
,
streamKey2
};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_ifFirstActionKeysEmpty_returnsEmptyKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
,
streamKey1
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_ifNotFirstActionKeysEmpty_returnsEmptyKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey2
,
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
private
void
doTestMergeActionReturnsMergedKeys
(
StreamKey
[]
keys1
,
StreamKey
[]
keys2
,
StreamKey
[]
expectedKeys
)
{
DownloadAction
downloadAction
=
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Arrays
.
asList
(
keys2
),
/* customCacheKey= */
null
,
/* data= */
null
);
DownloadStateBuilder
downloadStateBuilder
=
new
DownloadStateBuilder
(
downloadAction
)
.
setState
(
DownloadState
.
STATE_QUEUED
)
.
setStreamKeys
(
keys1
);
DownloadState
downloadState
=
downloadStateBuilder
.
build
();
DownloadState
mergedDownloadState
=
downloadState
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
DownloadState
expectedDownloadState
=
downloadStateBuilder
.
setStreamKeys
(
expectedKeys
).
build
();
assertEqual
(
mergedDownloadState
,
expectedDownloadState
);
}
static
void
assertEqual
(
DownloadState
downloadState
,
DownloadState
expected
)
{
assertEqual
(
downloadState
,
expected
,
false
);
}
static
void
assertEqual
(
DownloadState
downloadState
,
DownloadState
that
,
boolean
compareTimeFields
)
{
assertThat
(
downloadState
.
action
).
isEqualTo
(
that
.
action
);
assertThat
(
downloadState
.
state
).
isEqualTo
(
that
.
state
);
assertThat
(
downloadState
.
getDownloadPercentage
()).
isEqualTo
(
that
.
getDownloadPercentage
());
assertThat
(
downloadState
.
getDownloadedBytes
()).
isEqualTo
(
that
.
getDownloadedBytes
());
assertThat
(
downloadState
.
getTotalBytes
()).
isEqualTo
(
that
.
getTotalBytes
());
if
(
compareTimeFields
)
{
assertThat
(
downloadState
.
startTimeMs
).
isEqualTo
(
that
.
startTimeMs
);
assertThat
(
downloadState
.
updateTimeMs
).
isEqualTo
(
that
.
updateTimeMs
);
}
assertThat
(
downloadState
.
failureReason
).
isEqualTo
(
that
.
failureReason
);
assertThat
(
downloadState
.
manualStopReason
).
isEqualTo
(
that
.
manualStopReason
);
}
private
DownloadAction
createDownloadAction
()
{
return
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Collections
.
emptyList
(),
/* customCacheKey= */
null
,
/* data= */
null
);
}
}
library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadTest.java
0 → 100644
View file @
8688bd2d
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer2
.
offline
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
static
org
.
junit
.
Assert
.
fail
;
import
android.net.Uri
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit tests for {@link Download}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
class
DownloadTest
{
private
Uri
testUri
;
@Before
public
void
setUp
()
throws
Exception
{
testUri
=
Uri
.
parse
(
"https://www.test.com/download1"
);
}
@Test
public
void
mergeAction_actionHaveDifferentType_throwsException
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
Download
download
=
new
DownloadBuilder
(
downloadAction
)
.
setType
(
downloadAction
.
type
+
"_different"
)
.
setState
(
Download
.
STATE_QUEUED
)
.
build
();
try
{
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
fail
();
}
catch
(
Exception
e
)
{
// Expected.
}
}
@Test
public
void
mergeAction_actionHaveDifferentId_throwsException
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
Download
download
=
new
DownloadBuilder
(
downloadAction
)
.
setId
(
downloadAction
.
id
+
"_different"
)
.
setState
(
Download
.
STATE_QUEUED
)
.
build
();
try
{
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
fail
();
}
catch
(
Exception
e
)
{
// Expected.
}
}
@Test
public
void
mergeAction_actionsWithSameIdAndType_doesNotFail
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
).
setState
(
Download
.
STATE_QUEUED
);
Download
download
=
downloadBuilder
.
build
();
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
}
@Test
public
void
mergeAction_actionHaveDifferentUri_downloadUriIsUpdated
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
)
.
setUri
(
downloadAction
.
uri
+
"_different"
)
.
setState
(
Download
.
STATE_QUEUED
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setUri
(
downloadAction
.
uri
).
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
@Test
public
void
mergeAction_actionHaveDifferentData_downloadDataIsUpdated
()
{
DownloadAction
downloadAction
=
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Collections
.
emptyList
(),
/* customCacheKey= */
null
,
/* data= */
new
byte
[]
{
1
,
2
,
3
,
4
});
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
)
.
setState
(
Download
.
STATE_QUEUED
)
.
setCustomMetadata
(
new
byte
[
0
]);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setCustomMetadata
(
downloadAction
.
data
).
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
@Test
public
void
mergeAction_removingDownloadDownloadAction_stateBecomesRestarting
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
).
setState
(
Download
.
STATE_REMOVING
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setState
(
Download
.
STATE_RESTARTING
).
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
@Test
public
void
mergeAction_failedDownloadDownloadAction_stateBecomesQueued
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
)
.
setState
(
Download
.
STATE_FAILED
)
.
setFailureReason
(
Download
.
FAILURE_REASON_UNKNOWN
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setState
(
Download
.
STATE_QUEUED
)
.
setFailureReason
(
Download
.
FAILURE_REASON_NONE
)
.
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
@Test
public
void
mergeAction_stoppedDownloadDownloadAction_stateStaysStopped
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
)
.
setState
(
Download
.
STATE_STOPPED
)
.
setManualStopReason
(
Download
.
MANUAL_STOP_REASON_UNDEFINED
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
assertEqual
(
mergedDownload
,
download
);
}
@Test
public
void
mergeAction_manualStopReasonSetButNotInStoppedState_stateBecomesStopped
()
{
DownloadAction
downloadAction
=
createDownloadAction
();
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
)
.
setState
(
Download
.
STATE_COMPLETED
)
.
setManualStopReason
(
Download
.
MANUAL_STOP_REASON_UNDEFINED
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setState
(
Download
.
STATE_STOPPED
).
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
@Test
public
void
mergeAction_returnsMergedKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{
streamKey1
,
streamKey2
};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_returnsUniqueKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey1Copy
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
,
streamKey1Copy
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{
streamKey1
,
streamKey2
};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_ifFirstActionKeysEmpty_returnsEmptyKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{};
StreamKey
[]
keys2
=
new
StreamKey
[]
{
streamKey2
,
streamKey1
};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
@Test
public
void
mergeAction_ifNotFirstActionKeysEmpty_returnsEmptyKeys
()
{
StreamKey
streamKey1
=
new
StreamKey
(
/* groupIndex= */
0
,
/* trackIndex= */
0
);
StreamKey
streamKey2
=
new
StreamKey
(
/* groupIndex= */
1
,
/* trackIndex= */
1
);
StreamKey
[]
keys1
=
new
StreamKey
[]
{
streamKey2
,
streamKey1
};
StreamKey
[]
keys2
=
new
StreamKey
[]
{};
StreamKey
[]
expectedKeys
=
new
StreamKey
[]
{};
doTestMergeActionReturnsMergedKeys
(
keys1
,
keys2
,
expectedKeys
);
}
private
void
doTestMergeActionReturnsMergedKeys
(
StreamKey
[]
keys1
,
StreamKey
[]
keys2
,
StreamKey
[]
expectedKeys
)
{
DownloadAction
downloadAction
=
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Arrays
.
asList
(
keys2
),
/* customCacheKey= */
null
,
/* data= */
null
);
DownloadBuilder
downloadBuilder
=
new
DownloadBuilder
(
downloadAction
).
setState
(
Download
.
STATE_QUEUED
).
setStreamKeys
(
keys1
);
Download
download
=
downloadBuilder
.
build
();
Download
mergedDownload
=
download
.
copyWithMergedAction
(
downloadAction
,
/* canStart= */
true
);
Download
expectedDownload
=
downloadBuilder
.
setStreamKeys
(
expectedKeys
).
build
();
assertEqual
(
mergedDownload
,
expectedDownload
);
}
static
void
assertEqual
(
Download
download
,
Download
expected
)
{
assertEqual
(
download
,
expected
,
false
);
}
static
void
assertEqual
(
Download
download
,
Download
that
,
boolean
compareTimeFields
)
{
assertThat
(
download
.
action
).
isEqualTo
(
that
.
action
);
assertThat
(
download
.
state
).
isEqualTo
(
that
.
state
);
assertThat
(
download
.
getDownloadPercentage
()).
isEqualTo
(
that
.
getDownloadPercentage
());
assertThat
(
download
.
getDownloadedBytes
()).
isEqualTo
(
that
.
getDownloadedBytes
());
assertThat
(
download
.
getTotalBytes
()).
isEqualTo
(
that
.
getTotalBytes
());
if
(
compareTimeFields
)
{
assertThat
(
download
.
startTimeMs
).
isEqualTo
(
that
.
startTimeMs
);
assertThat
(
download
.
updateTimeMs
).
isEqualTo
(
that
.
updateTimeMs
);
}
assertThat
(
download
.
failureReason
).
isEqualTo
(
that
.
failureReason
);
assertThat
(
download
.
manualStopReason
).
isEqualTo
(
that
.
manualStopReason
);
}
private
DownloadAction
createDownloadAction
()
{
return
new
DownloadAction
(
"id"
,
DownloadAction
.
TYPE_DASH
,
testUri
,
Collections
.
emptyList
(),
/* customCacheKey= */
null
,
/* data= */
null
);
}
}
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java
View file @
8688bd2d
...
...
@@ -29,10 +29,10 @@ import androidx.test.core.app.ApplicationProvider;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.android.exoplayer2.offline.DefaultDownloadIndex
;
import
com.google.android.exoplayer2.offline.DefaultDownloaderFactory
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.DownloadAction
;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadService
;
import
com.google.android.exoplayer2.offline.DownloadState
;
import
com.google.android.exoplayer2.offline.DownloaderConstructorHelper
;
import
com.google.android.exoplayer2.offline.StreamKey
;
import
com.google.android.exoplayer2.scheduler.Requirements
;
...
...
@@ -141,7 +141,7 @@ public class DownloadServiceDashTest {
}
@Override
protected
Notification
getForegroundNotification
(
Download
State
[]
downloadState
s
)
{
protected
Notification
getForegroundNotification
(
Download
[]
download
s
)
{
throw
new
UnsupportedOperationException
();
}
};
...
...
library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java
View file @
8688bd2d
...
...
@@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
import
androidx.annotation.StringRes
;
import
androidx.core.app.NotificationCompat
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.offline.Download
State
;
import
com.google.android.exoplayer2.offline.Download
;
/** Helper for creating download notifications. */
public
final
class
DownloadNotificationHelper
{
...
...
@@ -49,37 +49,37 @@ public final class DownloadNotificationHelper {
* @param smallIcon A small icon for the notification.
* @param contentIntent An optional content intent to send when the notification is clicked.
* @param message An optional message to display on the notification.
* @param download
State
s The download states.
* @param downloads The download states.
* @return The notification.
*/
public
Notification
buildProgressNotification
(
@DrawableRes
int
smallIcon
,
@Nullable
PendingIntent
contentIntent
,
@Nullable
String
message
,
Download
State
[]
downloadState
s
)
{
Download
[]
download
s
)
{
float
totalPercentage
=
0
;
int
downloadTaskCount
=
0
;
boolean
allDownloadPercentagesUnknown
=
true
;
boolean
haveDownloadedBytes
=
false
;
boolean
haveDownloadTasks
=
false
;
boolean
haveRemoveTasks
=
false
;
for
(
Download
State
downloadState
:
downloadState
s
)
{
if
(
download
State
.
state
==
DownloadState
.
STATE_REMOVING
||
download
State
.
state
==
DownloadState
.
STATE_RESTARTING
)
{
for
(
Download
download
:
download
s
)
{
if
(
download
.
state
==
Download
.
STATE_REMOVING
||
download
.
state
==
Download
.
STATE_RESTARTING
)
{
haveRemoveTasks
=
true
;
continue
;
}
if
(
download
State
.
state
!=
DownloadState
.
STATE_DOWNLOADING
&&
download
State
.
state
!=
DownloadState
.
STATE_COMPLETED
)
{
if
(
download
.
state
!=
Download
.
STATE_DOWNLOADING
&&
download
.
state
!=
Download
.
STATE_COMPLETED
)
{
continue
;
}
haveDownloadTasks
=
true
;
float
downloadPercentage
=
download
State
.
getDownloadPercentage
();
float
downloadPercentage
=
download
.
getDownloadPercentage
();
if
(
downloadPercentage
!=
C
.
PERCENTAGE_UNSET
)
{
allDownloadPercentagesUnknown
=
false
;
totalPercentage
+=
downloadPercentage
;
}
haveDownloadedBytes
|=
download
State
.
getDownloadedBytes
()
>
0
;
haveDownloadedBytes
|=
download
.
getDownloadedBytes
()
>
0
;
downloadTaskCount
++;
}
...
...
library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationUtil.java
View file @
8688bd2d
...
...
@@ -20,7 +20,7 @@ import android.app.PendingIntent;
import
android.content.Context
;
import
androidx.annotation.DrawableRes
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.offline.Download
State
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.util.Util
;
/**
...
...
@@ -40,7 +40,7 @@ public final class DownloadNotificationUtil {
* @param channelId The id of the notification channel to use.
* @param contentIntent An optional content intent to send when the notification is clicked.
* @param message An optional message to display on the notification.
* @param download
State
s The download states.
* @param downloads The download states.
* @return The notification.
*/
public
static
Notification
buildProgressNotification
(
...
...
@@ -49,9 +49,9 @@ public final class DownloadNotificationUtil {
String
channelId
,
@Nullable
PendingIntent
contentIntent
,
@Nullable
String
message
,
Download
State
[]
downloadState
s
)
{
Download
[]
download
s
)
{
return
new
DownloadNotificationHelper
(
context
,
channelId
)
.
buildProgressNotification
(
smallIcon
,
contentIntent
,
message
,
download
State
s
);
.
buildProgressNotification
(
smallIcon
,
contentIntent
,
message
,
downloads
);
}
/**
...
...
testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/TestDownloadManagerListener.java
View file @
8688bd2d
...
...
@@ -19,9 +19,9 @@ import static com.google.common.truth.Truth.assertThat;
import
static
org
.
junit
.
Assert
.
fail
;
import
android.os.ConditionVariable
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.Download.State
;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadState
;
import
com.google.android.exoplayer2.offline.DownloadState.State
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Locale
;
...
...
@@ -42,7 +42,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
private
final
ConditionVariable
initializedCondition
;
private
CountDownLatch
downloadFinishedCondition
;
@Download
State
.
FailureReason
private
int
failureReason
;
@Download
.
FailureReason
private
int
failureReason
;
public
TestDownloadManagerListener
(
DownloadManager
downloadManager
,
DummyMainThread
dummyMainThread
)
{
...
...
@@ -69,16 +69,16 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
}
@Override
public
void
onDownload
StateChanged
(
DownloadManager
downloadManager
,
DownloadState
downloadState
)
{
if
(
download
State
.
state
==
DownloadState
.
STATE_FAILED
)
{
failureReason
=
download
State
.
failureReason
;
public
void
onDownload
Changed
(
DownloadManager
downloadManager
,
Download
download
)
{
if
(
download
.
state
==
Download
.
STATE_FAILED
)
{
failureReason
=
download
.
failureReason
;
}
getStateQueue
(
download
State
.
action
.
id
).
add
(
downloadState
.
state
);
getStateQueue
(
download
.
action
.
id
).
add
(
download
.
state
);
}
@Override
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
State
downloadState
)
{
getStateQueue
(
download
State
.
action
.
id
).
add
(
STATE_REMOVED
);
public
void
onDownloadRemoved
(
DownloadManager
downloadManager
,
Download
download
)
{
getStateQueue
(
download
.
action
.
id
).
add
(
STATE_REMOVED
);
}
@Override
...
...
@@ -94,8 +94,8 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
*/
public
void
blockUntilTasksCompleteAndThrowAnyDownloadError
()
throws
Throwable
{
blockUntilTasksComplete
();
if
(
failureReason
!=
Download
State
.
FAILURE_REASON_NONE
)
{
throw
new
Exception
(
"Failure reason: "
+
Download
State
.
getFailureString
(
failureReason
));
if
(
failureReason
!=
Download
.
FAILURE_REASON_NONE
)
{
throw
new
Exception
(
"Failure reason: "
+
Download
.
getFailureString
(
failureReason
));
}
}
...
...
@@ -152,9 +152,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
}
int
receivedState
=
receivedStates
.
get
(
i
);
String
receivedStateString
=
receivedState
==
STATE_REMOVED
?
"REMOVED"
:
DownloadState
.
getStateString
(
receivedState
);
receivedState
==
STATE_REMOVED
?
"REMOVED"
:
Download
.
getStateString
(
receivedState
);
sb
.
append
(
receivedStateString
);
}
fail
(
...
...
@@ -162,7 +160,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
Locale
.
US
,
"for download (%s) expected:<%s> but was:<%s>"
,
taskId
,
Download
State
.
getStateString
(
expectedState
),
Download
.
getStateString
(
expectedState
),
sb
));
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment