Added device info card

This commit is contained in:
Viktor De Pasquale 2019-10-26 20:59:30 +02:00
parent da707afa3f
commit a70c0174e1
8 changed files with 281 additions and 9 deletions

View File

@ -121,6 +121,7 @@ object Config : PreferenceModel, DBConfig {
var suReAuth by preference(Key.SU_REAUTH, false) var suReAuth by preference(Key.SU_REAUTH, false)
var checkUpdate by preference(Key.CHECK_UPDATES, true) var checkUpdate by preference(Key.CHECK_UPDATES, true)
var magiskHide by preference(Key.MAGISKHIDE, true) var magiskHide by preference(Key.MAGISKHIDE, true)
@JvmStatic
var coreOnly by preference(Key.COREONLY, false) var coreOnly by preference(Key.COREONLY, false)
var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false) var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false)

View File

@ -24,8 +24,10 @@ import com.topjohnwu.magisk.utils.DynamicClassLoader
import com.topjohnwu.magisk.utils.FileProvider import com.topjohnwu.magisk.utils.FileProvider
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.currentLocale import com.topjohnwu.magisk.utils.currentLocale
import com.topjohnwu.superuser.ShellUtils
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.text.SimpleDateFormat
import java.util.* import java.util.*
val packageName: String get() = get<Context>().packageName val packageName: String get() = get<Context>().packageName
@ -281,3 +283,32 @@ fun Context.unwrap(): Context {
fun Context.hasPermissions(vararg permissions: String) = permissions.all { fun Context.hasPermissions(vararg permissions: String) = permissions.all {
ContextCompat.checkSelfPermission(this, it) == PERMISSION_GRANTED ContextCompat.checkSelfPermission(this, it) == PERMISSION_GRANTED
} }
private val securityLevelFormatter get() = SimpleDateFormat("yyyy-MM-dd", currentLocale)
/** Friendly reminder to seek newer roms or install oem updates. */
val isDeviceSecure: Boolean
get() {
val latestPermittedTime = Calendar.getInstance().apply {
time = securityLevelDate
add(Calendar.MONTH, 2)
}.time.time
return now in 0..latestPermittedTime
}
val securityLevelDate get() = securityLevelFormatter.parseOrNull(securityLevel) ?: Date(0)
val securityLevel
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Build.VERSION.SECURITY_PATCH
} else {
null
} ?: "1970-01-01" //never
val isSAR
get() = ShellUtils
.fastCmd("grep_prop ro.build.system_root_image")
.let { it.isNotEmpty() && it.toBoolean() }
val isAB
get() = ShellUtils
.fastCmd("grep_prop ro.build.ab_update")
.let { it.isNotEmpty() && it.toBoolean() }

View File

@ -3,9 +3,11 @@ package com.topjohnwu.magisk.extensions
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import androidx.core.net.toFile import androidx.core.net.toFile
import timber.log.Timber
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
@ -101,3 +103,6 @@ fun Locale.toLangTag(): String {
return tag.toString() return tag.toString()
} }
} }
fun SimpleDateFormat.parseOrNull(date: String) =
runCatching { parse(date) }.onFailure { Timber.e(it) }.getOrNull()

View File

