mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: allow user to save logs
This commit is contained in:
parent
8dd8f88d2b
commit
d9d83df9de
@ -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())
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user