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,
|
cacheDir: String,
|
||||||
frameworkDir: String,
|
frameworkDir: String,
|
||||||
aaptPath: String,
|
aaptPath: String,
|
||||||
|
private val logger: Logger,
|
||||||
private val input: File,
|
private val input: File,
|
||||||
private val onProgress: suspend (Progress) -> Unit = { }
|
private val onProgress: suspend (Progress) -> Unit = { }
|
||||||
) : Closeable {
|
) : Closeable {
|
||||||
private val logger = LogcatLogger
|
|
||||||
private val temporary = File(cacheDir).resolve("manager").also { it.mkdirs() }
|
private val temporary = File(cacheDir).resolve("manager").also { it.mkdirs() }
|
||||||
private val patcher = Patcher(
|
private val patcher = Patcher(
|
||||||
PatcherOptions(
|
PatcherOptions(
|
||||||
@ -83,24 +83,4 @@ class Session(
|
|||||||
override fun close() {
|
override fun close() {
|
||||||
temporary.delete()
|
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.manager.util.tag
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.options
|
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
|
import app.revanced.patcher.logging.Logger
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -46,7 +47,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters) :
|
|||||||
val options: Options,
|
val options: Options,
|
||||||
val packageName: String,
|
val packageName: String,
|
||||||
val packageVersion: String,
|
val packageVersion: String,
|
||||||
val progress: MutableStateFlow<ImmutableList<Step>>
|
val progress: MutableStateFlow<ImmutableList<Step>>,
|
||||||
|
val logger: Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -159,6 +161,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters) :
|
|||||||
applicationContext.cacheDir.absolutePath,
|
applicationContext.cacheDir.absolutePath,
|
||||||
frameworkPath,
|
frameworkPath,
|
||||||
aaptPath,
|
aaptPath,
|
||||||
|
args.logger,
|
||||||
File(args.input)
|
File(args.input)
|
||||||
) {
|
) {
|
||||||
updateProgress(it)
|
updateProgress(it)
|
||||||
|
@ -25,6 +25,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
@ -48,11 +49,13 @@ fun InstallerScreen(
|
|||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
vm: InstallerViewModel
|
vm: InstallerViewModel
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
val exportApkLauncher =
|
val exportApkLauncher =
|
||||||
rememberLauncherForActivityResult(CreateDocument(APK_MIMETYPE), vm::export)
|
rememberLauncherForActivityResult(CreateDocument(APK_MIMETYPE), vm::export)
|
||||||
val patcherState by vm.patcherState.observeAsState(null)
|
val patcherState by vm.patcherState.observeAsState(null)
|
||||||
val steps by vm.progress.collectAsStateWithLifecycle()
|
val steps by vm.progress.collectAsStateWithLifecycle()
|
||||||
val canInstall by remember { derivedStateOf { patcherState == true && (vm.installedPackageName != null || !vm.isInstalling) } }
|
val canInstall by remember { derivedStateOf { patcherState == true && (vm.installedPackageName != null || !vm.isInstalling) } }
|
||||||
|
var dropdownActive by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
AppScaffold(
|
AppScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@ -63,9 +66,19 @@ fun InstallerScreen(
|
|||||||
IconButton(onClick = {}) {
|
IconButton(onClick = {}) {
|
||||||
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
|
Icon(Icons.Outlined.HelpOutline, stringResource(R.string.help))
|
||||||
}
|
}
|
||||||
IconButton(onClick = {}) {
|
IconButton(onClick = { dropdownActive = true }) {
|
||||||
Icon(Icons.Outlined.MoreVert, stringResource(R.string.more))
|
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.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.map
|
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.domain.manager.KeystoreManager
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.domain.worker.WorkerRepository
|
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.PM
|
||||||
import app.revanced.manager.util.tag
|
import app.revanced.manager.util.tag
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
|
import app.revanced.patcher.logging.Logger
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -60,6 +62,7 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
|||||||
|
|
||||||
private val _progress: MutableStateFlow<ImmutableList<Step>>
|
private val _progress: MutableStateFlow<ImmutableList<Step>>
|
||||||
private val patcherWorkerId: UUID
|
private val patcherWorkerId: UUID
|
||||||
|
private val logger = ManagerLogger()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val (appInfo, patches, options) = input
|
val (appInfo, patches, options) = input
|
||||||
@ -77,7 +80,8 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
|||||||
options,
|
options,
|
||||||
packageName,
|
packageName,
|
||||||
appInfo.packageInfo!!.versionName,
|
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() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
app.unregisterReceiver(installBroadcastReceiver)
|
app.unregisterReceiver(installBroadcastReceiver)
|
||||||
@ -166,4 +181,42 @@ class InstallerViewModel(input: Destination.Installer) : ViewModel(), KoinCompon
|
|||||||
isInstalling = false
|
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">Export</string>
|
||||||
<string name="export_app_success">Apk exported</string>
|
<string name="export_app_success">Apk exported</string>
|
||||||
<string name="sign_fail">Failed to sign Apk: %s</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_group_prepare">Preparation</string>
|
||||||
<string name="patcher_step_load_patches">Load patches</string>
|
<string name="patcher_step_load_patches">Load patches</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user