fix auto update

This commit is contained in:
Kr328 committed 2020-04-14 10:45:55 +08:00
1 parent c2280555d3
commit 1536c9f056
9 files changed
+54 -64

No files matched your search

@@ -12,6 +12,7 @@ import com.github.kr328.clash.common.util.startForegroundServiceCompat
import com.github.kr328.clash.remote.withProfile
import com.github.kr328.clash.service.ProfileBackgroundService
import com.github.kr328.clash.service.ProfileProvider
import com.github.kr328.clash.service.ProfileReceiver
import com.github.kr328.clash.service.model.ProfileMetadata
import com.github.kr328.clash.weight.ProfilesMenu
import com.google.android.material.snackbar.Snackbar
@@ -151,11 +152,7 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
}
private fun startUpdate(id: Long) {
val intent = Intent(Intents.INTENT_ACTION_PROFILE_REQUEST_UPDATE)
.setComponent(ProfileBackgroundService::class.componentName)
.putExtra(Intents.INTENT_EXTRA_PROFILE_ID, id)
startForegroundServiceCompat(intent)
startForegroundServiceCompat(ProfileReceiver.buildUpdateIntentForId(id))
}
override fun onOpenEditor(entity: ProfileMetadata) {
@@ -4,24 +4,20 @@ import com.github.kr328.clash.common.BuildConfig
object Intents {
const val INTENT_ACTION_CLASH_STARTED =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.clash.started"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.clash.STARTED"
const val INTENT_ACTION_CLASH_STOPPED =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.clash.stopped"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.clash.STOPPED"
const val INTENT_ACTION_CLASH_REQUEST_STOP =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.clash.REQUEST_STOP"
const val INTENT_ACTION_PROFILE_CHANGED =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.changed"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.CHANGED"
const val INTENT_ACTION_PROFILE_REQUEST_UPDATE =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.enqueue.request"
const val INTENT_ACTION_PROFILE_SETUP =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.setup"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.REQUEST_UPDATE"
const val INTENT_ACTION_PROFILE_LOADED =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.loaded"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.profile.LOADED"
const val INTENT_ACTION_NETWORK_CHANGED =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.network.changed"
const val INTENT_ACTION_REQUEST_STOP =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.request.stop"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.action.network.CHANGED"
const val INTENT_EXTRA_CLASH_STOP_REASON =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.clash.stop.reason"
const val INTENT_EXTRA_PROFILE_ID =
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.profile.id"
"${BuildConfig.LIBRARY_PACKAGE_NAME}.intent.extra.clash.STOP_REASON"
}
@@ -62,17 +62,11 @@ class ProfileBackgroundService : BaseService() {
when (intent?.action) {
Intents.INTENT_ACTION_PROFILE_REQUEST_UPDATE -> {
val id = intent.getLongExtra(Intents.INTENT_EXTRA_PROFILE_ID, -1)
if (id < 0)
return START_NOT_STICKY
val id = intent.data?.schemeSpecificPart?.toLongOrNull()
?: return START_NOT_STICKY
requests.offer(id)
}
Intents.INTENT_ACTION_PROFILE_SETUP -> {
launch {
setup()
}
}
}
return START_NOT_STICKY
@@ -132,12 +126,6 @@ class ProfileBackgroundService : BaseService() {
stopSelf()
}
private suspend fun setup() {
for (id in ProfileDao.queryAllIds()) {
ProfileReceiver.requestNextUpdate(this, id)
}
}
private fun createNotificationChannels() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return
@@ -44,6 +44,8 @@ object ProfileProcessor {
ProfileDao.insert(entity)
else
ProfileDao.update(entity)
ProfileReceiver.requestNextUpdate(context, metadata.id)
}
private suspend fun downloadProfile(
@@ -5,14 +5,15 @@ import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.getSystemService
import com.github.kr328.clash.common.ids.Intents
import com.github.kr328.clash.common.ids.PendingIds
import com.github.kr328.clash.common.util.componentName
import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.common.util.startForegroundServiceCompat
import com.github.kr328.clash.service.data.ProfileDao
import com.github.kr328.clash.service.model.toProfileMetadata
import kotlinx.coroutines.sync.Mutex
class ProfileReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
@@ -24,26 +25,20 @@ class ProfileReceiver : BroadcastReceiver() {
intent.component = ProfileBackgroundService::class.componentName
context.startForegroundServiceCompat(intent)
}
Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED -> {
tryInitialize(context)
}
}
}
companion object {
private val requested = mutableMapOf<Long, PendingIntent>()
private var initialized = false
private val initialized = Mutex()
@Synchronized
fun tryInitialize(context: Context) {
if (initialized)
suspend fun initialize(context: Context) {
if ( !initialized.tryLock() )
return
initialized = true
context.startForegroundServiceCompat(
ProfileBackgroundService::class.intent
.setAction(Intents.INTENT_ACTION_PROFILE_SETUP)
)
ProfileDao.queryAllIds().forEach {
requestNextUpdate(context, it)
}
}
suspend fun requestNextUpdate(context: Context, id: Long) {
@@ -53,29 +48,37 @@ class ProfileReceiver : BroadcastReceiver() {
if (metadata.interval <= 0)
return
cancelNextUpdate(context, id)
val pendingIntent = PendingIntent.getBroadcast(
context,
PendingIds.generateProfileResultId(id),
Intent(Intents.INTENT_ACTION_PROFILE_REQUEST_UPDATE)
.setComponent(ProfileReceiver::class.componentName)
.putExtra(Intents.INTENT_EXTRA_PROFILE_ID, id),
PendingIntent.FLAG_UPDATE_CURRENT
)
val pendingIntent = cancelNextUpdate(context, id)
service.set(
AlarmManager.RTC,
metadata.lastModified + metadata.interval,
pendingIntent
)
requested[id] = pendingIntent
}
fun cancelNextUpdate(context: Context, id: Long) {
val service = context.getSystemService<AlarmManager>() ?: return
service.cancel(requested.remove(id) ?: return)
fun cancelNextUpdate(context: Context, id: Long): PendingIntent {
val intent = buildUpdatePendingIntent(context, id)
val service = context.getSystemService<AlarmManager>() ?: return intent
service.cancel(intent)
return intent
}
fun buildUpdateIntentForId(id: Long): Intent {
return Intent(Intents.INTENT_ACTION_PROFILE_REQUEST_UPDATE)
.setComponent(ProfileReceiver::class.componentName)
.setData(Uri.fromParts("id", id.toString(), null))
}
private fun buildUpdatePendingIntent(context: Context, id: Long): PendingIntent {
return PendingIntent.getBroadcast(
context,
PendingIds.generateProfileResultId(id),
buildUpdateIntentForId(id),
PendingIntent.FLAG_UPDATE_CURRENT
)
}
}
}
@@ -151,6 +151,8 @@ class ProfileService : BaseService() {
super.onCreate()
launch {
ProfileReceiver.initialize(service)
process()
}
}
@@ -3,6 +3,8 @@ package com.github.kr328.clash.service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.common.util.startForegroundServiceCompat
import com.github.kr328.clash.service.util.startClashService
class RestartReceiver : BroadcastReceiver() {
@@ -16,7 +18,7 @@ class RestartReceiver : BroadcastReceiver() {
else -> return
}
ProfileReceiver.tryInitialize(context)
context.startForegroundServiceCompat(ProfileBackgroundService::class.intent)
if (ServiceStatusProvider.shouldStartClashOnBoot)
context.startClashService()
@@ -5,7 +5,7 @@ import com.github.kr328.clash.common.ids.Intents
class CloseModule : Module() {
override val receiveBroadcasts: Set<String>
get() = setOf(Intents.INTENT_ACTION_REQUEST_STOP)
get() = setOf(Intents.INTENT_ACTION_CLASH_REQUEST_STOP)
private var callback: () -> Unit = {}
@@ -15,7 +15,7 @@ class CloseModule : Module() {
override suspend fun onBroadcastReceived(intent: Intent) {
when (intent.action) {
Intents.INTENT_ACTION_REQUEST_STOP ->
Intents.INTENT_ACTION_CLASH_REQUEST_STOP ->
callback()
}
}
@@ -27,5 +27,5 @@ fun Context.startClashService(): Intent? {
}
fun Context.stopClashService() {
sendBroadcastSelf(Intent(Intents.INTENT_ACTION_REQUEST_STOP))
sendBroadcastSelf(Intent(Intents.INTENT_ACTION_CLASH_REQUEST_STOP))
}