feat: allow user to save logs

This commit is contained in:
Ax333l 2023-07-06 20:01:44 +02:00
parent 370276dcab
commit 62e293763d
No known key found for this signature in database
GPG Key ID: D2B4D85271127D23
5 changed files with 75 additions and 25 deletions

View File

@ -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())
}
}

View File

@ -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<ImmutableList<Step>>
val progress: MutableStateFlow<ImmutableList<Step>>,
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)

View File

@ -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
)
}
}
)
}

View File

@ -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<ImmutableList<Step>>
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<Pair<LogLevel, String>>()
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"
}
}

View File

@ -97,6 +97,7 @@
<string name="export_app">Export</string>
<string name="export_app_success">Apk exported</string>
<string name="sign_fail">Failed to sign Apk: %s</string>
<string name="save_logs">Save logs</string>
<string name="patcher_step_group_prepare">Preparation</string>
<string name="patcher_step_load_patches">Load patches</string>