diff --git a/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt b/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt index d55c43d..34f0aca 100644 --- a/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/CreateProfileActivity.kt @@ -26,6 +26,8 @@ class CreateProfileActivity : BaseActivity() { const val REQUEST_CODE = 20000 } + private val self = this + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -43,7 +45,7 @@ class CreateProfileActivity : BaseActivity() { mainList.setOnItemClickListener { _, _, position, _ -> val item = providers[position] - launch { + self.launch { val id = withProfile { acquireUnused(item.type) } diff --git a/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt b/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt index dfc7557..df8e0e0 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfileEditActivity.kt @@ -1,5 +1,6 @@ package com.github.kr328.clash +import android.app.Activity import android.os.Bundle import android.view.View import androidx.appcompat.app.AlertDialog @@ -107,6 +108,10 @@ class ProfileEditActivity : BaseActivity() { updateMetadata(metadata.id, metadata) commitAsync(metadata.id).await() } + + setResult(Activity.RESULT_OK) + + finish() } catch (e: Exception) { showSnackbarException(getString(R.string.download_failure), e.message) } 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 3905f75..25f7d5e 100644 --- a/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt +++ b/app/src/main/java/com/github/kr328/clash/ProfilesActivity.kt @@ -9,6 +9,7 @@ import com.github.kr328.clash.common.ids.Intents 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.common.utils.Log import com.github.kr328.clash.remote.withProfile import com.github.kr328.clash.service.ProfileBackgroundService import com.github.kr328.clash.service.ProfileProvider @@ -171,9 +172,7 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C override fun onDuplicate(entity: ProfileMetadata) { launch { withProfile { - val newId = acquireCloned(entity.id) - - openProperties(newId) + openProperties(acquireCloned(entity.id)) } } } diff --git a/app/src/main/java/com/github/kr328/clash/TileService.kt b/app/src/main/java/com/github/kr328/clash/TileService.kt index ad032cc..a94103e 100644 --- a/app/src/main/java/com/github/kr328/clash/TileService.kt +++ b/app/src/main/java/com/github/kr328/clash/TileService.kt @@ -86,7 +86,7 @@ class TileService : TileService() { addAction(Intents.INTENT_ACTION_CLASH_STOPPED) addAction(Intents.INTENT_ACTION_PROFILE_LOADED) }, - Permissions.PERMISSION_ACCESS_CLASH, + Permissions.PERMISSION_RECEIVE_BROADCASTS, null ) diff --git a/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt b/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt index 2b9712f..0857d39 100644 --- a/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt +++ b/app/src/main/java/com/github/kr328/clash/fragment/ProfileEditFragment.kt @@ -91,7 +91,7 @@ class ProfileEditFragment( icon = requireContext().getDrawable(R.drawable.ic_update), hint = getString(R.string.more_than_15_minutes), id = KEY_AUTO_UPDATE, - content = (interval / 1000 / 60).toString() + content = (interval / 1000 / 60).toStringIfNonZero() ) { onDisplayContent { val interval = it.toString().toIntOrNull() ?: 0 @@ -119,6 +119,9 @@ class ProfileEditFragment( interval = content.toString().toLong() * 1000 * 60 } + + if ( type == Type.FILE ) + isHidden = true } screen.restoreState(savedInstanceState) @@ -177,4 +180,8 @@ class ProfileEditFragment( return true } + + private fun Long.toStringIfNonZero(): String { + return if ( this == 0L ) "" else this.toString() + } } \ No newline at end of file diff --git a/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt b/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt index 4746957..18df48c 100644 --- a/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt +++ b/app/src/main/java/com/github/kr328/clash/remote/Broadcasts.kt @@ -71,7 +71,7 @@ object Broadcasts { addAction(Intents.INTENT_ACTION_CLASH_STOPPED) addAction(Intents.INTENT_ACTION_CLASH_STARTED) addAction(Intents.INTENT_ACTION_PROFILE_LOADED) - }, Permissions.PERMISSION_ACCESS_CLASH, null) + }, Permissions.PERMISSION_RECEIVE_BROADCASTS, null) val current = RemoteUtils.detectClashRunning(application) if (current != clashRunning) { diff --git a/app/src/main/java/com/github/kr328/clash/remote/ProfileClient.kt b/app/src/main/java/com/github/kr328/clash/remote/ProfileClient.kt index b7c2944..cb10af6 100644 --- a/app/src/main/java/com/github/kr328/clash/remote/ProfileClient.kt +++ b/app/src/main/java/com/github/kr328/clash/remote/ProfileClient.kt @@ -62,7 +62,6 @@ class ProfileClient(private val service: IProfileService) { service.queryById(id) } - suspend fun setActive(id: Long) = withContext(Dispatchers.IO) { service.setActive(id) } diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 727998b..d79765a 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -8,7 +8,7 @@ 自动追加系统 DNS 到 Clash 应用损坏 Clash for Android - 自动更新 (秒) + 自动更新 (分钟) 行为 启动 绕过私有网络 @@ -96,7 +96,7 @@ 代理排序 在系统启动时启动 Clash 开机时启动 - 打开 URL 提供商 失败 + 打开 URL 提供程序失败 已停止 支持 点此启动 @@ -128,6 +128,6 @@ 配置文件丢失 大于15分钟 载入中 - 免费开源的项目, 不提供任何代理服务
请务必不要反馈非应用自身引起的问题]]>
+ 免费开源的项目
我们不提供任何代理服务
请务必不要反馈非应用自身引起的问题]]>
捐赠 \ No newline at end of file diff --git a/common/src/main/AndroidManifest.xml b/common/src/main/AndroidManifest.xml index 5b4eb94..3a0f4f4 100644 --- a/common/src/main/AndroidManifest.xml +++ b/common/src/main/AndroidManifest.xml @@ -5,4 +5,5 @@ android:label="@string/receive_clash_broadcasts" android:description="@string/receive_broadcasts_of_clash" android:protectionLevel="privileged|signature" /> + diff --git a/common/src/main/java/com/github/kr328/clash/common/Permissions.kt b/common/src/main/java/com/github/kr328/clash/common/Permissions.kt index ed5a968..6bb39a1 100644 --- a/common/src/main/java/com/github/kr328/clash/common/Permissions.kt +++ b/common/src/main/java/com/github/kr328/clash/common/Permissions.kt @@ -1,6 +1,6 @@ package com.github.kr328.clash.common object Permissions { - val PERMISSION_ACCESS_CLASH: String + val PERMISSION_RECEIVE_BROADCASTS: String get() = Global.application.packageName + ".permission.RECEIVE_BROADCASTS" } \ No newline at end of file diff --git a/core/src/main/golang/bridge/init.go b/core/src/main/golang/bridge/init.go index c94cf79..4895af7 100644 --- a/core/src/main/golang/bridge/init.go +++ b/core/src/main/golang/bridge/init.go @@ -25,6 +25,10 @@ func InitCore(geoipDatabase[] byte, homeDir string, version string) { mmdb.LoadFromBytes(dataClone) C.SetHomeDir(homeDir) config.ApplicationVersion = version + + Reset() + + log.Infoln("Initialed") } func Reset() { diff --git a/core/src/main/golang/config/load.go b/core/src/main/golang/config/load.go index aa6785c..f71612a 100644 --- a/core/src/main/golang/config/load.go +++ b/core/src/main/golang/config/load.go @@ -5,36 +5,17 @@ import ( "io/ioutil" "github.com/Dreamacro/clash/config" - "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/hub/executor" "github.com/Dreamacro/clash/log" "github.com/kr328/cfa/tun" ) -const defaultConfig = ` -log: debug -mode: Direct -Proxy: -- name: "broadcast" - type: socks5 - server: 255.255.255.255 - port: 1080 - -Proxy Group: -- name: "select" - type: select - proxies: [DIRECT] - -Rule: -- 'MATCH,DIRECT' -` - // LoadDefault - load default configure func LoadDefault() { DnsPatch = nil NameServersAppend = make([]string, 0) - defaultC, err := parseConfig([]byte(defaultConfig), constant.Path.HomeDir()) + defaultC, err := config.Parse([]byte{}) if err != nil { log.Warnln("Load Default Failure " + err.Error()) return 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 980e452..dfa8877 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 @@ -18,7 +18,7 @@ import java.io.InputStream object Clash { private val logReceivers = mutableMapOf Unit>() - fun init() { + init { val context = Global.application val bytes = context.assets.open("Country.mmdb") diff --git a/design/src/main/java/com/github/kr328/clash/design/common/Base.kt b/design/src/main/java/com/github/kr328/clash/design/common/Base.kt index 124642a..bac13fa 100644 --- a/design/src/main/java/com/github/kr328/clash/design/common/Base.kt +++ b/design/src/main/java/com/github/kr328/clash/design/common/Base.kt @@ -22,6 +22,9 @@ abstract class Base(val screen: CommonUiScreen) { get() = field || (dependOn?.isHidden ?: false) set(value) { field = value + + reapplyAttribute() + screen.postReapplyAttribute() } diff --git a/design/src/main/java/com/github/kr328/clash/design/common/CommonUiBuilder.kt b/design/src/main/java/com/github/kr328/clash/design/common/CommonUiBuilder.kt index b55e2e8..0b2149f 100644 --- a/design/src/main/java/com/github/kr328/clash/design/common/CommonUiBuilder.kt +++ b/design/src/main/java/com/github/kr328/clash/design/common/CommonUiBuilder.kt @@ -25,9 +25,9 @@ class CommonUiBuilder(val screen: CommonUiScreen) { textInput.id = id textInput.dependOn = dependOn?.run { screen.requireElement(this) } - setup(textInput) - screen.addElement(textInput) + + textInput.setup() } fun option( 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 21ebc1f..4e1fd33 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 @@ -91,6 +91,8 @@ class ProfileBackgroundService : BaseService() { requests.onReceive { ProfileReceiver.cancelNextUpdate(self, it) + queue.add(it) + service.commit(it, object : IStreamCallback.Stub() { override fun completeExceptionally(reason: String?) { responses.offer(it to RemoteException(reason)) @@ -106,6 +108,8 @@ class ProfileBackgroundService : BaseService() { false } responses.onReceive { + queue.remove(it.first) + if (it.second == null) sendUpdateCompleted(it.first) else 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 245f41f..f13fc8a 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 @@ -21,6 +21,9 @@ object ProfileProcessor { withContext(Dispatchers.IO) { metadata.enforceFieldValid() + context.resolveBaseDir(metadata.id).mkdirs() + context.resolveProfileFile(metadata.id).parentFile?.mkdirs() + downloadProfile( context, metadata.uri, context.resolveProfileFile(metadata.id), 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 79d96f6..76121c0 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 @@ -4,6 +4,7 @@ import android.content.Intent import android.net.Uri import android.os.IBinder import android.os.RemoteException +import com.github.kr328.clash.common.utils.Log import com.github.kr328.clash.service.data.ProfileDao import com.github.kr328.clash.service.ipc.IStreamCallback import com.github.kr328.clash.service.model.ProfileMetadata @@ -82,7 +83,8 @@ class ProfileService : BaseService() { return runBlocking { val clonedId = generateNextId() - pending[clonedId] = queryMetadataById(id) ?: return@runBlocking -1L + pending[clonedId] = queryMetadataById(id)?.copy(id = clonedId, active = false) + ?: return@runBlocking -1L clonedId } @@ -117,6 +119,8 @@ class ProfileService : BaseService() { it.deleteRecursively() } } + + service.broadcastProfileChanged() } } @@ -147,6 +151,8 @@ class ProfileService : BaseService() { override fun onCreate() { super.onCreate() + ProfileReceiver.tryInitialize(this) + launch { process() } @@ -173,6 +179,8 @@ class ProfileService : BaseService() { ProfileProcessor.createOrUpdate(service, metadata) ctx.value?.complete() + + service.broadcastProfileChanged() } catch (e: Exception) { ctx.value?.completeExceptionally(e.message) } diff --git a/service/src/main/java/com/github/kr328/clash/service/clash/ClashRuntime.kt b/service/src/main/java/com/github/kr328/clash/service/clash/ClashRuntime.kt index 2d978db..76bf5e4 100644 --- a/service/src/main/java/com/github/kr328/clash/service/clash/ClashRuntime.kt +++ b/service/src/main/java/com/github/kr328/clash/service/clash/ClashRuntime.kt @@ -66,7 +66,7 @@ class ClashRuntime(private val context: Context) { modules.flatMap { it.receiveBroadcasts }.distinct().forEach { addAction(it) } - }, Permissions.PERMISSION_ACCESS_CLASH, null) + }, Permissions.PERMISSION_RECEIVE_BROADCASTS, null) while (isActive) { tickerEnabled = modules.any { it.enableTicker } diff --git a/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt b/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt index 9fb06f2..b71cb45 100644 --- a/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt +++ b/service/src/main/java/com/github/kr328/clash/service/files/ProfilesResolver.kt @@ -3,6 +3,7 @@ package com.github.kr328.clash.service.files import android.content.Context import android.os.ParcelFileDescriptor import android.provider.DocumentsContract +import com.github.kr328.clash.common.utils.Log import com.github.kr328.clash.service.R import com.github.kr328.clash.service.data.ProfileDao import com.github.kr328.clash.service.util.resolveProfileFile diff --git a/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt b/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt index 3e343c3..d27cf71 100644 --- a/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt +++ b/service/src/main/java/com/github/kr328/clash/service/model/Converters.kt @@ -19,7 +19,7 @@ fun ProfileEntity.toProfileMetadata(context: Context): ProfileMetadata { name = name, type = type, uri = Uri.parse(uri), - source = Uri.parse(source), + source = source?.let { Uri.parse(it)}, active = active, interval = interval, lastModified = lastModified @@ -38,7 +38,7 @@ fun ProfileMetadata.toProfileEntity(): ProfileEntity { name = name, type = type, uri = uri.toString(), - source = source.toString(), + source = source?.toString(), active = active, interval = interval, id = id diff --git a/service/src/main/java/com/github/kr328/clash/service/transact/ProfileRequest.kt b/service/src/main/java/com/github/kr328/clash/service/transact/ProfileRequest.kt deleted file mode 100644 index ea07aa4..0000000 --- a/service/src/main/java/com/github/kr328/clash/service/transact/ProfileRequest.kt +++ /dev/null @@ -1,114 +0,0 @@ -package com.github.kr328.clash.service.transact - -import android.net.Uri -import android.os.Bundle -import android.os.Parcel -import android.os.Parcelable -import com.github.kr328.clash.service.ipc.IStreamCallback - -class ProfileRequest private constructor(private val bundle: Bundle) : Parcelable { - constructor() : this(Bundle()) - constructor(parcel: Parcel) : this( - parcel.readBundle(ProfileRequest::class.java.classLoader) - ?: throw NullPointerException("Empty bundle") - ) - - enum class Action { - UPDATE_OR_CREATE, REMOVE, CLEAR - } - - val action: Action - get() = Action.valueOf(requireNotNull(bundle.getString(KEY_ACTION))) - val type: Int - get() = bundle.getInt(KEY_TYPE, -1) - val id: Long - get() = bundle.getLong(KEY_ID, -1) - val name: String? - get() = bundle.getString(KEY_NAME) - val url: Uri? - get() = bundle.getParcelable(KEY_URL) - val source: Uri? - get() = bundle.getParcelable(KEY_SOURCE) - val interval: Long - get() = bundle.getLong(KEY_UPDATE_INTERVAL, -1) - val callback: IStreamCallback? - get() = IStreamCallback.Stub.asInterface(bundle.getBinder(KEY_CALLBACK)) - - fun action(action: Action): ProfileRequest { - return apply { - bundle.putString(KEY_ACTION, action.toString()) - } - } - - fun withType(type: Int): ProfileRequest { - return apply { - bundle.putInt(KEY_TYPE, type) - } - } - - fun withId(id: Long): ProfileRequest { - return apply { - bundle.putLong(KEY_ID, id) - } - } - - fun withName(name: String): ProfileRequest { - return apply { - bundle.putString(KEY_NAME, name) - } - } - - fun withURL(url: Uri): ProfileRequest { - return apply { - bundle.putParcelable(KEY_URL, url) - } - } - - fun withSource(source: Uri?): ProfileRequest { - return apply { - bundle.putParcelable(KEY_SOURCE, source) - } - } - - fun withUpdateInterval(interval: Long): ProfileRequest { - return apply { - bundle.putLong(KEY_UPDATE_INTERVAL, interval) - } - } - - fun withCallback(callback: IStreamCallback.Stub): ProfileRequest { - return apply { - bundle.putBinder(KEY_CALLBACK, callback) - } - } - - override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeBundle(bundle) - } - - override fun describeContents(): Int { - return 0 - } - - companion object { - private const val KEY_ACTION = "action" - private const val KEY_ID = "id" - private const val KEY_NAME = "name" - private const val KEY_URL = "url" - private const val KEY_SOURCE = "source" - private const val KEY_TYPE = "type" - private const val KEY_CALLBACK = "callback" - private const val KEY_UPDATE_INTERVAL = "update_interval" - - @JvmField - val CREATOR = object : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): ProfileRequest { - return ProfileRequest(parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } - } -} \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt b/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt index 2815d33..d278b6c 100644 --- a/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt +++ b/service/src/main/java/com/github/kr328/clash/service/util/BroadcastUtils.kt @@ -4,10 +4,12 @@ import android.content.Context import android.content.Intent import com.github.kr328.clash.common.Permissions import com.github.kr328.clash.common.ids.Intents +import com.github.kr328.clash.common.utils.Log +import java.lang.Exception fun Context.sendBroadcastSelf(intent: Intent) { this.sendBroadcast(intent.setPackage(this.packageName), - Permissions.PERMISSION_ACCESS_CLASH) + Permissions.PERMISSION_RECEIVE_BROADCASTS) } fun Context.broadcastProfileChanged() {