Commit 50305ca1 authored by vvb2060's avatar vvb2060 Committed by topjohnwu

Support save manager log

parent 3e915676
...@@ -16,8 +16,6 @@ object Const { ...@@ -16,8 +16,6 @@ object Const {
const val BOOTCTL_REVISION = "18ab78817087c337ae0edd1ecac38aec49217880" const val BOOTCTL_REVISION = "18ab78817087c337ae0edd1ecac38aec49217880"
// Misc // Misc
const val ANDROID_MANIFEST = "AndroidManifest.xml"
const val MAGISK_INSTALL_LOG_FILENAME = "magisk_install_log_%s.log"
val USER_ID = Process.myUid() / 100000 val USER_ID = Process.myUid() / 100000
object Version { object Version {
......
...@@ -33,6 +33,7 @@ object HideAPK { ...@@ -33,6 +33,7 @@ object HideAPK {
private const val ALPHA = "abcdefghijklmnopqrstuvwxyz" private const val ALPHA = "abcdefghijklmnopqrstuvwxyz"
private const val ALPHADOTS = "$ALPHA....." private const val ALPHADOTS = "$ALPHA....."
private const val APP_NAME = "Magisk Manager" private const val APP_NAME = "Magisk Manager"
private const val ANDROID_MANIFEST = "AndroidManifest.xml"
// Some arbitrary limit // Some arbitrary limit
const val MAX_LABEL_LENGTH = 32 const val MAX_LABEL_LENGTH = 32
...@@ -71,7 +72,7 @@ object HideAPK { ...@@ -71,7 +72,7 @@ object HideAPK {
): Boolean { ): Boolean {
try { try {
val jar = JarMap.open(apk) val jar = JarMap.open(apk)
val je = jar.getJarEntry(Const.ANDROID_MANIFEST) val je = jar.getJarEntry(ANDROID_MANIFEST)
val xml = AXML(jar.getRawData(je)) val xml = AXML(jar.getRawData(je))
if (!xml.findAndPatch(APPLICATION_ID to pkg, APP_NAME to label.toString())) if (!xml.findAndPatch(APPLICATION_ID to pkg, APP_NAME to label.toString()))
......
...@@ -13,18 +13,17 @@ import com.topjohnwu.magisk.arch.itemBindingOf ...@@ -13,18 +13,17 @@ import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.tasks.FlashZip import com.topjohnwu.magisk.core.tasks.FlashZip
import com.topjohnwu.magisk.core.tasks.MagiskInstaller import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.databinding.RvBindingAdapter import com.topjohnwu.magisk.databinding.RvBindingAdapter
import com.topjohnwu.magisk.events.SnackbarEvent import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.* import com.topjohnwu.magisk.ktx.*
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.superuser.CallbackList import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class FlashViewModel( class FlashViewModel(
args: FlashFragmentArgs, args: FlashFragmentArgs,
...@@ -106,18 +105,16 @@ class FlashViewModel( ...@@ -106,18 +105,16 @@ class FlashViewModel(
} }
private fun savePressed() = withExternalRW { private fun savePressed() = withExternalRW {
viewModelScope.launch { viewModelScope.launch(Dispatchers.IO) {
withContext(Dispatchers.IO) { val name = "magisk_install_log_%s.log".format(now.toTime(timeFormatStandard))
val name = Const.MAGISK_INSTALL_LOG_FILENAME.format(now.toTime(timeFormatStandard)) val file = MediaStoreUtils.getFile(name)
val file = MediaStoreUtils.getFile(name) file.uri.outputStream().bufferedWriter().use { writer ->
file.uri.outputStream().bufferedWriter().use { writer -> logItems.forEach {
logItems.forEach { writer.write(it)
writer.write(it) writer.newLine()
writer.newLine()
}
} }
SnackbarEvent(file.toString()).publish()
} }
SnackbarEvent(file.toString()).publish()
} }
} }
......
...@@ -3,20 +3,27 @@ package com.topjohnwu.magisk.ui.log ...@@ -3,20 +3,27 @@ package com.topjohnwu.magisk.ui.log
import androidx.databinding.Bindable import androidx.databinding.Bindable
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.diffListOf import com.topjohnwu.magisk.arch.diffListOf
import com.topjohnwu.magisk.arch.itemBindingOf import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.data.repository.LogRepository import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
import com.topjohnwu.magisk.data.repository.LogRepository
import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.ktx.now
import com.topjohnwu.magisk.ktx.timeFormatStandard
import com.topjohnwu.magisk.ktx.toTime
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import com.topjohnwu.magisk.view.TextItem import com.topjohnwu.magisk.view.TextItem
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.* import java.util.concurrent.Executor
class LogViewModel( class LogViewModel(
private val repo: LogRepository private val repo: LogRepository
...@@ -54,14 +61,28 @@ class LogViewModel( ...@@ -54,14 +61,28 @@ class LogViewModel(
fun saveMagiskLog() = withExternalRW { fun saveMagiskLog() = withExternalRW {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val now = Calendar.getInstance() val filename = "magisk_log_%s.log".format(now.toTime(timeFormatStandard))
val filename = "magisk_log_%04d%02d%02d_%02d%02d%02d.log".format(
now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1,
now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY),
now.get(Calendar.MINUTE), now.get(Calendar.SECOND)
)
val logFile = MediaStoreUtils.getFile(filename) val logFile = MediaStoreUtils.getFile(filename)
logFile.uri.outputStream().writer().use { it.write(consoleText) } logFile.uri.outputStream().bufferedWriter().use { file ->
file.write("---System Properties---\n\n")
val fileList = object : CallbackList<String>(Executor { it.run() }) {
override fun onAddElement(e: String) {
file.write(e)
file.newLine()
}
}
Shell.su("getprop").to(fileList).exec()
file.write("\n---Magisk Logs---\n")
file.write("${Info.env.magiskVersionString} (${Info.env.magiskVersionCode})\n\n")
file.write(consoleText)
file.write("\n---Manager Logs---\n")
file.write("${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\n\n")
ProcessBuilder("logcat", "-d").start()
.inputStream.reader().use { it.copyTo(file) }
}
SnackbarEvent(logFile.toString()).publish() SnackbarEvent(logFile.toString()).publish()
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment