Added new log screen
This commit is contained in:
parent
fbeaad077f
commit
6379108a75
@ -14,8 +14,10 @@ class LogRepository(
|
||||
private val logDao: LogDao
|
||||
) {
|
||||
|
||||
fun fetchLogs() = logDao.fetchAll()
|
||||
.map { it.sortByDescending { it.date.time }; it }
|
||||
fun fetchLogsNowrap() = logDao.fetchAll()
|
||||
.map { it.sortedByDescending { it.date.time } }
|
||||
|
||||
fun fetchLogs() = fetchLogsNowrap()
|
||||
.map { it.wrap() }
|
||||
|
||||
fun fetchMagiskLogs() = "tail -n 5000 ${Const.MAGISK_LOG}".suRaw()
|
||||
|
@ -19,7 +19,7 @@ val redesignModule = module {
|
||||
viewModel { FlashViewModel() }
|
||||
viewModel { HideViewModel(get()) }
|
||||
viewModel { HomeViewModel(get()) }
|
||||
viewModel { LogViewModel() }
|
||||
viewModel { LogViewModel(get()) }
|
||||
viewModel { ModuleViewModel(get(), get(), get()) }
|
||||
viewModel { RequestViewModel() }
|
||||
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 timeFormatMedium by lazy { DateFormat.getDateInstance(DateFormat.MEDIUM, 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
|
||||
|
||||
import androidx.databinding.Bindable
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.timeDateFormat
|
||||
import com.topjohnwu.magisk.extensions.timeFormatMedium
|
||||
import com.topjohnwu.magisk.extensions.toTime
|
||||
import com.topjohnwu.magisk.extensions.toggle
|
||||
@ -74,4 +77,37 @@ class MagiskLogRvItem : ComparableRvItem<MagiskLogRvItem>() {
|
||||
override fun contentSameAs(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
|
||||
|
||||
import android.graphics.Insets
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.FragmentLogMd2Binding
|
||||
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 viewModel by viewModel<LogViewModel>()
|
||||
|
||||
override fun consumeSystemWindowInsets(insets: Insets) = insets
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
activity.title = resources.getString(R.string.section_log)
|
||||
}
|
||||
|
||||
override fun onPreBind(binding: FragmentLogMd2Binding) = Unit
|
||||
|
||||
}
|
@ -1,5 +1,33 @@
|
||||
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.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"?>
|
||||
<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>
|
||||
|
||||
@ -9,15 +11,19 @@
|
||||
|
||||
</data>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
itemBinding="@{viewModel.itemBinding}"
|
||||
items="@{viewModel.items}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@dimen/l1"
|
||||
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||
android:paddingEnd="@dimen/l1"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_log_access_md2"
|
||||
tools:paddingTop="40dp" />
|
||||
|
||||
</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">
|
||||
<item name="android:theme">@style/ThemeFoundationMD2.Default</item>
|
||||
<!--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>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user