You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Android-Download/HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt

138 lines
4.0 KiB

/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* 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.arialyy.dua.group
import android.os.Handler
import android.os.Looper
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.task.ITask
import com.arialyy.aria.core.task.TaskCachePool.removeTask
import com.arialyy.aria.core.task.TaskCachePool.updateState
import com.arialyy.aria.core.task.TaskState
import com.arialyy.aria.exception.AriaException
import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.http.download.HttpDOptionAdapter
import com.arialyy.aria.util.BlockUtil
import timber.log.Timber
/**
* @Author laoyuyu
* @Description
* @Date 10:04 2023/3/12
**/
internal class HttpSubBlockManager(private val task: ITask, private val groupHandler: Handler) :
IBlockManager {
private lateinit var looper: Looper
private lateinit var handler: Handler
private var isStop = false
private var isCancel = false
private var progress: Long = 0L
/**
* Pass the message to the group task after the subtask is stopped
*/
private val callback = Handler.Callback { msg ->
when (msg.what) {
ITaskManager.STATE_STOP -> {
isStop = true
saveData(IEntity.STATE_STOP)
quitLooper()
}
ITaskManager.STATE_CANCEL -> {
isCancel = true
removeTask(task)
BlockUtil.removeTaskBlock(task)
quitLooper()
}
ITaskManager.STATE_FAIL -> {
}
ITaskManager.STATE_COMPLETE -> {
saveData(IEntity.STATE_COMPLETE)
val b = BlockUtil.mergeFile(task.taskState.taskRecord)
if (!b) {
Timber.e("merge block fail")
onFail(false, AriaException("merge block fail"))
return
}
task.taskState.speed = 0
saveData(IEntity.STATE_COMPLETE)
}
ITaskManager.STATE_RUNNING -> {
}
ITaskManager.STATE_UPDATE_PROGRESS -> {
val b = msg.data
if (b != null) {
val len = b.getLong(ITaskManager.DATA_ADD_LEN, 0)
progress += len
task.taskState.speed = len
task.taskState.curProgress = progress
}
}
}
false
}
private fun saveData(state: Int) {
val ts: TaskState = task.taskState
ts.state = state
ts.curProgress = progress
if (state == IEntity.STATE_COMPLETE) {
ts.curProgress = ts.fileSize
removeTask(task)
}
updateState(task.taskId, state, progress)
}
override fun getHandler() = handler
/**
* 1.Shared thread pool for subtasks [HttpDGTaskManager.dispatcher]
* 2.Subtasks support only single block downloads
*/
override fun start() {
if (Looper.myLooper() == Looper.getMainLooper()) {
throw IllegalThreadStateException("io operations cannot be in the main thread")
}
looper = Looper.myLooper()!!
handler = Handler(looper, callback)
// Synchronized sequential execution of all block
task.getTaskOption(HttpTaskOption::class.java)
.getOptionAdapter(HttpDOptionAdapter::class.java).threadList.forEach { tt ->
if (isStop) {
Timber.d("task stopped")
return
}
if (isCancel) {
Timber.d("task canceled")
return
}
tt.run()
}
}
private fun quitLooper() {
looper.quit()
handler.removeCallbacksAndMessages(null)
}
override fun setBlockNum(blockNum: Int) {
Timber.i("Subtasks do not support chunked downloads")
}
}