Added new log screen

This commit is contained in:
Viktor De Pasquale 2019-11-20 22:42:44 +01:00
parent fbeaad077f
commit 6379108a75
13 changed files with 306 additions and 14 deletions

View File

@ -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()

View File

@ -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()) }

View File

@ -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
)
}

View File

@ -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
}

View File

@ -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
} }

View File

@ -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
}
}

View 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>

View 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>

View 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>

View File

@ -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>

View 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>

View 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>

View File

@ -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>