1
1
package com.tonyodev.fetch2.helper
2
2
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
3
6
import com.tonyodev.fetch2.*
4
7
import com.tonyodev.fetch2.downloader.DownloadManager
5
8
import com.tonyodev.fetch2core.HandlerWrapper
6
9
import com.tonyodev.fetch2.provider.DownloadProvider
7
10
import com.tonyodev.fetch2.provider.NetworkInfoProvider
8
- import com.tonyodev.fetch2.util.PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS
11
+ import com.tonyodev.fetch2.util.DEFAULT_PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS
9
12
import com.tonyodev.fetch2.NetworkType
10
13
import com.tonyodev.fetch2.fetch.ListenerCoordinator
11
14
import com.tonyodev.fetch2core.Logger
12
15
import com.tonyodev.fetch2core.isFetchFileServerUrl
16
+ import java.util.concurrent.TimeUnit
13
17
14
18
class PriorityListProcessorImpl constructor(private val handlerWrapper : HandlerWrapper ,
15
19
private val downloadProvider : DownloadProvider ,
@@ -33,10 +37,29 @@ class PriorityListProcessorImpl constructor(private val handlerWrapper: HandlerW
33
37
private var stopped = true
34
38
override val isStopped: Boolean
35
39
get() = stopped
40
+ @Volatile
41
+ private var backOffTime = DEFAULT_PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS
42
+ private val networkBroadcastReceiver: BroadcastReceiver = object : BroadcastReceiver () {
43
+
44
+ override fun onReceive (context : Context ? , intent : Intent ? ) {
45
+ if (context != null && ! stopped && ! paused && networkInfoProvider.isNetworkAvailable
46
+ && backOffTime > DEFAULT_PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS ) {
47
+ resetBackOffTime()
48
+ }
49
+ }
50
+ }
51
+
52
+ init {
53
+ networkInfoProvider.registerNetworkBroadcastReceiver(networkBroadcastReceiver)
54
+ }
55
+
36
56
private val priorityIteratorRunnable = Runnable {
37
57
if (canContinueToProcess()) {
38
58
if (downloadManager.canAccommodateNewDownload() && canContinueToProcess()) {
39
59
val priorityList = getPriorityList()
60
+ if (priorityList.isEmpty() || ! networkInfoProvider.isNetworkAvailable) {
61
+ increaseBackOffTime()
62
+ }
40
63
delegate?.onHasActiveDownloads(priorityList.isNotEmpty())
41
64
for (index in 0 .. priorityList.lastIndex) {
42
65
if (downloadManager.canAccommodateNewDownload() && canContinueToProcess()) {
@@ -70,6 +93,7 @@ class PriorityListProcessorImpl constructor(private val handlerWrapper: HandlerW
70
93
71
94
override fun start () {
72
95
synchronized(lock) {
96
+ resetBackOffTime()
73
97
stopped = false
74
98
paused = false
75
99
delegate?.onHasActiveDownloads(true )
@@ -101,6 +125,7 @@ class PriorityListProcessorImpl constructor(private val handlerWrapper: HandlerW
101
125
102
126
override fun resume () {
103
127
synchronized(lock) {
128
+ resetBackOffTime()
104
129
paused = false
105
130
stopped = false
106
131
registerPriorityIterator()
@@ -121,7 +146,7 @@ class PriorityListProcessorImpl constructor(private val handlerWrapper: HandlerW
121
146
122
147
private fun registerPriorityIterator () {
123
148
if (downloadConcurrentLimit > 0 ) {
124
- handlerWrapper.postDelayed(priorityIteratorRunnable, PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS )
149
+ handlerWrapper.postDelayed(priorityIteratorRunnable, backOffTime )
125
150
}
126
151
}
127
152
@@ -135,4 +160,27 @@ class PriorityListProcessorImpl constructor(private val handlerWrapper: HandlerW
135
160
return ! stopped && ! paused
136
161
}
137
162
163
+ override fun resetBackOffTime () {
164
+ synchronized(lock) {
165
+ backOffTime = DEFAULT_PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS
166
+ unregisterPriorityIterator()
167
+ registerPriorityIterator()
168
+ logger.d(" PriorityIterator backoffTime reset to $backOffTime milliseconds" )
169
+ }
170
+ }
171
+
172
+ private fun increaseBackOffTime () {
173
+ backOffTime = if (backOffTime == DEFAULT_PRIORITY_QUEUE_INTERVAL_IN_MILLISECONDS ) {
174
+ ONE_MINUTE_IN_MILLISECONDS
175
+ } else {
176
+ backOffTime * 2L
177
+ }
178
+ val minutes = TimeUnit .MILLISECONDS .toMinutes(backOffTime)
179
+ logger.d(" PriorityIterator backoffTime increased to $minutes minute(s)" )
180
+ }
181
+
182
+ private companion object {
183
+ private const val ONE_MINUTE_IN_MILLISECONDS = 60000L
184
+ }
185
+
138
186
}
0 commit comments