mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-05-12 22:18:26 +00:00
Use RV to show Magisk logs
This commit is contained in:
parent
03cee0b8d4
commit
4de93cfd4b
@ -1,30 +1,29 @@
|
|||||||
package com.topjohnwu.magisk.ui.log
|
package com.topjohnwu.magisk.ui.log
|
||||||
|
|
||||||
import androidx.databinding.Bindable
|
import androidx.databinding.ViewDataBinding
|
||||||
import com.topjohnwu.magisk.BR
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.textview.MaterialTextView
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.model.su.SuLog
|
|
||||||
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||||
import com.topjohnwu.magisk.databinding.RvContainer
|
import com.topjohnwu.magisk.databinding.RvContainer
|
||||||
import com.topjohnwu.magisk.databinding.set
|
import com.topjohnwu.magisk.databinding.ViewAwareRvItem
|
||||||
import com.topjohnwu.magisk.ktx.timeDateFormat
|
|
||||||
import com.topjohnwu.magisk.ktx.toTime
|
|
||||||
|
|
||||||
class LogRvItem(
|
class LogRvItem(
|
||||||
override val item: SuLog
|
override val item: String
|
||||||
) : ObservableDiffRvItem<LogRvItem>(), RvContainer<SuLog> {
|
) : ObservableDiffRvItem<LogRvItem>(), RvContainer<String>, ViewAwareRvItem {
|
||||||
|
|
||||||
override val layoutRes = R.layout.item_log_access_md2
|
override val layoutRes = R.layout.item_log_textview
|
||||||
|
|
||||||
val date = item.time.toTime(timeDateFormat)
|
override fun itemSameAs(other: LogRvItem) = item == other.item
|
||||||
|
|
||||||
@get:Bindable
|
override fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) {
|
||||||
var isTop = false
|
val view = binding.root as MaterialTextView
|
||||||
set(value) = set(value, field, { field = it }, BR.top)
|
view.measure(0, 0)
|
||||||
|
val desiredWidth = view.measuredWidth
|
||||||
@get:Bindable
|
val layoutParams = view.layoutParams
|
||||||
var isBottom = false
|
layoutParams.width = desiredWidth
|
||||||
set(value) = set(value, field, { field = it }, BR.bottom)
|
if (recyclerView.width < desiredWidth) {
|
||||||
|
recyclerView.requestLayout()
|
||||||
override fun itemSameAs(other: LogRvItem) = item.appName == other.item.appName
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ import java.io.FileInputStream
|
|||||||
class LogViewModel(
|
class LogViewModel(
|
||||||
private val repo: LogRepository
|
private val repo: LogRepository
|
||||||
) : AsyncLoadViewModel() {
|
) : AsyncLoadViewModel() {
|
||||||
|
@get:Bindable
|
||||||
|
var loading = true
|
||||||
|
private set(value) = set(value, field, { field = it }, BR.loading)
|
||||||
|
|
||||||
// --- empty view
|
// --- empty view
|
||||||
|
|
||||||
@ -34,27 +37,34 @@ class LogViewModel(
|
|||||||
|
|
||||||
// --- su log
|
// --- su log
|
||||||
|
|
||||||
val items = DiffRvItemList<LogRvItem>()
|
val items = DiffRvItemList<SuLogRvItem>()
|
||||||
val extraBindings = bindExtra {
|
val extraBindings = bindExtra {
|
||||||
it.put(BR.viewModel, this)
|
it.put(BR.viewModel, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- magisk log
|
// --- magisk log
|
||||||
@get:Bindable
|
val logs = DiffRvItemList<LogRvItem>()
|
||||||
var consoleText = " "
|
var magiskLogRaw = " "
|
||||||
set(value) = set(value, field, { field = it }, BR.consoleText)
|
|
||||||
|
|
||||||
override suspend fun doLoadWork() {
|
override suspend fun doLoadWork() {
|
||||||
consoleText = repo.fetchMagiskLogs()
|
loading = true
|
||||||
val (suLogs, diff) = withContext(Dispatchers.Default) {
|
val (logs, logDiff) = withContext(Dispatchers.Default) {
|
||||||
val suLogs = repo.fetchSuLogs().map { LogRvItem(it) }
|
magiskLogRaw = repo.fetchMagiskLogs()
|
||||||
|
val logs = magiskLogRaw.split('\n').map { LogRvItem(it) }
|
||||||
|
logs to this@LogViewModel.logs.calculateDiff(logs)
|
||||||
|
}
|
||||||
|
this.logs.update(logs, logDiff)
|
||||||
|
|
||||||
|
val (suLogs, suDiff) = withContext(Dispatchers.Default) {
|
||||||
|
val suLogs = repo.fetchSuLogs().map { SuLogRvItem(it) }
|
||||||
suLogs to items.calculateDiff(suLogs)
|
suLogs to items.calculateDiff(suLogs)
|
||||||
}
|
}
|
||||||
items.firstOrNull()?.isTop = false
|
items.firstOrNull()?.isTop = false
|
||||||
items.lastOrNull()?.isBottom = false
|
items.lastOrNull()?.isBottom = false
|
||||||
items.update(suLogs, diff)
|
items.update(suLogs, suDiff)
|
||||||
items.firstOrNull()?.isTop = true
|
items.firstOrNull()?.isTop = true
|
||||||
items.lastOrNull()?.isBottom = true
|
items.lastOrNull()?.isBottom = true
|
||||||
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveMagiskLog() = withExternalRW {
|
fun saveMagiskLog() = withExternalRW {
|
||||||
@ -82,7 +92,7 @@ class LogViewModel(
|
|||||||
|
|
||||||
file.write("\n---Magisk Logs---\n")
|
file.write("\n---Magisk Logs---\n")
|
||||||
file.write("${Info.env.versionString} (${Info.env.versionCode})\n\n")
|
file.write("${Info.env.versionString} (${Info.env.versionCode})\n\n")
|
||||||
if (Info.env.isActive) file.write(consoleText)
|
if (Info.env.isActive) file.write(magiskLogRaw)
|
||||||
|
|
||||||
file.write("\n---Manager Logs---\n")
|
file.write("\n---Manager Logs---\n")
|
||||||
file.write("${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\n\n")
|
file.write("${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\n\n")
|
||||||
|
30
app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt
Normal file
30
app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package com.topjohnwu.magisk.ui.log
|
||||||
|
|
||||||
|
import androidx.databinding.Bindable
|
||||||
|
import com.topjohnwu.magisk.BR
|
||||||
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.core.model.su.SuLog
|
||||||
|
import com.topjohnwu.magisk.databinding.ObservableDiffRvItem
|
||||||
|
import com.topjohnwu.magisk.databinding.RvContainer
|
||||||
|
import com.topjohnwu.magisk.databinding.set
|
||||||
|
import com.topjohnwu.magisk.ktx.timeDateFormat
|
||||||
|
import com.topjohnwu.magisk.ktx.toTime
|
||||||
|
|
||||||
|
class SuLogRvItem(
|
||||||
|
override val item: SuLog
|
||||||
|
) : ObservableDiffRvItem<SuLogRvItem>(), RvContainer<SuLog> {
|
||||||
|
|
||||||
|
override val layoutRes = R.layout.item_log_access_md2
|
||||||
|
|
||||||
|
val date = item.time.toTime(timeDateFormat)
|
||||||
|
|
||||||
|
@get:Bindable
|
||||||
|
var isTop = false
|
||||||
|
set(value) = set(value, field, { field = it }, BR.top)
|
||||||
|
|
||||||
|
@get:Bindable
|
||||||
|
var isBottom = false
|
||||||
|
set(value) = set(value, field, { field = it }, BR.bottom)
|
||||||
|
|
||||||
|
override fun itemSameAs(other: SuLogRvItem) = item.appName == other.item.appName
|
||||||
|
}
|
@ -23,6 +23,7 @@
|
|||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
gone="@{viewModel.loading}"
|
||||||
android:id="@+id/log_filter_toggle"
|
android:id="@+id/log_filter_toggle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -15,46 +15,63 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<HorizontalScrollView
|
||||||
gone="@{viewModel.consoleText.empty}"
|
gone="@{viewModel.loading}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:fillViewport="true">
|
android:fillViewport="true">
|
||||||
|
|
||||||
<HorizontalScrollView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/log_magisk"
|
||||||
android:layout_height="wrap_content">
|
app:items="@{viewModel.logs}"
|
||||||
|
app:extraBindings="@{viewModel.extraBindings}"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/internal_action_bar_size"
|
||||||
|
android:paddingBottom="@dimen/internal_action_bar_size"
|
||||||
|
app:fitsSystemWindowsInsets="top|bottom"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_log_textview"
|
||||||
|
tools:paddingTop="24dp" />
|
||||||
|
</HorizontalScrollView>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:paddingTop="@dimen/internal_action_bar_size"
|
|
||||||
android:paddingBottom="128dp"
|
|
||||||
android:text="@{viewModel.consoleText}"
|
|
||||||
android:textAppearance="@style/AppearanceFoundation.Caption"
|
|
||||||
app:layout_fitsSystemWindowsInsets="top|bottom"
|
|
||||||
tools:text="@tools:sample/lorem/random" />
|
|
||||||
|
|
||||||
</HorizontalScrollView>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
gone="@{!viewModel.consoleText.empty}"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center">
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<TextView
|
||||||
item="@{viewModel.itemMagiskEmpty}"
|
goneUnless="@{viewModel.loading}"
|
||||||
layout="@layout/item_text"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/loading"
|
||||||
|
android:textAppearance="@style/AppearanceFoundation.Title"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
style="@style/WidgetFoundation.ProgressBar.Indeterminate"
|
||||||
|
goneUnless="@{viewModel.loading}"
|
||||||
|
android:layout_marginTop="@dimen/l1" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
gone="@{viewModel.loading || !viewModel.magiskLogRaw.empty}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center">
|
||||||
|
|
||||||
</FrameLayout>
|
<include
|
||||||
|
item="@{viewModel.itemMagiskEmpty}"
|
||||||
|
layout="@layout/item_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="item"
|
name="item"
|
||||||
type="com.topjohnwu.magisk.ui.log.LogRvItem" />
|
type="com.topjohnwu.magisk.ui.log.SuLogRvItem" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
|
20
app/src/main/res/layout/item_log_textview.xml
Normal file
20
app/src/main/res/layout/item_log_textview.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="item"
|
||||||
|
type="com.topjohnwu.magisk.ui.log.LogRvItem" />
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:textAppearance="@style/AppearanceFoundation.Caption"
|
||||||
|
android:text="@{item.item}" />
|
||||||
|
|
||||||
|
</layout>
|
Loading…
x
Reference in New Issue
Block a user