Improve: merge ClashManager and ProfileService

This commit is contained in:
kr328
2021-05-25 20:28:40 +08:00
parent c48ce82640
commit a8f502ef4f
12 changed files with 161 additions and 148 deletions

View File

@@ -24,8 +24,6 @@ class AppCrashedActivity : BaseActivity<AppCrashedDesign>() {
SystemLogcat.dumpCrash()
}
Tracker.uploadLogcat(logs)
design.setAppLogs(logs)
while (isActive) {

View File

@@ -20,9 +20,9 @@ import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.core.model.LogMessage
import com.github.kr328.clash.log.LogcatCache
import com.github.kr328.clash.log.LogcatWriter
import com.github.kr328.clash.service.ClashManager
import com.github.kr328.clash.service.remote.IClashManager
import com.github.kr328.clash.service.RemoteService
import com.github.kr328.clash.service.remote.ILogObserver
import com.github.kr328.clash.service.remote.IRemoteService
import com.github.kr328.clash.service.remote.unwrap
import com.github.kr328.clash.util.logsDir
import kotlinx.coroutines.*
@@ -52,7 +52,7 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
showNotification()
bindService(ClashManager::class.intent, connection, Context.BIND_AUTO_CREATE)
bindService(RemoteService::class.intent, connection, Context.BIND_AUTO_CREATE)
}
override fun onDestroy() {
@@ -88,7 +88,7 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
return stopSelf()
launch(Dispatchers.IO) {
val service = binder.unwrap(IClashManager::class)
val service = binder.unwrap(IRemoteService::class).clash()
val channel = Channel<LogMessage>(CACHE_CAPACITY)
try {

View File

@@ -8,7 +8,8 @@ object SystemLogcat {
"Go",
"DEBUG",
"AndroidRuntime",
"ClashForAndroid"
"ClashForAndroid",
"LwIP",
)
fun dumpCrash(): String {

View File

@@ -15,7 +15,7 @@ import kotlinx.coroutines.launch
object Remote {
val broadcasts: Broadcasts = Broadcasts(Global.application)
val services: Services = Services(Global.application) {
val service: Service = Service(Global.application) {
ApplicationObserver.createdActivities.forEach { it.finish() }
val intent = AppCrashedActivity::class.intent
@@ -56,10 +56,10 @@ object Remote {
while (true) {
if (visible.receive()) {
services.bind()
service.bind()
broadcasts.register()
} else {
services.unbind()
service.unbind()
broadcasts.unregister()
}
}

View File

@@ -0,0 +1,64 @@
package com.github.kr328.clash.remote
import android.app.Application
import android.content.ComponentName
import android.content.Context
import android.content.ServiceConnection
import android.os.IBinder
import com.github.kr328.clash.Tracker
import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.log.SystemLogcat
import com.github.kr328.clash.service.RemoteService
import com.github.kr328.clash.service.remote.IRemoteService
import com.github.kr328.clash.service.remote.unwrap
import com.github.kr328.clash.util.unbindServiceSilent
import java.util.concurrent.TimeUnit
class Service(private val context: Application, val crashed: () -> Unit) {
val remote = Resource<IRemoteService>()
private val connection = object : ServiceConnection {
private var lastCrashed: Long = -1
override fun onServiceConnected(name: ComponentName?, service: IBinder) {
remote.set(service.unwrap(IRemoteService::class))
}
override fun onServiceDisconnected(name: ComponentName?) {
remote.set(null)
Tracker.uploadLogcat(SystemLogcat.dumpCrash())
if (System.currentTimeMillis() - lastCrashed < TOGGLE_CRASHED_INTERVAL) {
unbind()
crashed()
}
lastCrashed = System.currentTimeMillis()
Log.w("RemoteManager crashed")
}
}
fun bind() {
try {
context.bindService(RemoteService::class.intent, connection, Context.BIND_AUTO_CREATE)
} catch (e: Exception) {
unbind()
crashed()
}
}
fun unbind() {
context.unbindServiceSilent(connection)
remote.set(null)
}
companion object {
private val TOGGLE_CRASHED_INTERVAL = TimeUnit.SECONDS.toMillis(10)
}
}

View File

@@ -1,88 +0,0 @@
package com.github.kr328.clash.remote
import android.app.Application
import android.content.ComponentName
import android.content.Context
import android.content.ServiceConnection
import android.os.IBinder
import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.service.ClashManager
import com.github.kr328.clash.service.ProfileService
import com.github.kr328.clash.service.remote.IClashManager
import com.github.kr328.clash.service.remote.IProfileManager
import com.github.kr328.clash.service.remote.unwrap
import com.github.kr328.clash.util.unbindServiceSilent
import java.util.concurrent.TimeUnit
class Services(private val context: Application, val crashed: () -> Unit) {
val clash = Resource<IClashManager>()
val profile = Resource<IProfileManager>()
private val clashConnection = object : ServiceConnection {
private var lastCrashed: Long = -1
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
clash.set(service?.unwrap(IClashManager::class))
}
override fun onServiceDisconnected(name: ComponentName?) {
clash.set(null)
if (System.currentTimeMillis() - lastCrashed < TOGGLE_CRASHED_INTERVAL) {
unbind()
crashed()
}
lastCrashed = System.currentTimeMillis()
Log.w("ClashManager crashed")
}
}
private val profileConnection = object : ServiceConnection {
private var lastCrashed: Long = -1
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
profile.set(service?.unwrap(IProfileManager::class))
}
override fun onServiceDisconnected(name: ComponentName?) {
profile.set(null)
if (System.currentTimeMillis() - lastCrashed < TOGGLE_CRASHED_INTERVAL) {
unbind()
crashed()
}
lastCrashed = System.currentTimeMillis()
Log.w("ProfileService crashed")
}
}
fun bind() {
try {
context.bindService(ClashManager::class.intent, clashConnection, Context.BIND_AUTO_CREATE)
context.bindService(ProfileService::class.intent, profileConnection, Context.BIND_AUTO_CREATE)
} catch (e: Exception) {
unbind()
crashed()
}
}
fun unbind() {
context.unbindServiceSilent(clashConnection)
context.unbindServiceSilent(profileConnection)
clash.set(null)
profile.set(null)
}
companion object {
private val TOGGLE_CRASHED_INTERVAL = TimeUnit.SECONDS.toMillis(10)
}
}

View File

@@ -14,14 +14,15 @@ suspend fun <T> withClash(
block: suspend IClashManager.() -> T
): T {
while (true) {
val client = Remote.services.clash.get()
val remote = Remote.service.remote.get()
val client = remote.clash()
try {
return withContext(context) { client.block() }
} catch (e: DeadObjectException) {
Log.w("Remote services panic")
Remote.services.clash.reset(client)
Remote.service.remote.reset(remote)
}
}
}
@@ -31,14 +32,15 @@ suspend fun <T> withProfile(
block: suspend IProfileManager.() -> T
): T {
while (true) {
val client = Remote.services.profile.get()
val remote = Remote.service.remote.get()
val client = remote.profile()
try {
return withContext(context) { client.block() }
} catch (e: DeadObjectException) {
Log.w("Remote services panic")
Remote.services.profile.reset(client)
Remote.service.remote.reset(remote)
}
}
}