From 62e293763d0996a5299af0243f749bc9423b5abe Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 6 Jul 2023 20:01:44 +0200 Subject: [PATCH] feat: allow user to save logs --- .../app/revanced/manager/patcher/Session.kt | 22 +------ .../manager/patcher/worker/PatcherWorker.kt | 5 +- .../manager/ui/screen/InstallerScreen.kt | 15 ++++- .../ui/viewmodel/InstallerViewModel.kt | 57 ++++++++++++++++++- app/src/main/res/values/strings.xml | 1 + 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/patcher/Session.kt b/app/src/main/java/app/revanced/manager/patcher/Session.kt index b10fc48..ae0239c 100644 --- a/app/src/main/java/app/revanced/manager/patcher/Session.kt +++ b/app/src/main/java/app/revanced/manager/patcher/Session.kt @@ -22,10 +22,10 @@ class Session( cacheDir: String, frameworkDir: String, aaptPath: String, + private val logger: Logger, private val input: File, private val onProgress: suspend (Progress) -> Unit = { } ) : Closeable { - private val logger = LogcatLogger private val temporary = File(cacheDir).resolve("manager").also { it.mkdirs() } private val patcher = Patcher( PatcherOptions( @@ -83,24 +83,4 @@ class Session( override fun close() { temporary.delete() } -} - -private object LogcatLogger : Logger { - fun String.fmt() = "[Patcher]: $this" - - override fun error(msg: String) { - Log.e(tag, msg.fmt()) - } - - override fun warn(msg: String) { - Log.w(tag, msg.fmt()) - } - - override fun info(msg: String) { - Log.i(tag, msg.fmt()) - } - - override fun trace(msg: String) { - Log.v(tag, msg.fmt()) - } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt index b47e4af..1c81a7e 100644 --- a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt +++ b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt @@ -24,6 +24,7 @@ import app.revanced.manager.util.PatchesSelection import app.revanced.manager.util.tag import app.revanced.patcher.extensions.PatchExtensions.options import app.revanced.patcher.extensions.PatchExtensions.patchName +import app.revanced.patcher.logging.Logger import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow @@ -46,7 +47,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters) : val options: Options, val packageName: String, val packageVersion: String, - val progress: MutableStateFlow> + val progress: MutableStateFlow>, + val logger: Logger ) companion object { @@ -159,6 +161,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters) : applicationContext.cacheDir.absolutePath, frameworkPath, aaptPath, + args.logger, File(args.input) ) { updateProgress(it) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/InstallerScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/InstallerScreen.kt index 3d48dd8..0728a0a 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/InstallerScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/InstallerScreen.kt @@ -25,6 +25,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -48,11 +49,13 @@ fun InstallerScreen( onBackClick: () -> Unit, vm: InstallerViewModel ) { + val context = LocalContext.current val exportApkLauncher = rememberLauncherForActivityResult(CreateDocument(APK_MIMETYPE), vm::export) val patcherState by vm.patcherState.observeAsState(null) val steps by vm.progress.collectAsStateWithLifecycle() val canInstall by remember { derivedStateOf { patcherState == true && (vm.installedPackageName != null || !vm.isInstalling) } } + var dropdownActive by rememberSaveable { mutableStateOf(false) } AppScaffold( topBar = { @@ -63,9 +66,19 @@ fun InstallerScreen( IconButton(onClick = {}) { Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help)) } - IconButton(onClick = {}) { + IconButton(onClick = { dropdownActive = true }) { Icon(Icons.Outlined.MoreVert, stringResource(R.string.more)) } + DropdownMenu( + expanded = dropdownActive, + onDismissRequest = { dropdownActive = false } + ) { + DropdownMenuItem( + text = { Text(stringResource(R.string.save_logs)) }, + onClick = { vm.exportLogs(context) }, + enabled = patcherState != null + ) + } } ) } diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt index 0818956..f956ba5 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/InstallerViewModel.kt @@ -15,7 +15,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.map -import androidx.work.* +import androidx.work.WorkInfo +import androidx.work.WorkManager import app.revanced.manager.domain.manager.KeystoreManager import app.revanced.manager.R import app.revanced.manager.domain.worker.WorkerRepository @@ -28,6 +29,7 @@ import app.revanced.manager.ui.destination.Destination import app.revanced.manager.util.PM import app.revanced.manager.util.tag import app.revanced.manager.util.toast +import app.revanced.patcher.logging.Logger import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow @@ -60,6 +62,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon private val _progress: MutableStateFlow> private val patcherWorkerId: UUID + private val logger = ManagerLogger() init { val (appInfo, patches, options) = input @@ -77,7 +80,8 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon options, packageName, appInfo.packageInfo!!.versionName, - _progress + _progress, + logger ) ) } @@ -122,6 +126,17 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon }) } + fun exportLogs(context: Context) { + val sendIntent: Intent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_TEXT, logger.export()) + type = "text/plain" + } + + val shareIntent = Intent.createChooser(sendIntent, null) + context.startActivity(shareIntent) + } + override fun onCleared() { super.onCleared() app.unregisterReceiver(installBroadcastReceiver) @@ -166,4 +181,42 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon isInstalling = false } } +} + +private class ManagerLogger : Logger { + private val logs = mutableListOf>() + private fun log(level: LogLevel, msg: String) { + level.androidLog(msg) + if (level == LogLevel.TRACE) return + logs.add(level to msg) + } + + fun export() = + logs.asSequence().map { (level, msg) -> "[${level.name}]: $msg" }.joinToString("\n") + + override fun trace(msg: String) = log(LogLevel.TRACE, msg) + override fun info(msg: String) = log(LogLevel.INFO, msg) + override fun warn(msg: String) = log(LogLevel.WARN, msg) + override fun error(msg: String) = log(LogLevel.ERROR, msg) +} + +enum class LogLevel { + TRACE { + override fun androidLog(msg: String) = Log.v(androidTag, msg) + }, + INFO { + override fun androidLog(msg: String) = Log.i(androidTag, msg) + }, + WARN { + override fun androidLog(msg: String) = Log.w(androidTag, msg) + }, + ERROR { + override fun androidLog(msg: String) = Log.e(androidTag, msg) + }; + + abstract fun androidLog(msg: String): Int + + private companion object { + const val androidTag = "ReVanced Patcher" + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd015d7..5ca1a0a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,6 +97,7 @@ Export Apk exported Failed to sign Apk: %s + Save logs Preparation Load patches