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
a940d8bc
authored
Jan 03, 2019
by
eguven
Committed by
Oliver Woodman
Jan 08, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Use removing and restarting state internally in DownloadManager
PiperOrigin-RevId: 227682159
parent
c1307239
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
99 additions
and
83 deletions
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java
View file @
a940d8bc
...
...
@@ -175,7 +175,6 @@ public final class DownloadManager {
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
downloads
.
get
(
i
).
clearStopFlags
(
STOP_FLAG_STOPPED
);
}
maybeStartDownloads
();
logd
(
"Downloads are started"
);
}
}
...
...
@@ -254,7 +253,7 @@ public final class DownloadManager {
return
false
;
}
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
if
(
downloads
.
get
(
i
).
isStarted
())
{
if
(
!
downloads
.
get
(
i
).
isIdle
())
{
return
false
;
}
}
...
...
@@ -284,8 +283,7 @@ public final class DownloadManager {
private
void
addDownloadForAction
(
DownloadAction
action
)
{
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
Download
download
=
downloads
.
get
(
i
);
if
(
download
.
action
.
isSameMedia
(
action
))
{
download
.
addAction
(
action
);
if
(
download
.
addAction
(
action
))
{
logd
(
"Action is added to existing download"
,
download
);
return
;
}
...
...
@@ -296,33 +294,27 @@ public final class DownloadManager {
logd
(
"Download is added"
,
download
);
}
/**
* Iterates through the download queue and starts any download if all of the following are true:
*
* <ul>
* <li>It hasn't started yet.
* <li>The maximum number of active downloads hasn't been reached.
* </ul>
*/
private
void
maybeStartDownloads
()
{
if
(!
initialized
||
released
)
{
return
;
}
for
(
int
i
=
0
;
i
<
downloads
.
size
();
i
++)
{
maybeStartDownload
(
downloads
.
get
(
i
));
}
}
private
void
maybeStartDownload
(
Download
download
)
{
if
(
download
.
action
.
isRemoveAction
)
{
download
.
start
();
}
else
if
(
activeDownloads
.
size
()
<
maxActiveDownloads
)
{
if
(
initialized
&&
!
released
&&
activeDownloads
.
size
()
<
maxActiveDownloads
)
{
if
(
download
.
start
())
{
activeDownloads
.
add
(
download
);
}
}
}
private
void
maybeRestartDownload
(
Download
download
)
{
Assertions
.
checkState
(
activeDownloads
.
contains
(
download
));
if
(
initialized
&&
!
released
)
{
download
.
start
();
}
}
private
void
maybeNotifyListenersIdle
()
{
if
(!
isIdle
())
{
return
;
...
...
@@ -337,8 +329,8 @@ public final class DownloadManager {
if
(
released
)
{
return
;
}
boolean
stopped
=
!
download
.
isStarted
();
if
(
stopped
)
{
boolean
idle
=
download
.
isIdle
();
if
(
idle
)
{
activeDownloads
.
remove
(
download
);
}
notifyListenersDownloadStateChange
(
download
);
...
...
@@ -346,7 +338,7 @@ public final class DownloadManager {
downloads
.
remove
(
download
);
saveActions
();
}
if
(
stopped
)
{
if
(
idle
)
{
maybeStartDownloads
();
maybeNotifyListenersIdle
();
}
...
...
@@ -380,17 +372,18 @@ public final class DownloadManager {
for
(
DownloadAction
action
:
actions
)
{
addDownloadForAction
(
action
);
}
logd
(
"Downloads are created."
);
initialized
=
true
;
for
(
Listener
listener
:
listeners
)
{
listener
.
onInitialized
(
DownloadManager
.
this
);
}
if
(!
actionQueue
.
isEmpty
())
{
while
(!
actionQueue
.
isEmpty
())
{
addDownloadForAction
(
actionQueue
.
remove
());
}
saveActions
();
}
logd
(
"Downloads are created."
);
initialized
=
true
;
for
(
Listener
listener
:
listeners
)
{
listener
.
onInitialized
(
DownloadManager
.
this
);
}
maybeStartDownloads
();
});
});
}
...
...
@@ -433,7 +426,6 @@ public final class DownloadManager {
private
final
int
minRetryCount
;
private
final
long
startTimeMs
;
private
final
ArrayDeque
<
DownloadAction
>
actionQueue
;
private
DownloadAction
action
;
/** The current state of the download. */
@DownloadState
.
State
private
int
state
;
...
...
@@ -456,29 +448,36 @@ public final class DownloadManager {
this
.
startTimeMs
=
System
.
currentTimeMillis
();
actionQueue
=
new
ArrayDeque
<>();
actionQueue
.
add
(
action
);
// Don't notify listeners until we make sure the state doesn't change immediately.
state
=
STATE_QUEUED
;
setActionAndUpdateState
(
action
);
downloadManager
.
maybeStartDownload
(
this
);
if
(
state
==
STATE_QUEUED
)
{
downloadManager
.
onDownloadStateChange
(
this
);
}
initialize
(
/* restart= */
false
);
}
public
void
addAction
(
DownloadAction
newAction
)
{
public
boolean
addAction
(
DownloadAction
newAction
)
{
DownloadAction
action
=
actionQueue
.
peek
();
if
(!
action
.
isSameMedia
(
newAction
))
{
return
false
;
}
Assertions
.
checkState
(
action
.
type
.
equals
(
newAction
.
type
));
actionQueue
.
add
(
newAction
);
DownloadAction
updatedAction
=
DownloadActionUtil
.
mergeActions
(
actionQueue
);
if
(
action
.
equals
(
updatedAction
))
{
return
;
}
if
(
state
==
STATE_DOWNLOADING
)
{
stopDownloadThread
();
}
else
{
Assertions
.
checkState
(
state
==
STATE_QUEUED
||
state
==
STATE_STOPPED
);
setActionAndUpdateState
(
updatedAction
);
if
(
state
==
STATE_REMOVING
)
{
Assertions
.
checkState
(
updatedAction
.
isRemoveAction
);
if
(
actionQueue
.
size
()
>
1
)
{
setState
(
STATE_RESTARTING
);
}
}
else
if
(
state
==
STATE_RESTARTING
)
{
Assertions
.
checkState
(
updatedAction
.
isRemoveAction
);
if
(
actionQueue
.
size
()
==
1
)
{
setState
(
STATE_REMOVING
);
}
}
else
if
(!
action
.
equals
(
updatedAction
))
{
if
(
state
==
STATE_DOWNLOADING
)
{
stopDownloadThread
();
}
else
{
Assertions
.
checkState
(
state
==
STATE_QUEUED
||
state
==
STATE_STOPPED
);
initialize
(
/* restart= */
false
);
}
}
return
true
;
}
public
DownloadState
getDownloadState
()
{
...
...
@@ -490,20 +489,13 @@ public final class DownloadManager {
downloadedBytes
=
downloader
.
getDownloadedBytes
();
totalBytes
=
downloader
.
getTotalBytes
();
}
int
newState
=
state
;
if
(
action
.
isRemoveAction
)
{
if
(
state
==
STATE_DOWNLOADING
)
{
newState
=
actionQueue
.
size
()
>
1
?
STATE_RESTARTING
:
STATE_REMOVING
;
}
else
if
(
state
==
STATE_COMPLETED
||
state
==
STATE_FAILED
)
{
newState
=
STATE_REMOVED
;
}
}
DownloadAction
action
=
actionQueue
.
peek
();
return
new
DownloadState
(
action
.
id
,
action
.
type
,
action
.
uri
,
action
.
customCacheKey
,
newS
tate
,
s
tate
,
downloadPercentage
,
downloadedBytes
,
totalBytes
,
...
...
@@ -515,30 +507,24 @@ public final class DownloadManager {
action
.
data
);
}
/** Returns whether the download is finished. */
public
boolean
isFinished
()
{
return
state
==
STATE_FAILED
||
state
==
STATE_COMPLETED
;
return
state
==
STATE_FAILED
||
state
==
STATE_COMPLETED
||
state
==
STATE_REMOVED
;
}
/** Returns whether the download is started. */
public
boolean
isStarted
()
{
return
state
==
STATE_DOWNLOADING
;
public
boolean
isIdle
()
{
return
state
!=
STATE_DOWNLOADING
&&
state
!=
STATE_REMOVING
&&
state
!=
STATE_RESTARTING
;
}
@Override
public
String
toString
()
{
String
actionString
=
action
.
isRemoveAction
?
"remove"
:
"download"
;
return
id
+
' '
+
actionString
+
' '
+
DownloadState
.
getStateString
(
state
);
return
id
+
' '
+
DownloadState
.
getStateString
(
state
);
}
public
boolean
start
()
{
if
(
state
!=
STATE_QUEUED
)
{
return
false
;
}
downloader
=
downloaderFactory
.
createDownloader
(
action
);
downloadThread
=
new
DownloadThread
(
this
,
downloader
,
action
.
isRemoveAction
,
minRetryCount
,
downloadManager
.
handler
);
startDownloadThread
(
actionQueue
.
peek
());
setState
(
STATE_DOWNLOADING
);
return
true
;
}
...
...
@@ -560,30 +546,55 @@ public final class DownloadManager {
private
void
updateStopFlags
(
int
mask
,
int
flags
)
{
stopFlags
=
(
flags
&
mask
)
|
(
stopFlags
&
~
mask
);
if
(
stopFlags
!=
0
)
{
if
(!
action
.
isRemoveAction
)
{
if
(
state
==
STATE_DOWNLOADING
)
{
stopDownloadThread
();
}
else
if
(
state
==
STATE_QUEUED
)
{
setState
(
STATE_STOPPED
);
}
if
(
state
==
STATE_DOWNLOADING
)
{
stopDownloadThread
();
}
else
if
(
state
==
STATE_QUEUED
)
{
setState
(
STATE_STOPPED
);
}
}
else
if
(
state
==
STATE_STOPPED
)
{
s
etState
(
STATE_QUEUED
);
s
tartOrQueue
(
/* restart= */
false
);
}
}
private
void
setActionAndUpdateState
(
DownloadAction
action
)
{
this
.
action
=
action
;
setState
(!
this
.
action
.
isRemoveAction
&&
stopFlags
!=
0
?
STATE_STOPPED
:
STATE_QUEUED
);
private
void
initialize
(
boolean
restart
)
{
DownloadAction
action
=
actionQueue
.
peek
();
if
(
action
.
isRemoveAction
)
{
if
(!
downloadManager
.
released
)
{
startDownloadThread
(
action
);
}
setState
(
actionQueue
.
size
()
==
1
?
STATE_REMOVING
:
STATE_RESTARTING
);
}
else
if
(
stopFlags
!=
0
)
{
setState
(
STATE_STOPPED
);
}
else
{
startOrQueue
(
restart
);
}
}
private
void
setState
(
@DownloadState
.
State
int
newState
)
{
if
(
state
!=
newState
)
{
state
=
newState
;
private
void
startOrQueue
(
boolean
restart
)
{
// Set to queued state but don't notify listeners until we make sure we can't start now.
state
=
STATE_QUEUED
;
if
(
restart
)
{
downloadManager
.
maybeRestartDownload
(
this
);
}
else
{
downloadManager
.
maybeStartDownload
(
this
);
}
if
(
state
==
STATE_QUEUED
)
{
downloadManager
.
onDownloadStateChange
(
this
);
}
}
private
void
setState
(
@DownloadState
.
State
int
newState
)
{
state
=
newState
;
downloadManager
.
onDownloadStateChange
(
this
);
}
private
void
startDownloadThread
(
DownloadAction
action
)
{
downloader
=
downloaderFactory
.
createDownloader
(
action
);
downloadThread
=
new
DownloadThread
(
this
,
downloader
,
action
.
isRemoveAction
,
minRetryCount
,
downloadManager
.
handler
);
}
private
void
stopDownloadThread
()
{
Assertions
.
checkNotNull
(
downloadThread
).
cancel
();
}
...
...
@@ -591,18 +602,23 @@ public final class DownloadManager {
private
void
onDownloadThreadStopped
(
@Nullable
Throwable
finalError
)
{
failureReason
=
FAILURE_REASON_NONE
;
if
(!
downloadThread
.
isCanceled
)
{
if
(
finalError
!=
null
)
{
if
(
finalError
!=
null
&&
state
!=
STATE_REMOVING
&&
state
!=
STATE_RESTARTING
)
{
failureReason
=
FAILURE_REASON_UNKNOWN
;
setState
(
STATE_FAILED
);
return
;
}
if
(
actionQueue
.
size
()
==
1
)
{
if
(
state
==
STATE_REMOVING
)
{
setState
(
STATE_REMOVED
);
}
else
{
Assertions
.
checkState
(
state
==
STATE_DOWNLOADING
);
setState
(
STATE_COMPLETED
);
}
return
;
}
actionQueue
.
remove
();
}
if
(!
actionQueue
.
isEmpty
())
{
setActionAndUpdateState
(
actionQueue
.
peek
());
}
else
{
setState
(
STATE_COMPLETED
);
}
initialize
(
/* restart= */
state
==
STATE_DOWNLOADING
);
}
}
...
...
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