manager: Refactor the way information is fetched in the home screen to avoid null pointers
- add an auto-refresh cache feature
This commit is contained in:
@@ -726,7 +726,7 @@ private fun InfoCard(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 活跃管理器
|
// 活跃管理器
|
||||||
if (systemInfo.isDynamicSignEnabled && systemInfo.managersList != null) {
|
if (!isSimpleMode && systemInfo.isDynamicSignEnabled && systemInfo.managersList != null) {
|
||||||
val signatureMap = systemInfo.managersList.managers.groupBy { it.signatureIndex }
|
val signatureMap = systemInfo.managersList.managers.groupBy { it.signatureIndex }
|
||||||
|
|
||||||
val managersText = buildString {
|
val managersText = buildString {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.dergoogler.mmrl.platform.Platform.Companion.context
|
import com.dergoogler.mmrl.platform.Platform.Companion.context
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.JsonSyntaxException
|
||||||
import com.sukisu.ultra.KernelVersion
|
import com.sukisu.ultra.KernelVersion
|
||||||
import com.sukisu.ultra.Natives
|
import com.sukisu.ultra.Natives
|
||||||
import com.sukisu.ultra.getKernelVersion
|
import com.sukisu.ultra.getKernelVersion
|
||||||
@@ -31,6 +32,8 @@ class HomeViewModel : ViewModel() {
|
|||||||
private const val KEY_SYSTEM_INFO = "system_info"
|
private const val KEY_SYSTEM_INFO = "system_info"
|
||||||
private const val KEY_VERSION_INFO = "version_info"
|
private const val KEY_VERSION_INFO = "version_info"
|
||||||
private const val KEY_LAST_UPDATE = "last_update_time"
|
private const val KEY_LAST_UPDATE = "last_update_time"
|
||||||
|
private const val KEY_ERROR_COUNT = "error_count"
|
||||||
|
private const val MAX_ERROR_COUNT = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// 系统状态
|
// 系统状态
|
||||||
@@ -93,16 +96,67 @@ class HomeViewModel : ViewModel() {
|
|||||||
var showKpmInfo by mutableStateOf(false)
|
var showKpmInfo by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private fun clearAllCache() {
|
||||||
|
try {
|
||||||
|
prefs.edit { clear() }
|
||||||
|
Log.i(TAG, "All cache cleared successfully")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error clearing cache", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetToDefaults() {
|
||||||
|
systemStatus = SystemStatus()
|
||||||
|
systemInfo = SystemInfo()
|
||||||
|
latestVersionInfo = LatestVersionInfo()
|
||||||
|
isSimpleMode = false
|
||||||
|
isKernelSimpleMode = false
|
||||||
|
isHideVersion = false
|
||||||
|
isHideOtherInfo = false
|
||||||
|
isHideSusfsStatus = false
|
||||||
|
isHideLinkCard = false
|
||||||
|
showKpmInfo = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleError(error: Exception, operation: String) {
|
||||||
|
Log.e(TAG, "Error in $operation", error)
|
||||||
|
|
||||||
|
val errorCount = prefs.getInt(KEY_ERROR_COUNT, 0)
|
||||||
|
val newErrorCount = errorCount + 1
|
||||||
|
|
||||||
|
if (newErrorCount >= MAX_ERROR_COUNT) {
|
||||||
|
Log.w(TAG, "Too many errors ($newErrorCount), clearing cache and resetting")
|
||||||
|
clearAllCache()
|
||||||
|
resetToDefaults()
|
||||||
|
} else {
|
||||||
|
prefs.edit {
|
||||||
|
putInt(KEY_ERROR_COUNT, newErrorCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String?.orSafe(default: String = ""): String {
|
||||||
|
return if (this.isNullOrBlank()) default else this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T, R> Pair<T?, R?>?.orSafe(default: Pair<T, R>): Pair<T, R> {
|
||||||
|
return if (this?.first == null || this.second == null) default else Pair(this.first!!, this.second!!)
|
||||||
|
}
|
||||||
|
|
||||||
fun loadUserSettings(context: Context) {
|
fun loadUserSettings(context: Context) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
try {
|
||||||
isSimpleMode = prefs.getBoolean("is_simple_mode", false)
|
val settingsPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||||
isKernelSimpleMode = prefs.getBoolean("is_kernel_simple_mode", false)
|
isSimpleMode = settingsPrefs.getBoolean("is_simple_mode", false)
|
||||||
isHideVersion = prefs.getBoolean("is_hide_version", false)
|
isKernelSimpleMode = settingsPrefs.getBoolean("is_kernel_simple_mode", false)
|
||||||
isHideOtherInfo = prefs.getBoolean("is_hide_other_info", false)
|
isHideVersion = settingsPrefs.getBoolean("is_hide_version", false)
|
||||||
isHideSusfsStatus = prefs.getBoolean("is_hide_susfs_status", false)
|
isHideOtherInfo = settingsPrefs.getBoolean("is_hide_other_info", false)
|
||||||
isHideLinkCard = prefs.getBoolean("is_hide_link_card", false)
|
isHideSusfsStatus = settingsPrefs.getBoolean("is_hide_susfs_status", false)
|
||||||
showKpmInfo = prefs.getBoolean("show_kpm_info", false)
|
isHideLinkCard = settingsPrefs.getBoolean("is_hide_link_card", false)
|
||||||
|
showKpmInfo = settingsPrefs.getBoolean("show_kpm_info", false)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
handleError(e, "loadUserSettings")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,25 +164,58 @@ class HomeViewModel : ViewModel() {
|
|||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
loadCachedData()
|
loadCachedData()
|
||||||
|
// 成功加载后重置错误计数
|
||||||
|
prefs.edit {
|
||||||
|
putInt(KEY_ERROR_COUNT, 0)
|
||||||
|
}
|
||||||
} catch(e: Exception) {
|
} catch(e: Exception) {
|
||||||
Log.e(TAG, "Error when reading cached data", e)
|
handleError(e, "initializeData")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCachedData() {
|
private fun loadCachedData() {
|
||||||
prefs.getString(KEY_SYSTEM_STATUS, null)?.let {
|
try {
|
||||||
systemStatus = gson.fromJson(it, SystemStatus::class.java)
|
prefs.getString(KEY_SYSTEM_STATUS, null)?.let { statusJson ->
|
||||||
|
try {
|
||||||
|
val cachedStatus = gson.fromJson(statusJson, SystemStatus::class.java)
|
||||||
|
if (cachedStatus != null) {
|
||||||
|
systemStatus = cachedStatus
|
||||||
}
|
}
|
||||||
prefs.getString(KEY_SYSTEM_INFO, null)?.let {
|
} catch (e: JsonSyntaxException) {
|
||||||
systemInfo = gson.fromJson(it, SystemInfo::class.java)
|
Log.w(TAG, "Invalid system status JSON, using defaults", e)
|
||||||
}
|
}
|
||||||
prefs.getString(KEY_VERSION_INFO, null)?.let {
|
}
|
||||||
latestVersionInfo = gson.fromJson(it, LatestVersionInfo::class.java)
|
|
||||||
|
prefs.getString(KEY_SYSTEM_INFO, null)?.let { infoJson ->
|
||||||
|
try {
|
||||||
|
val cachedInfo = gson.fromJson(infoJson, SystemInfo::class.java)
|
||||||
|
if (cachedInfo != null) {
|
||||||
|
systemInfo = cachedInfo
|
||||||
|
}
|
||||||
|
} catch (e: JsonSyntaxException) {
|
||||||
|
Log.w(TAG, "Invalid system info JSON, using defaults", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.getString(KEY_VERSION_INFO, null)?.let { versionJson ->
|
||||||
|
try {
|
||||||
|
val cachedVersion = gson.fromJson(versionJson, LatestVersionInfo::class.java)
|
||||||
|
if (cachedVersion != null) {
|
||||||
|
latestVersionInfo = cachedVersion
|
||||||
|
}
|
||||||
|
} catch (e: JsonSyntaxException) {
|
||||||
|
Log.w(TAG, "Invalid version info JSON, using defaults", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error loading cached data", e)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun fetchAndSaveData() {
|
private suspend fun fetchAndSaveData() {
|
||||||
|
try {
|
||||||
fetchSystemStatus()
|
fetchSystemStatus()
|
||||||
fetchSystemInfo()
|
fetchSystemInfo()
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
@@ -137,15 +224,19 @@ class HomeViewModel : ViewModel() {
|
|||||||
putString(KEY_SYSTEM_INFO, gson.toJson(systemInfo))
|
putString(KEY_SYSTEM_INFO, gson.toJson(systemInfo))
|
||||||
putString(KEY_VERSION_INFO, gson.toJson(latestVersionInfo))
|
putString(KEY_VERSION_INFO, gson.toJson(latestVersionInfo))
|
||||||
putLong(KEY_LAST_UPDATE, System.currentTimeMillis())
|
putLong(KEY_LAST_UPDATE, System.currentTimeMillis())
|
||||||
|
putInt(KEY_ERROR_COUNT, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
handleError(e, "fetchAndSaveData")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkForUpdates(context: Context) {
|
fun checkForUpdates(context: Context) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val checkUpdate = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
val settingsPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||||
.getBoolean("check_update", true)
|
val checkUpdate = settingsPrefs.getBoolean("check_update", true)
|
||||||
|
|
||||||
if (checkUpdate) {
|
if (checkUpdate) {
|
||||||
val newVersionInfo = checkNewVersion()
|
val newVersionInfo = checkNewVersion()
|
||||||
@@ -156,7 +247,7 @@ class HomeViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error checking for updates", e)
|
handleError(e, "checkForUpdates")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,7 +258,7 @@ class HomeViewModel : ViewModel() {
|
|||||||
fetchAndSaveData()
|
fetchAndSaveData()
|
||||||
checkForUpdates(context)
|
checkForUpdates(context)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error refreshing data", e)
|
handleError(e, "refreshAllData")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,10 +267,31 @@ class HomeViewModel : ViewModel() {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val kernelVersion = getKernelVersion()
|
val kernelVersion = getKernelVersion()
|
||||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
val isManager = try {
|
||||||
val ksuVersion = if (isManager) Natives.version else null
|
Natives.becomeManager(ksuApp.packageName.orSafe("com.sukisu.ultra"))
|
||||||
val fullVersion = Natives.getFullVersion()
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to become manager", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
val ksuVersion = if (isManager) {
|
||||||
|
try {
|
||||||
|
Natives.version
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get KSU version", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} else null
|
||||||
|
|
||||||
|
val fullVersion = try {
|
||||||
|
Natives.getFullVersion().orSafe("Unknown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get full version", e)
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
val ksuFullVersion = if (isKernelSimpleMode) {
|
val ksuFullVersion = if (isKernelSimpleMode) {
|
||||||
|
try {
|
||||||
val startIndex = fullVersion.indexOf('v')
|
val startIndex = fullVersion.indexOf('v')
|
||||||
if (startIndex >= 0) {
|
if (startIndex >= 0) {
|
||||||
val endIndex = fullVersion.indexOf('-', startIndex)
|
val endIndex = fullVersion.indexOf('-', startIndex)
|
||||||
@@ -193,12 +305,44 @@ class HomeViewModel : ViewModel() {
|
|||||||
} else {
|
} else {
|
||||||
fullVersion
|
fullVersion
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to process full version", e)
|
||||||
|
fullVersion
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fullVersion
|
fullVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
val lkmMode = ksuVersion?.let {
|
val lkmMode = ksuVersion?.let {
|
||||||
if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && kernelVersion.isGKI()) Natives.isLkmMode else null
|
try {
|
||||||
|
if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && kernelVersion.isGKI()) {
|
||||||
|
Natives.isLkmMode
|
||||||
|
} else null
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get LKM mode", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val isRootAvailable = try {
|
||||||
|
rootAvailable()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to check root availability", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
val isKpmConfigured = try {
|
||||||
|
Natives.isKPMEnabled()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to check KPM status", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
val requireNewKernel = try {
|
||||||
|
isManager && Natives.requireNewKernel()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to check kernel requirement", e)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
systemStatus = SystemStatus(
|
systemStatus = SystemStatus(
|
||||||
@@ -207,12 +351,13 @@ class HomeViewModel : ViewModel() {
|
|||||||
ksuFullVersion = ksuFullVersion,
|
ksuFullVersion = ksuFullVersion,
|
||||||
lkmMode = lkmMode,
|
lkmMode = lkmMode,
|
||||||
kernelVersion = kernelVersion,
|
kernelVersion = kernelVersion,
|
||||||
isRootAvailable = rootAvailable(),
|
isRootAvailable = isRootAvailable,
|
||||||
isKpmConfigured = Natives.isKPMEnabled(),
|
isKpmConfigured = isKpmConfigured,
|
||||||
requireNewKernel = isManager && Natives.requireNewKernel()
|
requireNewKernel = requireNewKernel
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error fetching system status", e)
|
Log.e(TAG, "Error fetching system status", e)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,24 +366,61 @@ class HomeViewModel : ViewModel() {
|
|||||||
private suspend fun fetchSystemInfo() {
|
private suspend fun fetchSystemInfo() {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val uname = Os.uname()
|
val uname = try {
|
||||||
val kpmVersion = getKpmVersion()
|
Os.uname()
|
||||||
val suSFS = getSuSFS()
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get uname", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val kpmVersion = try {
|
||||||
|
getKpmVersion().orSafe("Unknown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get kpm version", e)
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
val suSFS = try {
|
||||||
|
getSuSFS().orSafe("Unknown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SuSFS", e)
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
var suSFSVersion = ""
|
var suSFSVersion = ""
|
||||||
var suSFSVariant = ""
|
var suSFSVariant = ""
|
||||||
var suSFSFeatures = ""
|
var suSFSFeatures = ""
|
||||||
var susSUMode = ""
|
var susSUMode = ""
|
||||||
|
|
||||||
if (suSFS == "Supported") {
|
if (suSFS == "Supported") {
|
||||||
suSFSVersion = getSuSFSVersion()
|
suSFSVersion = try {
|
||||||
|
getSuSFSVersion().orSafe("")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SuSFS version", e)
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
if (suSFSVersion.isNotEmpty()) {
|
if (suSFSVersion.isNotEmpty()) {
|
||||||
suSFSVariant = getSuSFSVariant()
|
suSFSVariant = try {
|
||||||
suSFSFeatures = getSuSFSFeatures()
|
getSuSFSVariant().orSafe("")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SuSFS variant", e)
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
suSFSFeatures = try {
|
||||||
|
getSuSFSFeatures().orSafe("")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SuSFS features", e)
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
val isSUS_SU = suSFSFeatures == "CONFIG_KSU_SUSFS_SUS_SU"
|
val isSUS_SU = suSFSFeatures == "CONFIG_KSU_SUSFS_SUS_SU"
|
||||||
if (isSUS_SU) {
|
if (isSUS_SU) {
|
||||||
susSUMode = try {
|
susSUMode = try {
|
||||||
susfsSUS_SU_Mode().toString()
|
susfsSUS_SU_Mode()
|
||||||
} catch (_: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SUS SU mode", e)
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +435,13 @@ class HomeViewModel : ViewModel() {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
val isDynamicSignEnabled = dynamicSignConfig?.isValid() == true
|
val isDynamicSignEnabled = try {
|
||||||
|
dynamicSignConfig?.isValid() == true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to check dynamic sign validity", e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
val managersList = if (isDynamicSignEnabled) {
|
val managersList = if (isDynamicSignEnabled) {
|
||||||
try {
|
try {
|
||||||
Natives.getManagersList()
|
Natives.getManagersList()
|
||||||
@@ -265,39 +453,101 @@ class HomeViewModel : ViewModel() {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val deviceModel = try {
|
||||||
|
getDeviceModel().orSafe("Unknown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get device model", e)
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
val managerVersion = try {
|
||||||
|
getManagerVersion(ksuApp.applicationContext).orSafe(Pair("Unknown", 0L))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get manager version", e)
|
||||||
|
Pair("Unknown", 0L)
|
||||||
|
}
|
||||||
|
|
||||||
|
val seLinuxStatus = try {
|
||||||
|
getSELinuxStatus(context).orSafe("Unknown")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get SELinux status", e)
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
val superuserCount = try {
|
||||||
|
getSuperuserCount()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get superuser count", e)
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleCount = try {
|
||||||
|
getModuleCount()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get module count", e)
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
val kpmModuleCount = try {
|
||||||
|
getKpmModuleCount()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get kpm module count", e)
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
val zygiskImplement = try {
|
||||||
|
getZygiskImplement().orSafe("None")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get Zygisk implement", e)
|
||||||
|
"None"
|
||||||
|
}
|
||||||
|
|
||||||
systemInfo = SystemInfo(
|
systemInfo = SystemInfo(
|
||||||
kernelRelease = uname.release,
|
kernelRelease = uname?.release.orSafe("Unknown"),
|
||||||
androidVersion = Build.VERSION.RELEASE,
|
androidVersion = Build.VERSION.RELEASE.orSafe("Unknown"),
|
||||||
deviceModel = getDeviceModel(),
|
deviceModel = deviceModel,
|
||||||
managerVersion = getManagerVersion(ksuApp.applicationContext),
|
managerVersion = managerVersion,
|
||||||
seLinuxStatus = getSELinuxStatus(context),
|
seLinuxStatus = seLinuxStatus,
|
||||||
kpmVersion = kpmVersion,
|
kpmVersion = kpmVersion,
|
||||||
suSFSStatus = suSFS,
|
suSFSStatus = suSFS,
|
||||||
suSFSVersion = suSFSVersion,
|
suSFSVersion = suSFSVersion,
|
||||||
suSFSVariant = suSFSVariant,
|
suSFSVariant = suSFSVariant,
|
||||||
suSFSFeatures = suSFSFeatures,
|
suSFSFeatures = suSFSFeatures,
|
||||||
susSUMode = susSUMode,
|
susSUMode = susSUMode,
|
||||||
superuserCount = getSuperuserCount(),
|
superuserCount = superuserCount,
|
||||||
moduleCount = getModuleCount(),
|
moduleCount = moduleCount,
|
||||||
kpmModuleCount = getKpmModuleCount(),
|
kpmModuleCount = kpmModuleCount,
|
||||||
managersList = managersList,
|
managersList = managersList,
|
||||||
isDynamicSignEnabled = isDynamicSignEnabled,
|
isDynamicSignEnabled = isDynamicSignEnabled,
|
||||||
zygiskImplement = getZygiskImplement()
|
zygiskImplement = zygiskImplement
|
||||||
)
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error fetching system info", e)
|
Log.e(TAG, "Error fetching system info", e)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeviceInfo(): String {
|
private fun getDeviceInfo(): String {
|
||||||
var manufacturer =
|
return try {
|
||||||
Build.MANUFACTURER[0].uppercaseChar().toString() + Build.MANUFACTURER.substring(1)
|
var manufacturer = Build.MANUFACTURER.orSafe("Unknown")
|
||||||
if (!Build.BRAND.equals(Build.MANUFACTURER, ignoreCase = true)) {
|
manufacturer = manufacturer[0].uppercaseChar().toString() + manufacturer.substring(1)
|
||||||
manufacturer += " " + Build.BRAND[0].uppercaseChar() + Build.BRAND.substring(1)
|
|
||||||
|
val brand = Build.BRAND.orSafe("")
|
||||||
|
if (brand.isNotEmpty() && !brand.equals(Build.MANUFACTURER, ignoreCase = true)) {
|
||||||
|
manufacturer += " " + brand[0].uppercaseChar() + brand.substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val model = Build.MODEL.orSafe("")
|
||||||
|
if (model.isNotEmpty()) {
|
||||||
|
manufacturer += " $model "
|
||||||
|
}
|
||||||
|
|
||||||
|
manufacturer
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get device info", e)
|
||||||
|
"Unknown Device"
|
||||||
}
|
}
|
||||||
manufacturer += " " + Build.MODEL + " "
|
|
||||||
return manufacturer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("PrivateApi")
|
@SuppressLint("PrivateApi")
|
||||||
@@ -313,27 +563,32 @@ class HomeViewModel : ViewModel() {
|
|||||||
)
|
)
|
||||||
var result = getDeviceInfo()
|
var result = getDeviceInfo()
|
||||||
for (key in marketNameKeys) {
|
for (key in marketNameKeys) {
|
||||||
|
try {
|
||||||
val marketName = getMethod.invoke(null, key, "") as String
|
val marketName = getMethod.invoke(null, key, "") as String
|
||||||
if (marketName.isNotEmpty()) {
|
if (marketName.isNotEmpty()) {
|
||||||
result = marketName
|
result = marketName
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Failed to get market name for key: $key", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error getting device model", e)
|
Log.w(TAG, "Error getting device model", e)
|
||||||
getDeviceInfo()
|
getDeviceInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getManagerVersion(context: Context): Pair<String, Long> {
|
private fun getManagerVersion(context: Context): Pair<String, Long> {
|
||||||
return try {
|
return try {
|
||||||
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)!!
|
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
||||||
val versionCode = androidx.core.content.pm.PackageInfoCompat.getLongVersionCode(packageInfo)
|
val versionCode = androidx.core.content.pm.PackageInfoCompat.getLongVersionCode(packageInfo)
|
||||||
Pair(packageInfo.versionName!!, versionCode)
|
val versionName = packageInfo.versionName.orSafe("Unknown")
|
||||||
|
Pair(versionName, versionCode)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Error getting manager version", e)
|
Log.w(TAG, "Error getting manager version", e)
|
||||||
Pair("", 0L)
|
Pair("Unknown", 0L)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user