Added new log screen
This commit is contained in:
parent
fbeaad077f
commit
6379108a75
@ -14,8 +14,10 @@ class LogRepository(
|
|||||||
private val logDao: LogDao
|
private val logDao: LogDao
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun fetchLogs() = logDao.fetchAll()
|
fun fetchLogsNowrap() = logDao.fetchAll()
|
||||||
.map { it.sortByDescending { it.date.time }; it }
|
.map { it.sortedByDescending { it.date.time } }
|
||||||
|
|
||||||
|
fun fetchLogs() = fetchLogsNowrap()
|
||||||
.map { it.wrap() }
|
.map { it.wrap() }
|
||||||
|
|
||||||
fun fetchMagiskLogs() = "tail -n 5000 ${Const.MAGISK_LOG}".suRaw()
|
fun fetchMagiskLogs() = "tail -n 5000 ${Const.MAGISK_LOG}".suRaw()
|
||||||
|
@ -19,7 +19,7 @@ val redesignModule = module {
|
|||||||
viewModel { FlashViewModel() }
|
viewModel { FlashViewModel() }
|
||||||
viewModel { HideViewModel(get()) }
|
viewModel { HideViewModel(get()) }
|
||||||
viewModel { HomeViewModel(get()) }
|
viewModel { HomeViewModel(get()) }
|
||||||
viewModel { LogViewModel() }
|
viewModel { LogViewModel(get()) }
|
||||||
viewModel { ModuleViewModel(get(), get(), get()) }
|
viewModel { ModuleViewModel(get(), get(), get()) }
|
||||||
viewModel { RequestViewModel() }
|
viewModel { RequestViewModel() }
|
||||||
viewModel { SafetynetViewModel(get()) }
|
viewModel { SafetynetViewModel(get()) }
|
||||||
|
@ -18,3 +18,10 @@ val timeFormatFull by lazy { SimpleDateFormat("yyyy/MM/dd_HH:mm:ss", currentLoca
|
|||||||
val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", currentLocale) }
|
val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", currentLocale) }
|
||||||
val timeFormatMedium by lazy { DateFormat.getDateInstance(DateFormat.MEDIUM, currentLocale) }
|
val timeFormatMedium by lazy { DateFormat.getDateInstance(DateFormat.MEDIUM, currentLocale) }
|
||||||
val timeFormatTime by lazy { SimpleDateFormat("h:mm a", currentLocale) }
|
val timeFormatTime by lazy { SimpleDateFormat("h:mm a", currentLocale) }
|
||||||
|
val timeDateFormat by lazy {
|
||||||
|
DateFormat.getDateTimeInstance(
|
||||||
|
DateFormat.DEFAULT,
|
||||||
|
DateFormat.DEFAULT,
|
||||||
|
currentLocale
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package com.topjohnwu.magisk.model.entity.recycler
|
package com.topjohnwu.magisk.model.entity.recycler
|
||||||
|
|
||||||
|
import androidx.databinding.Bindable
|
||||||
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||||
|
import com.topjohnwu.magisk.extensions.timeDateFormat
|
||||||
import com.topjohnwu.magisk.extensions.timeFormatMedium
|
import com.topjohnwu.magisk.extensions.timeFormatMedium
|
||||||
import com.topjohnwu.magisk.extensions.toTime
|
import com.topjohnwu.magisk.extensions.toTime
|
||||||
import com.topjohnwu.magisk.extensions.toggle
|
import com.topjohnwu.magisk.extensions.toggle
|
||||||
@ -75,3 +78,36 @@ class MagiskLogRvItem : ComparableRvItem<MagiskLogRvItem>() {
|
|||||||
|
|
||||||
override fun itemSameAs(other: MagiskLogRvItem): Boolean = false
|
override fun itemSameAs(other: MagiskLogRvItem): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
class LogItem(val item: MagiskLog) : ObservableItem<LogItem>() {
|
||||||
|
|
||||||
|
override val layoutRes = R.layout.item_log_access_md2
|
||||||
|
|
||||||
|
val date = item.date.time.toTime(timeDateFormat)
|
||||||
|
var isTop = false
|
||||||
|
@Bindable get
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
notifyChange(BR.top)
|
||||||
|
}
|
||||||
|
var isBottom = false
|
||||||
|
@Bindable get
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
notifyChange(BR.bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun itemSameAs(other: LogItem) = item.appName == other.item.appName
|
||||||
|
|
||||||
|
override fun contentSameAs(other: LogItem) = item.fromUid == other.item.fromUid &&
|
||||||
|
item.toUid == other.item.toUid &&
|
||||||
|
item.fromPid == other.item.fromPid &&
|
||||||
|
item.packageName == other.item.packageName &&
|
||||||
|
item.command == other.item.command &&
|
||||||
|
item.action == other.item.action &&
|
||||||
|
item.date == other.item.date &&
|
||||||
|
isTop == other.isTop &&
|
||||||
|
isBottom == other.isBottom
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.redesign.log
|
package com.topjohnwu.magisk.redesign.log
|
||||||
|
|
||||||
|
import android.graphics.Insets
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
import com.topjohnwu.magisk.redesign.compat.CompatFragment
|
||||||
@ -10,10 +11,14 @@ class LogFragment : CompatFragment<LogViewModel, FragmentLogMd2Binding>() {
|
|||||||
override val layoutRes = R.layout.fragment_log_md2
|
override val layoutRes = R.layout.fragment_log_md2
|
||||||
override val viewModel by viewModel<LogViewModel>()
|
override val viewModel by viewModel<LogViewModel>()
|
||||||
|
|
||||||
|
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
|
||||||
activity.title = resources.getString(R.string.section_log)
|
activity.title = resources.getString(R.string.section_log)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPreBind(binding: FragmentLogMd2Binding) = Unit
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,33 @@
|
|||||||
package com.topjohnwu.magisk.redesign.log
|
package com.topjohnwu.magisk.redesign.log
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.BR
|
||||||
|
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||||
|
import com.topjohnwu.magisk.extensions.subscribeK
|
||||||
|
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
||||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||||
|
import com.topjohnwu.magisk.redesign.home.itemBindingOf
|
||||||
|
import com.topjohnwu.magisk.redesign.superuser.diffListOf
|
||||||
|
|
||||||
class LogViewModel : CompatViewModel()
|
class LogViewModel(
|
||||||
|
private val repo: LogRepository
|
||||||
|
) : CompatViewModel() {
|
||||||
|
|
||||||
|
val items = diffListOf<LogItem>()
|
||||||
|
val itemBinding = itemBindingOf<LogItem> {
|
||||||
|
it.bindExtra(BR.viewModel, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun refresh() = repo.fetchLogsNowrap()
|
||||||
|
.map { it.map { LogItem(it) } }
|
||||||
|
.map { it to items.calculateDiff(it) }
|
||||||
|
.subscribeK {
|
||||||
|
items.firstOrNull()?.isTop = false
|
||||||
|
items.lastOrNull()?.isBottom = false
|
||||||
|
|
||||||
|
items.update(it.first, it.second)
|
||||||
|
|
||||||
|
items.firstOrNull()?.isTop = true
|
||||||
|
items.lastOrNull()?.isBottom = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
app/src/main/res/drawable/bg_line_bottom_rounded.xml
Normal file
11
app/src/main/res/drawable/bg_line_bottom_rounded.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="?colorSecondary" />
|
||||||
|
<corners android:bottomLeftRadius="2dp" android:bottomRightRadius="2dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</selector>
|
11
app/src/main/res/drawable/bg_line_top_rounded.xml
Normal file
11
app/src/main/res/drawable/bg_line_top_rounded.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="?colorSecondary" />
|
||||||
|
<corners android:topLeftRadius="2dp" android:topRightRadius="2dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</selector>
|
10
app/src/main/res/drawable/ic_close_md2.xml
Normal file
10
app/src/main/res/drawable/ic_close_md2.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?colorOnSurface"
|
||||||
|
android:pathData="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
|
||||||
|
</vector>
|
@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
@ -9,15 +11,19 @@
|
|||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
itemBinding="@{viewModel.itemBinding}"
|
||||||
|
items="@{viewModel.items}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fillViewport="true">
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical"
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
android:paddingStart="@dimen/l1"
|
||||||
android:layout_width="match_parent"
|
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||||
android:layout_height="wrap_content" />
|
android:paddingEnd="@dimen/l1"
|
||||||
|
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||||
</androidx.core.widget.NestedScrollView>
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/item_log_access_md2"
|
||||||
|
tools:paddingTop="40dp" />
|
||||||
|
|
||||||
</layout>
|
</layout>
|
104
app/src/main/res/layout/item_log_access_md2.xml
Normal file
104
app/src/main/res/layout/item_log_access_md2.xml
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<import type="com.topjohnwu.magisk.R" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="item"
|
||||||
|
type="com.topjohnwu.magisk.model.entity.recycler.LogItem" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.topjohnwu.magisk.redesign.log.LogViewModel" />
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="?listPreferredItemHeightSmall"
|
||||||
|
tools:layout_gravity="center">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/log_track_container"
|
||||||
|
bullet="@{item.item.action ? R.drawable.ic_check_md2 : R.drawable.ic_close_md2}"
|
||||||
|
isBottom="@{item.isBottom}"
|
||||||
|
isSelected="@{!item.item.action}"
|
||||||
|
isTop="@{item.isTop}"
|
||||||
|
layout="@layout/item_log_track_md2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/l1"
|
||||||
|
android:paddingTop="@dimen/l_50"
|
||||||
|
android:paddingBottom="@dimen/l_50"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/log_track_container"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/log_app_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{item.item.appName}"
|
||||||
|
android:textAppearance="?appearanceTextBodyNormal"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/log_date"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="@string/app_name" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/log_date"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{item.date}"
|
||||||
|
android:textAppearance="?appearanceTextCaptionVariant"
|
||||||
|
android:textSize="10sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/log_app_details"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/log_app_name"
|
||||||
|
tools:text="06:00 PM, 10 Oct 2019" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/log_app_details"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{String.format(`%s %s`, @string/pid(item.item.fromPid), @string/target_uid(item.item.toUid))}"
|
||||||
|
android:textAppearance="?appearanceTextCaptionVariant"
|
||||||
|
android:textSize="10sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/log_command"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/log_date"
|
||||||
|
tools:text="PID: 7196 Target UID: 0" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/log_command"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:text="@{item.item.command}"
|
||||||
|
android:textAppearance="?appearanceTextCaptionVariant"
|
||||||
|
android:textSize="10sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/log_app_details"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/log_app_details"
|
||||||
|
tools:text="/system/bin/sh" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</layout>
|
72
app/src/main/res/layout/item_log_track_md2.xml
Normal file
72
app/src/main/res/layout/item_log_track_md2.xml
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="isTop"
|
||||||
|
type="Boolean" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="isBottom"
|
||||||
|
type="Boolean" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="bullet"
|
||||||
|
type="Integer" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="isSelected"
|
||||||
|
type="Boolean" />
|
||||||
|
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:layout_gravity="center"
|
||||||
|
tools:minHeight="?listPreferredItemHeightSmall">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/track_top"
|
||||||
|
invisible="@{isTop}"
|
||||||
|
android:layout_width="2dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginBottom="2dp"
|
||||||
|
android:alpha=".3"
|
||||||
|
android:background="@drawable/bg_line_bottom_rounded"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/track_bullet"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/track_bullet"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/track_bullet"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/track_bullet"
|
||||||
|
style="?styleImageSmall"
|
||||||
|
isSelected="@{isSelected}"
|
||||||
|
srcCompat="@{bullet}"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:tint="@color/color_primary_error_transient"
|
||||||
|
tools:srcCompat="@drawable/ic_check_md2" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/track_bottom"
|
||||||
|
invisible="@{isBottom}"
|
||||||
|
android:layout_width="2dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:alpha=".3"
|
||||||
|
android:background="@drawable/bg_line_top_rounded"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/track_bullet"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/track_bullet"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/track_bullet" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</layout>
|
@ -105,7 +105,7 @@
|
|||||||
<style name="Foundation.Default" parent="Foundation.Base">
|
<style name="Foundation.Default" parent="Foundation.Base">
|
||||||
<item name="android:theme">@style/ThemeFoundationMD2.Default</item>
|
<item name="android:theme">@style/ThemeFoundationMD2.Default</item>
|
||||||
<!--setting window background to transparent should reduce overdraw-->
|
<!--setting window background to transparent should reduce overdraw-->
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<!--<item name="android:windowBackground">@android:color/transparent</item>-->
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user