@ -12,3 +12,5 @@ fun reboot(reason: String = if (Info.recovery) "recovery" else "") {
fun File.suOutputStream() = SuFileOutputStream(this) fun File.suOutputStream() = SuFileOutputStream(this)
fun File.suInputStream() = SuFileInputStream(this) fun File.suInputStream() = SuFileInputStream(this)
val hasRoot get() = Shell.rootAccess()

View File

@ -62,6 +62,7 @@ class HomeViewModel(
val stateMagiskExpanded = KObservableField(false) val stateMagiskExpanded = KObservableField(false)
val stateManagerExpanded = KObservableField(false) val stateManagerExpanded = KObservableField(false)
val stateDeviceExpanded = KObservableField(false)
val stateHideManagerName = R.string.manager.res().let { val stateHideManagerName = R.string.manager.res().let {
if (!statePackageOriginal) { if (!statePackageOriginal) {

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="M17,19V5H7V19H17M17,1A2,2 0 0,1 19,3V21A2,2 0 0,1 17,23H7C5.89,23 5,22.1 5,21V3C5,1.89 5.89,1 7,1H17M9,7H15V9H9V7M9,11H13V13H9V11Z" />
</vector>

View File

@ -5,14 +5,22 @@
<data> <data>
<import type="android.os.Build" />
<import type="com.topjohnwu.magisk.R" /> <import type="com.topjohnwu.magisk.R" />
<import type="com.topjohnwu.magisk.Info" /> <import type="com.topjohnwu.magisk.Info" />
<import type="com.topjohnwu.magisk.Config" />
<import type="com.topjohnwu.magisk.BuildConfig" /> <import type="com.topjohnwu.magisk.BuildConfig" />
<import type="com.topjohnwu.magisk.ui.home.MagiskState" /> <import type="com.topjohnwu.magisk.ui.home.MagiskState" />
<import type="com.topjohnwu.magisk.extensions.XAndroidKt" />
<import type="com.topjohnwu.magisk.extensions.XSUKt" />
<variable <variable
name="viewModel" name="viewModel"
type="com.topjohnwu.magisk.redesign.home.HomeViewModel" /> type="com.topjohnwu.magisk.redesign.home.HomeViewModel" />
@ -31,13 +39,204 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical"> android:orientation="vertical"
android:paddingTop="@dimen/l1">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipToPadding="false" android:clipToPadding="false">
android:paddingTop="@dimen/l1">
<com.google.android.material.card.MaterialCardView
android:id="@+id/home_device_wrapper"
style="?styleCardVariant"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
android:onClick="@{() -> viewModel.toggle(viewModel.stateDeviceExpanded)}"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_card"
android:orientation="horizontal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<View
gone="@{XAndroidKt.isDeviceSecure()}"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha=".3"
android:background="?colorError"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/home_device_icon"
style="?styleIconPrimary"
android:layout_marginStart="@dimen/l_50"
android:layout_marginTop="@dimen/l1"
android:layout_marginBottom="@dimen/l1"
android:background="@null"
android:padding="@dimen/l_50"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_device"
app:tint="@color/color_primary_error_transient" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l_50"
android:layout_marginEnd="@dimen/l1"
android:gravity="start|center_vertical"
android:text="@{Build.MANUFACTURER}"
android:textAppearance="?appearanceTextTitleNormal"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/home_device_product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@+id/home_device_icon"
app:layout_constraintTop_toTopOf="@+id/home_device_icon"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Google" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_product"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Build.DEVICE ?? Build.PRODUCT}"
android:textAppearance="?appearanceTextCaptionVariant"
app:layout_constraintBottom_toTopOf="@+id/home_device_board"
app:layout_constraintEnd_toEndOf="@+id/home_device_title"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="@+id/home_device_title"
app:layout_constraintTop_toBottomOf="@+id/home_device_title"
tools:text="Pixel 4" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_board"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Build.BOARD}"
android:textAppearance="?appearanceTextCaptionVariant"
app:layout_constraintBottom_toBottomOf="@+id/home_device_icon"
app:layout_constraintEnd_toEndOf="@+id/home_device_title"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="@+id/home_device_title"
app:layout_constraintTop_toBottomOf="@+id/home_device_product"
tools:text="flame" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
goneUnless="@{viewModel.stateDeviceExpanded}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/l1"
android:visibility="gone"
tools:visibility="visible">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_security_title"
style="@style/W.Home.Extra.Title"
android:text="@string/home_device_security"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_security_value"
style="@style/W.Home.Extra.Value"
android:text="@{XAndroidKt.isDeviceSecure() ? @string/home_device_security_secure : @string/home_device_security_outdated}"
app:layout_constraintBottom_toBottomOf="@+id/home_device_extra_security_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/home_device_extra_security_title"
app:layout_constraintTop_toTopOf="@+id/home_device_extra_security_title"
tools:text="@string/home_device_security_secure" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_version_title"
style="@style/W.Home.Extra.Title"
android:text="@string/home_device_system"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_device_extra_security_title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_version_value"
style="@style/W.Home.Extra.Value"
android:text="@{Build.VERSION.RELEASE}"
app:layout_constraintBottom_toBottomOf="@+id/home_device_extra_version_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/home_device_extra_version_title"
app:layout_constraintTop_toTopOf="@+id/home_device_extra_version_title"
tools:text="10" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_build_style_title"
style="@style/W.Home.Extra.Title"
android:text="@string/home_device_build_style"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_device_extra_version_title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_build_style_value"
style="@style/W.Home.Extra.Value"
android:text="@{XAndroidKt.isAB ? @string/yes : @string/no}"
app:layout_constraintBottom_toBottomOf="@+id/home_device_extra_build_style_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/home_device_extra_build_style_title"
app:layout_constraintTop_toTopOf="@+id/home_device_extra_build_style_title"
tools:text="Yes" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_build_type_title"
style="@style/W.Home.Extra.Title"
android:text="@string/home_device_build_type"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_device_extra_build_style_title" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_device_extra_build_type_value"
style="@style/W.Home.Extra.Value"
android:text="@{XAndroidKt.isSAR ? @string/yes : @string/no}"
app:layout_constraintBottom_toBottomOf="@+id/home_device_extra_build_type_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/home_device_extra_build_type_title"
app:layout_constraintTop_toTopOf="@+id/home_device_extra_build_type_title"
tools:text="Yes" />
<!--todo(topjohnwu) Add device info here-->
<!--Copy & paste "..._title" and "..._value"-->
<!--Change ids to match "home_device_extra_*info-type*_value" or "..._title"-->
<!--Fix constraints by replacing ids (views are always bound to "title")-->
<androidx.constraintlayout.widget.Group
goneUnless="@{XSUKt.hasRoot}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="home_device_extra_build_style_title,home_device_extra_build_style_value,home_device_extra_build_type_title,home_device_extra_build_type_value" />
<!--todo(topjohnwu) If info requires root add id to this group-->
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/home_magisk_wrapper" android:id="@+id/home_magisk_wrapper"
@ -45,12 +244,15 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1" android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1"
android:maxWidth="200dp" android:maxWidth="200dp"
android:onClick="@{() -> viewModel.toggle(viewModel.stateMagiskExpanded)}" android:onClick="@{() -> viewModel.toggle(viewModel.stateMagiskExpanded)}"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="@+id/home_manager_wrapper" app:layout_constraintEnd_toStartOf="@+id/home_manager_wrapper"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toBottomOf="@+id/home_device_wrapper"
app:layout_constraintWidth_max="200dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -180,6 +382,7 @@
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_magisk_extra_mode_value" android:id="@+id/home_magisk_extra_mode_value"
style="@style/W.Home.Extra.Value" style="@style/W.Home.Extra.Value"
android:text="@{Config.coreOnly ? @string/home_extra_mode_safe : @string/home_extra_mode_normal}"
app:layout_constraintBottom_toBottomOf="@+id/home_magisk_extra_mode_title" app:layout_constraintBottom_toBottomOf="@+id/home_magisk_extra_mode_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/home_magisk_extra_mode_title" app:layout_constraintStart_toEndOf="@+id/home_magisk_extra_mode_title"
@ -193,6 +396,9 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_magisk_extra_mode_title" /> app:layout_constraintTop_toBottomOf="@+id/home_magisk_extra_mode_title" />
<!--todo(topjohnwu) fix connection type-->
<!--don't forget to bind verbose values to proper resources-->
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_magisk_extra_connection_value" android:id="@+id/home_magisk_extra_connection_value"
style="@style/W.Home.Extra.Value" style="@style/W.Home.Extra.Value"
@ -269,14 +475,17 @@
style="?styleCardVariant" style="?styleCardVariant"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.toggle(viewModel.stateManagerExpanded)}"
android:layout_marginStart="@dimen/l1" android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1"
android:layout_marginEnd="@dimen/l1" android:layout_marginEnd="@dimen/l1"
android:maxWidth="200dp" android:maxWidth="200dp"
android:onClick="@{() -> viewModel.toggle(viewModel.stateManagerExpanded)}"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@+id/home_magisk_wrapper" app:layout_constraintStart_toEndOf="@+id/home_magisk_wrapper"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toBottomOf="@+id/home_device_wrapper"
app:layout_constraintWidth_max="200dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -400,6 +609,8 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/home_manager_extra_code_title" /> app:layout_constraintTop_toBottomOf="@+id/home_manager_extra_code_title" />
<!--todo(diareuse) Info.isRunningAsStub ? @string/home_extra_mode_stub : @string/home_extra_mode_normal-->
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/home_manager_extra_mode_value" android:id="@+id/home_manager_extra_mode_value"
style="@style/W.Home.Extra.Value" style="@style/W.Home.Extra.Value"

View File

@ -5,6 +5,9 @@
<string name="magisk">Magisk</string> <string name="magisk">Magisk</string>
<string name="system">System</string> <string name="system">System</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="no_connection">No connection available</string> <string name="no_connection">No connection available</string>
<string name="section_home">Home</string> <string name="section_home">Home</string>
@ -28,6 +31,14 @@
<string name="home_item_source">Source</string> <string name="home_item_source">Source</string>
<string name="home_item_xda">XDA</string> <string name="home_item_xda">XDA</string>
<string name="home_device_security">Security</string>
<string name="home_device_system">System</string>
<string name="home_device_build_style">A/B</string>
<string name="home_device_build_type">SAR</string>
<string name="home_device_security_secure">Secure</string>
<string name="home_device_security_outdated">Outdated</string>
<string name="home_extra_version">Version</string> <string name="home_extra_version">Version</string>
<string name="home_extra_code">Code</string> <string name="home_extra_code">Code</string>
<string name="home_extra_mode">Mode</string> <string name="home_extra_mode">Mode</string>