From a44bb05345ec7bb6327dbd753975f4e8a4e54462 Mon Sep 17 00:00:00 2001 From: Kr328 <39107975+Kr328@users.noreply.github.com> Date: Tue, 14 Jan 2020 15:45:57 +0800 Subject: [PATCH] [WIP] refactor services --- core/src/main/golang/bridge/callback.go | 5 ++ core/src/main/golang/bridge/profiles.go | 63 ++++++++++++++++-- core/src/main/golang/bridge/proxies.go | 6 +- core/src/main/golang/profile/download.go | 37 ++++++++++- .../java/com/github/kr328/clash/core/Clash.kt | 40 +++++------ .../kr328/clash/core/model/Compression.kt | 66 ------------------- .../clash/core/transact/DoneCallbackImpl.kt | 18 +++++ 7 files changed, 136 insertions(+), 99 deletions(-) delete mode 100644 core/src/main/java/com/github/kr328/clash/core/model/Compression.kt create mode 100644 core/src/main/java/com/github/kr328/clash/core/transact/DoneCallbackImpl.kt diff --git a/core/src/main/golang/bridge/callback.go b/core/src/main/golang/bridge/callback.go index ac94c40..457e114 100644 --- a/core/src/main/golang/bridge/callback.go +++ b/core/src/main/golang/bridge/callback.go @@ -1 +1,6 @@ package bridge + +type DoneCallback interface { + Done() + DoneWithError(error) +} diff --git a/core/src/main/golang/bridge/profiles.go b/core/src/main/golang/bridge/profiles.go index f10d66c..e5c98b4 100644 --- a/core/src/main/golang/bridge/profiles.go +++ b/core/src/main/golang/bridge/profiles.go @@ -1,15 +1,64 @@ package bridge -import "github.com/kr328/cfa/profile" +import ( + "github.com/kr328/cfa/profile" + "sync" +) -func LoadProfileFile(path, baseDir string) error { - return profile.LoadFromFile(path, baseDir) +var mutex sync.Mutex + +func LoadProfileFile(path, baseDir string, callback DoneCallback) { + go func() { + mutex.Lock() + defer mutex.Unlock() + + err := profile.LoadFromFile(path, baseDir) + if err != nil { + callback.DoneWithError(err) + } else { + callback.Done() + } + }() } -func DownloadProfileAndCheck(url, output string) error { - return profile.DownloadAndCheck(url, output) +func DownloadProfileAndCheck(url, output, baseDir string, callback DoneCallback) { + go func() { + mutex.Lock() + defer mutex.Unlock() + + err := profile.DownloadAndCheck(url, output, baseDir) + if err != nil { + callback.DoneWithError(err) + } else { + callback.Done() + } + }() } -func SaveProfileAndCheck(data []byte, output string) error { - return profile.SaveAndCheck(data, output) +func SaveProfileAndCheck(data []byte, output, baseDir string, callback DoneCallback) { + go func() { + mutex.Lock() + defer mutex.Unlock() + + err := profile.SaveAndCheck(data, output, baseDir) + if err != nil { + callback.DoneWithError(err) + } else { + callback.Done() + } + }() +} + +func MoveProfileAndCheck(source, target, baseDir string, callback DoneCallback) { + go func() { + mutex.Lock() + defer mutex.Unlock() + + err := profile.MoveAndCheck(source, target, baseDir) + if err != nil { + callback.DoneWithError(err) + } else { + callback.Done() + } + }() } diff --git a/core/src/main/golang/bridge/proxies.go b/core/src/main/golang/bridge/proxies.go index 71ca774..118c31c 100644 --- a/core/src/main/golang/bridge/proxies.go +++ b/core/src/main/golang/bridge/proxies.go @@ -33,10 +33,6 @@ type ProxyCollection interface { Add(proxy *ProxyItem) bool } -type UrlTestCallback interface { - Done() -} - func (p *ProxyGroupItem) QueryAllProxies(collection ProxyCollection) { for _, v := range p.providers { for _, p := range v.Proxies() { @@ -51,7 +47,7 @@ func (p *ProxyGroupItem) QueryAllProxies(collection ProxyCollection) { } } -func StartUrlTest(group string, callback UrlTestCallback) { +func StartUrlTest(group string, callback DoneCallback) { go func() { defer callback.Done() diff --git a/core/src/main/golang/profile/download.go b/core/src/main/golang/profile/download.go index 167624f..e5e1c21 100644 --- a/core/src/main/golang/profile/download.go +++ b/core/src/main/golang/profile/download.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net" "net/http" + "os" "github.com/Dreamacro/clash/adapters/inbound" "github.com/Dreamacro/clash/component/socks5" @@ -43,7 +44,11 @@ var client = &http.Client{ }, } -func DownloadAndCheck(url, output string) error { +func DownloadAndCheck(url, output, baseDir string) error { + original := constant.Path.HomeDir() + constant.SetHomeDir(baseDir) + defer constant.SetHomeDir(original) + response, err := client.Get(url) if err != nil { return err @@ -63,7 +68,11 @@ func DownloadAndCheck(url, output string) error { return ioutil.WriteFile(output, data, defaultFileMode) } -func SaveAndCheck(data []byte, output string) error { +func SaveAndCheck(data []byte, output, baseDir string) error { + original := constant.Path.HomeDir() + constant.SetHomeDir(baseDir) + defer constant.SetHomeDir(original) + _, err := config.Parse(data) if err != nil { return err @@ -71,3 +80,27 @@ func SaveAndCheck(data []byte, output string) error { return ioutil.WriteFile(output, data, defaultFileMode) } + +func MoveAndCheck(source, target, baseDir string) error { + original := constant.Path.HomeDir() + constant.SetHomeDir(baseDir) + defer constant.SetHomeDir(original) + + buf, err := ioutil.ReadFile(source) + if err != nil { + return err + } + + _, err = config.Parse(buf) + if err != nil { + return err + } + + if err := ioutil.WriteFile(target, buf, defaultFileMode); err != nil { + return err + } + + os.Remove(source) + + return nil +} 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 a345eb1..cfc7fe1 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 @@ -10,6 +10,7 @@ import com.github.kr328.clash.core.event.TrafficEvent import com.github.kr328.clash.core.model.General import com.github.kr328.clash.core.model.Proxy import com.github.kr328.clash.core.model.ProxyGroup +import com.github.kr328.clash.core.transact.DoneCallbackImpl import com.github.kr328.clash.core.transact.ProxyCollectionImpl import com.github.kr328.clash.core.transact.ProxyGroupCollectionImpl import java.io.InputStream @@ -20,13 +21,6 @@ class Clash( context: Context, private val listener: (ProcessEvent) -> Unit ) { - companion object { - const val CLASH_DIR = "clash" - - const val DEFAULT_URL_TEST_TIMEOUT = 5000 - const val DEFAULT_URL_TEST_URL = "https://www.gstatic.com/generate_204" - } - class Poll(private val poll: EventPoll) { fun stop() { poll.stop() @@ -82,18 +76,30 @@ class Clash( Bridge.stopTunDevice() } - fun loadProfile(path: String, baseDir: String) { + fun loadProfile(path: String, baseDir: String): CompletableFuture { enforceStarted() - Bridge.loadProfileFile(path, baseDir) + return DoneCallbackImpl().apply { + Bridge.loadProfileFile(path, baseDir, this) + } } - fun downloadProfile(url: String, output: String) { - Bridge.downloadProfileAndCheck(url, output) + fun downloadProfile(url: String, output: String, baseDir: String): CompletableFuture { + return DoneCallbackImpl().apply { + Bridge.downloadProfileAndCheck(url, output, baseDir,this) + } } - fun saveProfile(data: ByteArray, output: String) { - Bridge.saveProfileAndCheck(data, output) + fun saveProfile(data: ByteArray, output: String, baseDir: String): CompletableFuture { + return DoneCallbackImpl().apply { + Bridge.saveProfileAndCheck(data, output, baseDir, this) + } + } + + fun moveProfile(source: String, target: String, baseDir: String): CompletableFuture { + return DoneCallbackImpl().apply { + Bridge.moveProfileAndCheck(source, target, baseDir, this) + } } fun queryProxyGroups(): List { @@ -119,13 +125,9 @@ class Clash( } fun startUrlTest(name: String): CompletableFuture { - val future = CompletableFuture() - - Bridge.startUrlTest(name) { - future.complete(Unit) + return DoneCallbackImpl().apply { + Bridge.startUrlTest(name, this) } - - return future } fun queryGeneral(): General { diff --git a/core/src/main/java/com/github/kr328/clash/core/model/Compression.kt b/core/src/main/java/com/github/kr328/clash/core/model/Compression.kt deleted file mode 100644 index dd266fe..0000000 --- a/core/src/main/java/com/github/kr328/clash/core/model/Compression.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.github.kr328.clash.core.model - -import android.os.Parcel -import android.os.Parcelable -import com.github.kr328.clash.core.serialization.Parcels -import com.github.kr328.clash.core.utils.Log -import kotlinx.serialization.Serializable -import java.lang.IllegalStateException - -fun List.compress(): CompressedProxyList { - val nameMap = this.toList().mapIndexed { index, proxy -> - proxy.name to index - }.toMap() - - val elements = this.map { - CompressedProxyList.Element( - name = nameMap[it.name] ?: throw IllegalStateException("Unknown proxy ${it.name}"), - type = it.type, - now = nameMap[it.now] ?: -1, - all = it.all.mapNotNull { name -> nameMap[name] }, - delay = it.delay - ) - } - - return CompressedProxyList(nameMap.entries.associate { (k, v) -> v to k }, elements) -} - -@Serializable -data class CompressedProxyList(val proxyName: Map, val elements: List): Parcelable { - @Serializable - data class Element(val name: Int, - val type: Proxy.Type, - val now: Int, - val all: List, - val delay: Long) - - fun uncompress(): List { - return elements.map { - Proxy( - name = proxyName[it.name] ?: throw IllegalStateException("Unknown proxy $it"), - type = it.type, - now = proxyName[it.now] ?: "", - all = it.all.mapNotNull { index -> proxyName[index] }, - delay = it.delay - ) - } - } - - override fun writeToParcel(parcel: Parcel, flags: Int) { - Parcels.dump(serializer(), this, parcel) - } - - override fun describeContents(): Int { - return 0 - } - - companion object CREATOR : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): CompressedProxyList { - return Parcels.load(serializer(), parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } -} \ No newline at end of file diff --git a/core/src/main/java/com/github/kr328/clash/core/transact/DoneCallbackImpl.kt b/core/src/main/java/com/github/kr328/clash/core/transact/DoneCallbackImpl.kt new file mode 100644 index 0000000..0f3a77c --- /dev/null +++ b/core/src/main/java/com/github/kr328/clash/core/transact/DoneCallbackImpl.kt @@ -0,0 +1,18 @@ +package com.github.kr328.clash.core.transact + +import bridge.DoneCallback +import java.lang.Exception +import java.util.concurrent.CompletableFuture + +class DoneCallbackImpl : DoneCallback, CompletableFuture() { + override fun doneWithError(e: Exception?) { + if ( e == null ) + complete(Unit) + else + completeExceptionally(e) + } + + override fun done() { + complete(Unit) + } +} \ No newline at end of file