This commit is contained in:
Kr328 committed 2020-04-13 23:48:40 +08:00
1 parent d034eb6f4b
commit 1b2c97d381
23 files changed
+59 -154

No files matched your search

@@ -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)
}
@@ -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)
}
@@ -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))
}
}
}
@@ -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
)
@@ -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()
}
}
@@ -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) {
@@ -62,7 +62,6 @@ class ProfileClient(private val service: IProfileService) {
service.queryById(id)
}
suspend fun setActive(id: Long) = withContext(Dispatchers.IO) {
service.setActive(id)
}
+3 -3
View File
@@ -8,7 +8,7 @@
<string name="append_system_dns_summary">自动追加系统 DNS 到 Clash</string>
<string name="application_broken">应用损坏</string>
<string name="application_name">Clash for Android</string>
<string name="auto_update">自动更新 (秒)</string>
<string name="auto_update">自动更新 (分钟)</string>
<string name="behavior">行为</string>
<string name="boot">启动</string>
<string name="bypass_private_network">绕过私有网络</string>
@@ -96,7 +96,7 @@
<string name="sort_proxy">代理排序</string>
<string name="start_clash_on_system_boot">在系统启动时启动 Clash</string>
<string name="start_on_boot">开机时启动</string>
<string name="start_url_provider_failure">打开 URL 提供商 失败</string>
<string name="start_url_provider_failure">打开 URL 提供程序失败</string>
<string name="stopped">已停止</string>
<string name="support">支持</string>
<string name="tap_to_start">点此启动</string>
@@ -128,6 +128,6 @@
<string name="profile_not_found">配置文件丢失</string>
<string name="more_than_15_minutes">大于15分钟</string>
<string name="loading">载入中</string>
<string name="tips_support"><![CDATA[Clash for Android 是一个<strong>免费开源</strong>的项目, <strong>不提供</strong>任何代理服务<br />请务必<strong>不要</strong>反馈非应用自身引起的问题]]></string>
<string name="tips_support"><![CDATA[Clash for Android 是一个<strong>免费开源</strong>的项目<br /> 我们<strong>不提供</strong>任何代理服务<br />请务必<strong>不要</strong>反馈非应用自身引起的问题]]></string>
<string name="donate">捐赠</string>
</resources>
+1
View File
@@ -5,4 +5,5 @@
android:label="@string/receive_clash_broadcasts"
android:description="@string/receive_broadcasts_of_clash"
android:protectionLevel="privileged|signature" />
<uses-permission android:name="${applicationId}.permission.RECEIVE_BROADCASTS" />
</manifest>
@@ -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"
}
+4
View File
@@ -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() {
+1 -20
View File
@@ -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
@@ -18,7 +18,7 @@ import java.io.InputStream
object Clash {
private val logReceivers = mutableMapOf<String, (LogEvent) -> Unit>()
fun init() {
init {
val context = Global.application
val bytes = context.assets.open("Country.mmdb")
@@ -22,6 +22,9 @@ abstract class Base(val screen: CommonUiScreen) {
get() = field || (dependOn?.isHidden ?: false)
set(value) {
field = value
reapplyAttribute()
screen.postReapplyAttribute()
}
@@ -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(
@@ -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
@@ -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),
@@ -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)
}
@@ -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 }
@@ -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
@@ -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
@@ -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<ProfileRequest> {
override fun createFromParcel(parcel: Parcel): ProfileRequest {
return ProfileRequest(parcel)
}
override fun newArray(size: Int): Array<ProfileRequest?> {
return arrayOfNulls(size)
}
}
}
}
@@ -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() {