fix profile edit & cleanup code
This commit is contained in:
8 files changed
+51
-83
No files matched your search
@@ -98,7 +98,7 @@ class ProfileEditActivity : BaseActivity() {
|
||||
override fun onDestroy() {
|
||||
runBlocking {
|
||||
withProfile {
|
||||
cancel(intent.getLongExtra("id", -1))
|
||||
release(intent.getLongExtra("id", -1))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.github.kr328.clash.adapter.ProfileAdapter
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.startForegroundServiceCompat
|
||||
import com.github.kr328.clash.remote.withProfile
|
||||
import com.github.kr328.clash.service.ProfileProvider
|
||||
import com.github.kr328.clash.service.ProfileReceiver
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.service.util.sendBroadcastSelf
|
||||
import com.github.kr328.clash.weight.ProfilesMenu
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.activity_profiles.*
|
||||
@@ -27,7 +26,6 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
|
||||
private const val EDITOR_REQUEST_CODE = 30000
|
||||
}
|
||||
|
||||
private val self = this
|
||||
private var backgroundJob: Job? = null
|
||||
private val reloadMutex = Mutex()
|
||||
private val editorStack = Stack<Long>()
|
||||
@@ -69,12 +67,7 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
|
||||
val id = editorStack.pop()
|
||||
|
||||
withProfile {
|
||||
if (resultCode == Activity.RESULT_OK)
|
||||
commitAsync(id)
|
||||
else
|
||||
ProfileProvider.releaseTemp(self, id)
|
||||
|
||||
Unit
|
||||
startUpdate(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +125,15 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
|
||||
if (id < 0)
|
||||
throw FileNotFoundException()
|
||||
|
||||
val uri = ProfileProvider.acquireTemp(self, id)
|
||||
val uri = withProfile {
|
||||
acquireTempUri(id)
|
||||
} ?: throw FileNotFoundException()
|
||||
|
||||
editorStack.push(id)
|
||||
|
||||
startActivityForResult(
|
||||
Intent(Intent.ACTION_VIEW)
|
||||
.setDataAndType(uri, "text/plain")
|
||||
.setDataAndType(Uri.parse(uri), "text/plain")
|
||||
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION),
|
||||
EDITOR_REQUEST_CODE
|
||||
)
|
||||
@@ -149,7 +144,7 @@ class ProfilesActivity : BaseActivity(), ProfileAdapter.Callback, ProfilesMenu.C
|
||||
}
|
||||
|
||||
private fun startUpdate(id: Long) {
|
||||
startForegroundServiceCompat(ProfileReceiver.buildUpdateIntentForId(id))
|
||||
sendBroadcastSelf(ProfileReceiver.buildUpdateIntentForId(id))
|
||||
}
|
||||
|
||||
override fun onOpenEditor(entity: Profile) {
|
||||
|
||||
@@ -18,6 +18,10 @@ class ProfileClient(private val service: IProfileService) {
|
||||
service.acquireCloned(id)
|
||||
}
|
||||
|
||||
suspend fun acquireTempUri(id: Long): String? = withContext(Dispatchers.IO) {
|
||||
service.acquireTempUri(id)
|
||||
}
|
||||
|
||||
suspend fun updateMetadata(id: Long, metadata: Profile) = withContext(Dispatchers.IO) {
|
||||
service.updateMetadata(id, metadata)
|
||||
}
|
||||
@@ -38,8 +42,8 @@ class ProfileClient(private val service: IProfileService) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun cancel(id: Long) = withContext(Dispatchers.IO) {
|
||||
service.cancel(id)
|
||||
suspend fun release(id: Long) = withContext(Dispatchers.IO) {
|
||||
service.release(id)
|
||||
}
|
||||
|
||||
suspend fun delete(id: Long) = withContext(Dispatchers.IO) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
package com.github.kr328.clash.core.event;
|
||||
|
||||
parcelable LogEvent;
|
||||
parcelable TrafficEvent;
|
||||
parcelable BandwidthEvent;
|
||||
parcelable LogEvent;
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.github.kr328.clash.service;
|
||||
|
||||
import com.github.kr328.clash.service.transact.IStreamCallback;
|
||||
import com.github.kr328.clash.service.model.ProfileMetadata;
|
||||
import com.github.kr328.clash.service.model.Profile;
|
||||
|
||||
interface IProfileService {
|
||||
long acquireUnused(String type);
|
||||
long acquireCloned(long id);
|
||||
void updateMetadata(long id, in ProfileMetadata metadata);
|
||||
String acquireTempUri(long id);
|
||||
void release(long id);
|
||||
void updateMetadata(long id, in Profile metadata);
|
||||
void commit(long id, in IStreamCallback callback);
|
||||
void cancel(long id);
|
||||
void delete(long id);
|
||||
void clear(long id);
|
||||
|
||||
ProfileMetadata queryById(long id);
|
||||
ProfileMetadata[] queryAll();
|
||||
ProfileMetadata queryActive();
|
||||
Profile queryById(long id);
|
||||
Profile[] queryAll();
|
||||
Profile queryActive();
|
||||
|
||||
void setActive(long id);
|
||||
}
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package com.github.kr328.clash.service.model;
|
||||
|
||||
parcelable ProfileMetadata;
|
||||
parcelable Profile;
|
||||
@@ -2,22 +2,11 @@ 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,
|
||||
@@ -25,45 +14,5 @@ class ProfileProvider : FileProvider() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class ProfileService : BaseService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel(id: Long) {
|
||||
override fun release(id: Long) {
|
||||
launch {
|
||||
lock.withLock {
|
||||
pending.remove(id)
|
||||
@@ -138,6 +138,26 @@ class ProfileService : BaseService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun acquireTempUri(id: Long): String? {
|
||||
val file = service.resolveProfileFile(id)
|
||||
if ( !file.exists() )
|
||||
return null
|
||||
|
||||
val tempFile = service.resolveTempProfileFile(id)
|
||||
|
||||
file.copyTo(tempFile)
|
||||
|
||||
val uri = ProfileProvider.resolveUri(service, tempFile)
|
||||
|
||||
return runBlocking {
|
||||
lock.withLock {
|
||||
pending[id] = queryMetadataById(id)?.copy(uri = uri) ?: return@withLock
|
||||
}
|
||||
|
||||
uri.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateMetadata(id: Long, metadata: Profile?) {
|
||||
launch {
|
||||
lock.withLock {
|
||||
@@ -164,7 +184,7 @@ class ProfileService : BaseService() {
|
||||
|
||||
val ctx = lock.withLock {
|
||||
tasks.entries.firstOrNull()?.also {
|
||||
tasks.remove(it.key)
|
||||
tasks[it.key]
|
||||
}
|
||||
} ?: continue
|
||||
|
||||
@@ -172,10 +192,6 @@ class ProfileService : BaseService() {
|
||||
val metadata = queryMetadataById(ctx.key)
|
||||
?: throw RemoteException("No such profile")
|
||||
|
||||
lock.withLock {
|
||||
pending.remove(metadata.id)
|
||||
}
|
||||
|
||||
ProfileProcessor.createOrUpdate(service, metadata)
|
||||
|
||||
ctx.value?.complete()
|
||||
@@ -184,6 +200,11 @@ class ProfileService : BaseService() {
|
||||
} catch (e: Exception) {
|
||||
ctx.value?.completeExceptionally(e.message)
|
||||
}
|
||||
finally {
|
||||
lock.withLock {
|
||||
tasks.remove(ctx.key)
|
||||
}
|
||||
}
|
||||
|
||||
request.offer(Unit)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user