From 1536c9f056d4edc2514ff8232c71fd41005fd25e Mon Sep 17 00:00:00 2001 From: Kr328 <39107975+Kr328@users.noreply.github.com> Date: Tue, 14 Apr 2020 10:45:55 +0800 Subject: [PATCH] fix auto update --- .../github/kr328/clash/ProfilesActivity.kt | 7 +-- .../github/kr328/clash/common/ids/Intents.kt | 22 +++---- .../clash/service/ProfileBackgroundService.kt | 16 +---- .../kr328/clash/service/ProfileProcessor.kt | 2 + .../kr328/clash/service/ProfileReceiver.kt | 59 ++++++++++--------- .../kr328/clash/service/ProfileService.kt | 2 + .../kr328/clash/service/RestartReceiver.kt | 4 +- .../clash/service/clash/module/CloseModule.kt | 4 +- .../kr328/clash/service/util/ServiceUtils.kt | 2 +- 9 files changed, 54 insertions(+), 64 deletions(-) diff --git a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt index 3162706..49d0330 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt @@ -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) { diff --git a/common/src/main/java/com/github/kr328/clash/common/ids/Intents.kt b/common/src/main/java/com/github/kr328/clash/common/ids/Intents.kt index e88a03a..e448c2e 100644 --- a/common/src/main/java/com/github/kr328/clash/common/ids/Intents.kt +++ b/common/src/main/java/com/github/kr328/clash/common/ids/Intents.kt @@ -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" } \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt index d48836d..2ed3dd2 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileBackgroundService.kt @@ -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 diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileProcessor.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileProcessor.kt index f13fc8a..99f7b08 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileProcessor.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileProcessor.kt @@ -44,6 +44,8 @@ object ProfileProcessor { ProfileDao.insert(entity) else ProfileDao.update(entity) + + ProfileReceiver.requestNextUpdate(context, metadata.id) } private suspend fun downloadProfile( diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt index 03cab16..b3c261c 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileReceiver.kt @@ -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() - 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() ?: return - service.cancel(requested.remove(id) ?: return) + fun cancelNextUpdate(context: Context, id: Long): PendingIntent { + val intent = buildUpdatePendingIntent(context, id) + val service = context.getSystemService() ?: 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 + ) } } } \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt b/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt index c187af0..23d163b 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ProfileService.kt @@ -151,6 +151,8 @@ class ProfileService : BaseService() { super.onCreate() launch { + ProfileReceiver.initialize(service) + process() } } diff --git a/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt b/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt index b1244ef..6f43af7 100644 --- a/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/RestartReceiver.kt @@ -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() diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/module/CloseModule.kt b/service/src/main/java/com/github/kr328/clash/service/clash/module/CloseModule.kt index 266efb5..ed33227 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/module/CloseModule.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/module/CloseModule.kt @@ -5,7 +5,7 @@ import com.github.kr328.clash.common.ids.Intents class CloseModule : Module() { override val receiveBroadcasts: Set - 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() } } diff --git a/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt b/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt index efdc510..8ad547f 100644 --- a/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt +++ b/service/src/main/java/com/github/kr328/clash/service/util/ServiceUtils.kt @@ -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)) } \ No newline at end of file