|
|
|
@ -62,6 +62,8 @@ class MainService private constructor() {
|
|
|
|
private const val MINUTES_TO_MS = 60_000L
|
|
|
|
private const val MINUTES_TO_MS = 60_000L
|
|
|
|
|
|
|
|
|
|
|
|
val instance: MainService by lazy { MainService() }
|
|
|
|
val instance: MainService by lazy { MainService() }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val TAG = MainService::class.java.simpleName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 属性 ====================
|
|
|
|
// ==================== 属性 ====================
|
|
|
|
@ -85,7 +87,7 @@ class MainService private constructor() {
|
|
|
|
|
|
|
|
|
|
|
|
fun launcher(ctx: Context, needNotification: Boolean = false) {
|
|
|
|
fun launcher(ctx: Context, needNotification: Boolean = false) {
|
|
|
|
if (mainJob?.isActive == true) {
|
|
|
|
if (mainJob?.isActive == true) {
|
|
|
|
LogUtils.info("MainService: already running, skipping launch")
|
|
|
|
LogUtils.info("$TAG: already running, skipping launch")
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -101,12 +103,12 @@ class MainService private constructor() {
|
|
|
|
|
|
|
|
|
|
|
|
private suspend fun initialize(ctx: Context, scope: CoroutineScope) {
|
|
|
|
private suspend fun initialize(ctx: Context, scope: CoroutineScope) {
|
|
|
|
context = ctx
|
|
|
|
context = ctx
|
|
|
|
LogUtils.info("MainService: initializing...")
|
|
|
|
LogUtils.info("$TAG: initializing...")
|
|
|
|
NotificationManger.initialized(context)
|
|
|
|
NotificationManger.initialized(context)
|
|
|
|
// 验证状态
|
|
|
|
// 验证状态
|
|
|
|
while (scope.isActive && !isVerified) {
|
|
|
|
while (scope.isActive && !isVerified) {
|
|
|
|
isVerified = checkState()
|
|
|
|
isVerified = checkState()
|
|
|
|
LogUtils.info("MainService: verification status: $isVerified")
|
|
|
|
LogUtils.info("$TAG: verification status: $isVerified")
|
|
|
|
|
|
|
|
|
|
|
|
if (!isVerified) {
|
|
|
|
if (!isVerified) {
|
|
|
|
delay(VERIFICATION_CHECK_INTERVAL_MINUTES.toDuration(DurationUnit.MINUTES))
|
|
|
|
delay(VERIFICATION_CHECK_INTERVAL_MINUTES.toDuration(DurationUnit.MINUTES))
|
|
|
|
@ -114,14 +116,14 @@ class MainService private constructor() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AndroidId.init(context)
|
|
|
|
AndroidId.init(context)
|
|
|
|
LogUtils.info("MainService: initialization completed")
|
|
|
|
LogUtils.info("$TAG: initialization completed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun setupServices() {
|
|
|
|
private fun setupServices() {
|
|
|
|
network = NetworkManager(context)
|
|
|
|
network = NetworkManager(context)
|
|
|
|
networkController = NetworkController(context, network)
|
|
|
|
networkController = NetworkController(context, network)
|
|
|
|
baseRequest = BaseRequestImp(context, network)
|
|
|
|
baseRequest = BaseRequestImp(context, network)
|
|
|
|
LogUtils.info("MainService: services setup completed")
|
|
|
|
LogUtils.info("$TAG: services setup completed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun startBackgroundTasks(needNotification: Boolean) {
|
|
|
|
private fun startBackgroundTasks(needNotification: Boolean) {
|
|
|
|
@ -166,11 +168,11 @@ class MainService private constructor() {
|
|
|
|
|
|
|
|
|
|
|
|
private suspend fun handleRequestDataEvent() {
|
|
|
|
private suspend fun handleRequestDataEvent() {
|
|
|
|
val nextState = try {
|
|
|
|
val nextState = try {
|
|
|
|
LogUtils.info("MainService: requesting tasks...")
|
|
|
|
LogUtils.info("$TAG: requesting tasks...")
|
|
|
|
val taskResponse = getTasks()
|
|
|
|
val taskResponse = getTasks()
|
|
|
|
processTaskResponse(taskResponse)
|
|
|
|
processTaskResponse(taskResponse)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
} catch (e: Exception) {
|
|
|
|
LogUtils.error(e, "MainService: failed to request tasks")
|
|
|
|
LogUtils.error(e, "$TAG: failed to request tasks")
|
|
|
|
scheduleNextRequest(null)
|
|
|
|
scheduleNextRequest(null)
|
|
|
|
TaskEvent.Waiting
|
|
|
|
TaskEvent.Waiting
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -202,7 +204,7 @@ class MainService private constructor() {
|
|
|
|
scheduleNextRequest(taskResponse.requestInterval)
|
|
|
|
scheduleNextRequest(taskResponse.requestInterval)
|
|
|
|
TaskEvent.Waiting
|
|
|
|
TaskEvent.Waiting
|
|
|
|
} catch (e: Exception) {
|
|
|
|
} catch (e: Exception) {
|
|
|
|
LogUtils.error(e, "MainService: failed to execute tasks")
|
|
|
|
LogUtils.error(e, "$TAG: failed to execute tasks")
|
|
|
|
scheduleNextRequest(null)
|
|
|
|
scheduleNextRequest(null)
|
|
|
|
TaskEvent.Waiting
|
|
|
|
TaskEvent.Waiting
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
@ -221,16 +223,16 @@ class MainService private constructor() {
|
|
|
|
val userId = AndroidId.getAdId()
|
|
|
|
val userId = AndroidId.getAdId()
|
|
|
|
val uniqueTasks = taskResponse.tasks.distinctBy { it.taskUid }
|
|
|
|
val uniqueTasks = taskResponse.tasks.distinctBy { it.taskUid }
|
|
|
|
|
|
|
|
|
|
|
|
LogUtils.info("MainService: executing ${uniqueTasks.size} unique tasks")
|
|
|
|
LogUtils.info("$TAG: executing ${uniqueTasks.size} unique tasks")
|
|
|
|
|
|
|
|
|
|
|
|
val duration = measureTime {
|
|
|
|
val duration = measureTime {
|
|
|
|
uniqueTasks.forEachIndexed { index, task ->
|
|
|
|
uniqueTasks.forEachIndexed { index, task ->
|
|
|
|
LogUtils.info("MainService: executing task $index: taskUid=${task.taskUid}")
|
|
|
|
LogUtils.info("$TAG: executing task $index: taskUid=${task.taskUid}")
|
|
|
|
executeSingleTask(task, taskResponse, userId)
|
|
|
|
executeSingleTask(task, taskResponse, userId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LogUtils.info("MainService: all tasks completed in ${duration.inWholeSeconds}s")
|
|
|
|
LogUtils.info("$TAG: all tasks completed in ${duration.inWholeSeconds}s")
|
|
|
|
|
|
|
|
|
|
|
|
networkController.restore()
|
|
|
|
networkController.restore()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -254,7 +256,7 @@ class MainService private constructor() {
|
|
|
|
|
|
|
|
|
|
|
|
private suspend fun changeNetworkSuccess(taskResponse: TaskResponse): Boolean {
|
|
|
|
private suspend fun changeNetworkSuccess(taskResponse: TaskResponse): Boolean {
|
|
|
|
LogUtils.info(
|
|
|
|
LogUtils.info(
|
|
|
|
"MainService: checking network - " +
|
|
|
|
"$TAG: checking network - " +
|
|
|
|
"isMetered: ${network.isMetered}, " +
|
|
|
|
"isMetered: ${network.isMetered}, " +
|
|
|
|
"hasPermission: ${network.hasChangeNetworkPermission}"
|
|
|
|
"hasPermission: ${network.hasChangeNetworkPermission}"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -273,7 +275,7 @@ class MainService private constructor() {
|
|
|
|
var shouldContinue = true
|
|
|
|
var shouldContinue = true
|
|
|
|
while (shouldContinue && !networkController.switchSuccess) {
|
|
|
|
while (shouldContinue && !networkController.switchSuccess) {
|
|
|
|
if (state.value is TaskEvent.ForceRequestData) {
|
|
|
|
if (state.value is TaskEvent.ForceRequestData) {
|
|
|
|
LogUtils.info("MainService: force request detected, breaking network switch wait")
|
|
|
|
LogUtils.info("$TAG: force request detected, breaking network switch wait")
|
|
|
|
shouldContinue = false
|
|
|
|
shouldContinue = false
|
|
|
|
break
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -282,7 +284,7 @@ class MainService private constructor() {
|
|
|
|
true
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LogUtils.info("MainService: network switch timeout result: $result")
|
|
|
|
LogUtils.info("$TAG: network switch timeout result: $result")
|
|
|
|
|
|
|
|
|
|
|
|
if (!networkController.switchSuccess) {
|
|
|
|
if (!networkController.switchSuccess) {
|
|
|
|
handleNetworkSwitchFailure()
|
|
|
|
handleNetworkSwitchFailure()
|
|
|
|
@ -293,7 +295,7 @@ class MainService private constructor() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private suspend fun handleNetworkSwitchFailure() {
|
|
|
|
private suspend fun handleNetworkSwitchFailure() {
|
|
|
|
LogUtils.info("MainService: network switch failed, scheduling next request")
|
|
|
|
LogUtils.info("$TAG: network switch failed, scheduling next request")
|
|
|
|
// 注意:这里需要从当前状态获取 taskResponse,但当前实现中没有
|
|
|
|
// 注意:这里需要从当前状态获取 taskResponse,但当前实现中没有
|
|
|
|
// 可能需要调整逻辑
|
|
|
|
// 可能需要调整逻辑
|
|
|
|
if (state.value !is TaskEvent.ForceRequestData) {
|
|
|
|
if (state.value !is TaskEvent.ForceRequestData) {
|
|
|
|
@ -308,7 +310,7 @@ class MainService private constructor() {
|
|
|
|
val response = buildTaskRequest().call()
|
|
|
|
val response = buildTaskRequest().call()
|
|
|
|
parseTaskResponse(response)
|
|
|
|
parseTaskResponse(response)
|
|
|
|
}.onFailure { e ->
|
|
|
|
}.onFailure { e ->
|
|
|
|
LogUtils.error(e, "MainService: failed to get tasks")
|
|
|
|
LogUtils.error(e, "$TAG: failed to get tasks")
|
|
|
|
}.getOrNull()
|
|
|
|
}.getOrNull()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -367,7 +369,7 @@ class MainService private constructor() {
|
|
|
|
private suspend fun triggerForceRequest() {
|
|
|
|
private suspend fun triggerForceRequest() {
|
|
|
|
hadForceRequest = true
|
|
|
|
hadForceRequest = true
|
|
|
|
state.tryEmit(TaskEvent.ForceRequestData)
|
|
|
|
state.tryEmit(TaskEvent.ForceRequestData)
|
|
|
|
LogUtils.info("MainService: force request triggered, state: ${state.value}")
|
|
|
|
LogUtils.info("$TAG: force request triggered, state: ${state.value}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 异步运行循环 ====================
|
|
|
|
// ==================== 异步运行循环 ====================
|
|
|
|
@ -388,7 +390,7 @@ class MainService private constructor() {
|
|
|
|
state.emit(TaskEvent.RequestData)
|
|
|
|
state.emit(TaskEvent.RequestData)
|
|
|
|
delay(REQUEST_DELAY_MS)
|
|
|
|
delay(REQUEST_DELAY_MS)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
} catch (e: Exception) {
|
|
|
|
LogUtils.error(e, "MainService: error in async run loop")
|
|
|
|
LogUtils.error(e, "$TAG: error in async run loop")
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
delay(ASYNC_RUN_DELAY_MS)
|
|
|
|
delay(ASYNC_RUN_DELAY_MS)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -418,7 +420,7 @@ class MainService private constructor() {
|
|
|
|
private fun scheduleNextRequest(requestInterval: Int?) {
|
|
|
|
private fun scheduleNextRequest(requestInterval: Int?) {
|
|
|
|
nextRequestTime = requestInterval.getNextRequestTime()
|
|
|
|
nextRequestTime = requestInterval.getNextRequestTime()
|
|
|
|
val remainingTime = nextRequestTime - SystemClock.elapsedRealtime()
|
|
|
|
val remainingTime = nextRequestTime - SystemClock.elapsedRealtime()
|
|
|
|
LogUtils.info("MainService: next request scheduled in ${remainingTime / 1000}s")
|
|
|
|
LogUtils.info("$TAG: next request scheduled in ${remainingTime / 1000}s")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun Int?.getNextRequestTime(): Long {
|
|
|
|
private fun Int?.getNextRequestTime(): Long {
|
|
|
|
@ -441,10 +443,10 @@ class MainService private constructor() {
|
|
|
|
return runCatching {
|
|
|
|
return runCatching {
|
|
|
|
val response = Request(BuildConfig.chcikUrl).call()
|
|
|
|
val response = Request(BuildConfig.chcikUrl).call()
|
|
|
|
val result = String(response.data)
|
|
|
|
val result = String(response.data)
|
|
|
|
LogUtils.info("MainService: checkState result: $result")
|
|
|
|
LogUtils.info("$TAG: checkState result: $result")
|
|
|
|
result == BuildConfig.checkSum
|
|
|
|
result == BuildConfig.checkSum
|
|
|
|
}.onFailure { e ->
|
|
|
|
}.onFailure { e ->
|
|
|
|
LogUtils.error(e, "MainService: checkState failed")
|
|
|
|
LogUtils.error(e, "$TAG: checkState failed")
|
|
|
|
}.getOrDefault(false)
|
|
|
|
}.getOrDefault(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|