From e979bec3217cc13cfef6f1efa98b171af75ed323 Mon Sep 17 00:00:00 2001 From: Kr328 <39107975+Kr328@users.noreply.github.com> Date: Fri, 17 Jan 2020 00:17:40 +0800 Subject: [PATCH] [WIP] refactor service --- .../java/com/github/kr328/clash/core/Clash.kt | 2 +- .../github/kr328/clash/core/event/Event.aidl | 6 +- .../github/kr328/clash/core/model/Packet.aidl | 2 +- .../kr328/clash/service/IClashManager.aidl | 24 ++++--- .../kr328/clash/service/ClashManager.kt | 66 +++++++++++++++++++ .../kr328/clash/service/ClashServiceImpl.kt | 2 +- .../kr328/clash/service/ipc/ParcelablePipe.kt | 55 ++++++++++++---- 7 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 service/src/main/java/com/github/kr328/clash/service/ClashManager.kt diff --git a/core/src/main/java/com/github/kr328/clash/core/Clash.kt b/core/src/main/java/com/github/kr328/clash/core/Clash.kt index 586ac7c..b19430e 100644 --- a/core/src/main/java/com/github/kr328/clash/core/Clash.kt +++ b/core/src/main/java/com/github/kr328/clash/core/Clash.kt @@ -122,7 +122,7 @@ class Clash( return Bridge.setSelectedProxy(name, selected) } - fun startUrlTest(name: String): CompletableFuture { + fun startHealthCheck(name: String): CompletableFuture { return DoneCallbackImpl().apply { Bridge.startUrlTest(name, this) } diff --git a/service/src/main/aidl/com/github/kr328/clash/core/event/Event.aidl b/service/src/main/aidl/com/github/kr328/clash/core/event/Event.aidl index dd25fe9..4769fec 100644 --- a/service/src/main/aidl/com/github/kr328/clash/core/event/Event.aidl +++ b/service/src/main/aidl/com/github/kr328/clash/core/event/Event.aidl @@ -1,9 +1,5 @@ package com.github.kr328.clash.core.event; -parcelable ProcessEvent; parcelable LogEvent; parcelable TrafficEvent; -parcelable BandwidthEvent; -parcelable ErrorEvent; -parcelable ProfileChangedEvent; -parcelable ProfileReloadEvent; \ No newline at end of file +parcelable BandwidthEvent; \ No newline at end of file diff --git a/service/src/main/aidl/com/github/kr328/clash/core/model/Packet.aidl b/service/src/main/aidl/com/github/kr328/clash/core/model/Packet.aidl index ba5c225..5477ae3 100644 --- a/service/src/main/aidl/com/github/kr328/clash/core/model/Packet.aidl +++ b/service/src/main/aidl/com/github/kr328/clash/core/model/Packet.aidl @@ -1,4 +1,4 @@ package com.github.kr328.clash.core.model; -parcelable CompressedProxyList; +parcelable ProxyGroup; parcelable General; \ No newline at end of file diff --git a/service/src/main/aidl/com/github/kr328/clash/service/IClashManager.aidl b/service/src/main/aidl/com/github/kr328/clash/service/IClashManager.aidl index 139b70d..ca5b98d 100644 --- a/service/src/main/aidl/com/github/kr328/clash/service/IClashManager.aidl +++ b/service/src/main/aidl/com/github/kr328/clash/service/IClashManager.aidl @@ -1,20 +1,26 @@ package com.github.kr328.clash.service; -import com.github.kr328.clash.service.IClashEventObserver; -import com.github.kr328.clash.service.IClashEventService; -import com.github.kr328.clash.service.IClashProfileService; -import com.github.kr328.clash.service.IClashSettingService; import com.github.kr328.clash.service.ipc.IPCParcelables; -import com.github.kr328.clash.callback.IUrlTestCallback; -import com.github.kr328.clash.core.event.Event; import com.github.kr328.clash.core.model.Packet; interface IClashManager { // Control - ParcelableCompletedFuture setSelectProxy(String proxy, String selected); + boolean setSelectProxy(String proxy, String selected); + ParcelableCompletedFuture startHealthCheck(String group); // Query - CompressedProxyList queryAllProxies(); + ProxyGroup[] queryAllProxies(); General queryGeneral(); - ParcelableCompletedFuture startUrlTest(String group); + + // Profiles + ParcelableCompletedFuture addProfile(String url); + ParcelableCompletedFuture updateProfile(int id); + ParcelableCompletedFuture queryAllProfiles(); + + // Events + ParcelablePipe openBandwidthEvent(); + ParcelablePipe openLogEvent(); + + // Settings + } diff --git a/service/src/main/java/com/github/kr328/clash/service/ClashManager.kt b/service/src/main/java/com/github/kr328/clash/service/ClashManager.kt new file mode 100644 index 0000000..6061070 --- /dev/null +++ b/service/src/main/java/com/github/kr328/clash/service/ClashManager.kt @@ -0,0 +1,66 @@ +package com.github.kr328.clash.service + +import com.github.kr328.clash.core.Clash +import com.github.kr328.clash.core.model.General +import com.github.kr328.clash.core.model.ProxyGroup +import com.github.kr328.clash.service.ipc.ParcelableCompletedFuture +import com.github.kr328.clash.service.ipc.ParcelablePipe + +class ClashManager(val clash: Clash): IClashManager.Stub() { + override fun updateProfile(id: Int): ParcelableCompletedFuture { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun addProfile(url: String?): ParcelableCompletedFuture { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun queryAllProxies(): Array { + return clash.queryProxyGroups().toTypedArray() + } + + override fun queryGeneral(): General { + return clash.queryGeneral() + } + + override fun setSelectProxy(proxy: String?, selected: String?): Boolean { + require(proxy != null && selected != null) + + return clash.setSelectedProxy(proxy, selected) + } + + override fun openBandwidthEvent(): ParcelablePipe { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun queryAllProfiles(): ParcelableCompletedFuture { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun startHealthCheck(group: String?): ParcelableCompletedFuture { + require(group != null) + + return ParcelableCompletedFuture().apply { + clash.startHealthCheck(group).whenComplete { _: Unit?, u: Throwable? -> + if ( u != null ) + this.completeExceptionally(u) + else + this.complete(null) + } + } + } + + override fun openLogEvent(): ParcelablePipe { + return object: ParcelablePipe() { + val stream = clash.openLogEvent().apply { + onEvent { + send(it) + } + } + + override fun onClose() { + stream.close() + } + } + } +} \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/ClashServiceImpl.kt b/service/src/main/java/com/github/kr328/clash/service/ClashServiceImpl.kt index 8697572..b085a17 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ClashServiceImpl.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ClashServiceImpl.kt @@ -65,7 +65,7 @@ class ClashServiceImpl(clashService: ClashService) : IClashService.Stub() { val count = AtomicInteger(proxies.size) proxies.forEach { - clash.startUrlTest(it) + clash.startHealthCheck(it) } } diff --git a/service/src/main/java/com/github/kr328/clash/service/ipc/ParcelablePipe.kt b/service/src/main/java/com/github/kr328/clash/service/ipc/ParcelablePipe.kt index e175ebe..f0275c3 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ipc/ParcelablePipe.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ipc/ParcelablePipe.kt @@ -5,30 +5,40 @@ import android.os.IBinder import android.os.Parcel import android.os.Parcelable -class ParcelablePipe() : Parcelable { - private inner class Slave: Binder() { +open class ParcelablePipe private constructor(val type: Type) : Parcelable { + enum class Type { + MASTER, SLAVE + } + + private inner class Slave : Binder() { override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean { - if ( code == TRANSACT_CODE_SEND_PARCELABLE ) { + if (code == TRANSACT_CODE_SEND_PARCELABLE) { receiveCallback(data.readParcelable(ParcelablePipe::class.java.classLoader)) return true } return false } } - private inner class Master: Binder() { + + private inner class Master : Binder() { override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean { - if ( code == TRANSACT_CODE_SET_SLAVE ) { - slave = data.readStrongBinder() + if (code == TRANSACT_CODE_SET_SLAVE) { + connection = data.readStrongBinder() return true } + if (code == TRANSACT_CODE_CLOSE) { + onClose() + } return false } } - private var slave: IBinder? = null + private var connection: IBinder? = null private var receiveCallback: (Parcelable?) -> Unit = {} - constructor(parcel: Parcel) : this() { + constructor() : this(Type.MASTER) + + constructor(parcel: Parcel) : this(Type.SLAVE) { val master = parcel.readStrongBinder() val data = Parcel.obtain() @@ -36,14 +46,15 @@ class ParcelablePipe() : Parcelable { data.writeStrongBinder(Slave()) master.transact(TRANSACT_CODE_SET_SLAVE, data, null, 0) - } - finally { + + connection = master + } finally { data.recycle() } } override fun writeToParcel(dest: Parcel?, flags: Int) { - if ( dest == null ) + if (dest == null) return dest.writeStrongBinder(Master()) @@ -52,28 +63,44 @@ class ParcelablePipe() : Parcelable { override fun describeContents(): Int = 0 fun send(parcelable: Parcelable?): Boolean { - val s = slave ?: return false + if (type != Type.MASTER) + return false + + val s = connection ?: return false val data = Parcel.obtain() try { data.writeParcelable(parcelable, 0) s.transact(TRANSACT_CODE_SEND_PARCELABLE, data, null, 0) - } - finally { + } finally { data.recycle() } return true } + fun close() { + val s = connection ?: return + val data = Parcel.obtain() + + try { + s.transact(TRANSACT_CODE_CLOSE, data, null, 0) + } finally { + data.recycle() + } + } + fun onReceive(callback: (Parcelable?) -> Unit) { this.receiveCallback = callback } + open fun onClose() {} + companion object { private const val TRANSACT_CODE_SET_SLAVE = 1 private const val TRANSACT_CODE_SEND_PARCELABLE = 2 + private const val TRANSACT_CODE_CLOSE = 3 @JvmField val CREATOR = object : Parcelable.Creator {