add temp acquire

This commit is contained in:
Kr328 committed 2020-04-13 11:45:05 +08:00
1 parent 12d76a2ad1
commit 2d3bd5c5cf
7 files changed
+93 -6

No files matched your search

@@ -7,6 +7,7 @@ import android.content.IntentFilter
import android.graphics.drawable.Icon
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import com.github.kr328.clash.common.Permissions
import com.github.kr328.clash.remote.RemoteUtils
import com.github.kr328.clash.common.ids.Intents
import com.github.kr328.clash.utils.startClashService
@@ -84,7 +85,9 @@ class TileService : TileService() {
addAction(Intents.INTENT_ACTION_CLASH_STARTED)
addAction(Intents.INTENT_ACTION_CLASH_STOPPED)
addAction(Intents.INTENT_ACTION_PROFILE_LOADED)
}
},
Permissions.PERMISSION_ACCESS_CLASH,
null
)
val name = RemoteUtils.getCurrentClashProfileName(this)
@@ -8,6 +8,7 @@ import android.content.IntentFilter
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.github.kr328.clash.common.Permissions
import com.github.kr328.clash.common.ids.Intents
object Broadcasts {
@@ -70,8 +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)
val current = RemoteUtils.detectClashRunning(application)
if (current != clashRunning) {
+1 -1
View File
@@ -33,7 +33,7 @@
android:process=":background" />
<provider
android:name="androidx.core.content.FileProvider"
android:name=".ProfileProvider"
android:authorities="${applicationId}.profiles"
android:exported="false"
android:grantUriPermissions="true">
@@ -27,7 +27,15 @@ object ProfileProcessor {
context.resolveBaseDir(metadata.id)
)
val entity = metadata.toProfileEntity()
val entity = if (metadata.type == Type.FILE)
metadata.copy(
uri = ProfileProvider.resolveUri(
context,
context.resolveProfileFile(metadata.id)
)
).toProfileEntity()
else
metadata.toProfileEntity()
if (ProfileDao.queryById(metadata.id) == null)
ProfileDao.insert(entity)
@@ -0,0 +1,69 @@
package com.github.kr328.clash.service
import android.content.Context
import android.net.Uri
import android.os.Bundle
import androidx.core.content.FileProvider
import androidx.core.os.bundleOf
import com.github.kr328.clash.service.util.resolveProfileFile
import com.github.kr328.clash.service.util.resolveTempProfileFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileNotFoundException
class ProfileProvider : FileProvider() {
companion object {
private const val METHOD_ACQUIRE_TEMP = "acquireTemp"
private const val METHOD_RELEASE_TEMP = "releaseTemp"
// service side functions
fun resolveUri(context: Context, file: File): Uri {
return getUriForFile(
context,
context.packageName + Constants.PROFILE_PROVIDER_SUFFIX,
file
)
}
// client side functions
suspend fun acquireTemp(context: Context, id: Long): Uri = withContext(Dispatchers.IO) {
val uri = Uri.parse(context.packageName + Constants.PROFILE_PROVIDER_SUFFIX)
context.contentResolver
.call(uri, METHOD_ACQUIRE_TEMP, id.toString(), null)?.getParcelable<Uri>("uri")
?: throw FileNotFoundException("No such profile")
}
suspend fun releaseTemp(context: Context, id: Long) = withContext(Dispatchers.IO) {
val uri = Uri.parse(context.packageName + Constants.PROFILE_PROVIDER_SUFFIX)
context.contentResolver
.call(uri, METHOD_RELEASE_TEMP, id.toString(), null)
}
}
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
when (method) {
METHOD_ACQUIRE_TEMP -> {
val id = arg?.toLongOrNull() ?: return null
val file = context!!.resolveProfileFile(id)
if (!file.exists())
return null
val temp = context!!.resolveTempProfileFile(id)
if (!temp.exists())
file.copyTo(context!!.resolveTempProfileFile(id))
return bundleOf("uri" to resolveUri(context!!, temp))
}
METHOD_RELEASE_TEMP -> {
val id = arg?.toLongOrNull() ?: return null
context!!.resolveTempProfileFile(id).delete()
}
}
return super.call(method, arg, extras)
}
}
@@ -11,6 +11,7 @@ import com.github.kr328.clash.service.model.toProfileMetadata
import com.github.kr328.clash.service.util.broadcastProfileChanged
import com.github.kr328.clash.service.util.resolveBaseDir
import com.github.kr328.clash.service.util.resolveProfileFile
import com.github.kr328.clash.service.util.resolveTempProfileFile
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.sync.Mutex
@@ -87,11 +88,13 @@ class ProfileService : BaseService() {
override fun delete(id: Long) {
launch {
lock.withLock {
pending.remove(id)
if (pending.remove(id) != null)
service.resolveBaseDir(id).deleteRecursively()
ProfileDao.remove(id)
}
service.resolveProfileFile(id).delete()
service.resolveTempProfileFile(id).delete()
service.resolveBaseDir(id).deleteRecursively()
service.broadcastProfileChanged()
@@ -10,4 +10,8 @@ fun Context.resolveProfileFile(id: Long): File {
fun Context.resolveBaseDir(id: Long): File {
return filesDir.resolve(Constants.CLASH_DIR).resolve(id.toString())
}
fun Context.resolveTempProfileFile(id: Long): File {
return cacheDir.resolve(Constants.PROFILES_DIR).resolve("$id.yaml")
}