From ec6bccc0b5652c679e4152cbfdacb2cc77974e6b Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Tue, 31 Dec 2024 20:32:40 +0800 Subject: [PATCH] Hardware monitor --- .../com/bintianqi/owndroid/MainActivity.kt | 2 + .../java/com/bintianqi/owndroid/dpm/System.kt | 91 ++++++++++++++++++- app/src/main/res/values-ru/strings.xml | 14 ++- app/src/main/res/values-tr/strings.xml | 14 ++- app/src/main/res/values-zh-rCN/strings.xml | 13 ++- app/src/main/res/values/strings.xml | 13 ++- 6 files changed, 142 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index df100ae..c0b9a60 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -77,6 +77,7 @@ import com.bintianqi.owndroid.dpm.DeviceOwner import com.bintianqi.owndroid.dpm.DisableAccountManagement import com.bintianqi.owndroid.dpm.DisableKeyguardFeatures import com.bintianqi.owndroid.dpm.FRPPolicy +import com.bintianqi.owndroid.dpm.HardwareMonitor import com.bintianqi.owndroid.dpm.InstallSystemUpdate import com.bintianqi.owndroid.dpm.IntentFilter import com.bintianqi.owndroid.dpm.Keyguard @@ -222,6 +223,7 @@ fun Home(activity: FragmentActivity, vm: MyViewModel) { composable(route = "System") { SystemManage(navCtrl) } composable(route = "SystemOptions") { SystemOptions(navCtrl) } composable(route = "Keyguard") { Keyguard(navCtrl) } + composable(route = "HardwareMonitor") { HardwareMonitor(navCtrl) } composable(route = "ChangeTime") { ChangeTime(navCtrl) } composable(route = "ChangeTimeZone") { ChangeTimeZone(navCtrl) } composable(route = "PermissionPolicy") { PermissionPolicy(navCtrl) } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt index 680f5f9..8957821 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt @@ -37,10 +37,12 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Build.VERSION +import android.os.HardwarePropertiesManager import android.os.UserManager import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts +import androidx.annotation.RequiresApi import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize import androidx.compose.foundation.clickable @@ -78,6 +80,7 @@ import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow +import androidx.compose.material3.Slider import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -87,9 +90,11 @@ import androidx.compose.material3.rememberTimePickerState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -128,6 +133,7 @@ import java.io.ByteArrayOutputStream import java.util.Date import java.util.TimeZone import java.util.concurrent.Executors +import kotlin.math.roundToLong @SuppressLint("NewApi") @Composable @@ -146,6 +152,8 @@ fun SystemManage(navCtrl: NavHostController) { FunctionItem(R.string.options, icon = R.drawable.tune_fill0) { navCtrl.navigate("SystemOptions") } } FunctionItem(R.string.keyguard, icon = R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("Keyguard") } + if(VERSION.SDK_INT >= 24 && deviceOwner && !dhizuku) + FunctionItem(R.string.hardware_monitor, icon = R.drawable.memory_fill0) { navCtrl.navigate("HardwareMonitor") } if(VERSION.SDK_INT >= 24 && deviceOwner) { FunctionItem(R.string.reboot, icon = R.drawable.restart_alt_fill0) { dialog = 1 } } @@ -338,7 +346,7 @@ fun Keyguard(navCtrl: NavHostController) { var flag by remember { mutableIntStateOf(0) } if(VERSION.SDK_INT >= 26 && profileOwner && dpm.isManagedProfile(receiver)) { CheckBoxItem( - R.string.evict_credential_encryptoon_key, + R.string.evict_credential_encryption_key, flag and FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY != 0 ) { flag = flag xor FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY } Spacer(Modifier.padding(vertical = 2.dp)) @@ -358,6 +366,87 @@ fun Keyguard(navCtrl: NavHostController) { } } +@OptIn(ExperimentalMaterial3Api::class) +@RequiresApi(24) +@Composable +fun HardwareMonitor(navCtrl: NavHostController) { + val context = LocalContext.current + val hpm = context.getSystemService(HardwarePropertiesManager::class.java) + var refreshInterval by remember { mutableFloatStateOf(1F) } + val refreshIntervalMs = (refreshInterval * 1000).roundToLong() + val temperatures = remember { mutableStateMapOf>() } + val tempTypeMap = mapOf( + HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU to R.string.cpu_temp, + HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU to R.string.gpu_temp, + HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY to R.string.battery_temp, + HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN to R.string.skin_temp + ) + val cpuUsages = remember { mutableStateListOf>() } + val fanSpeeds = remember { mutableStateListOf() } + fun refresh() { + cpuUsages.clear() + cpuUsages.addAll(hpm.cpuUsages.map { it.active to it.total }) + temperatures.clear() + tempTypeMap.forEach { + temperatures += it.key to hpm.getDeviceTemperatures(it.key, HardwarePropertiesManager.TEMPERATURE_CURRENT).toList() + } + fanSpeeds.clear() + fanSpeeds.addAll(hpm.fanSpeeds.toList()) + } + LaunchedEffect(Unit) { + while(true) { + refresh() + delay(refreshIntervalMs) + } + } + MyScaffold(R.string.hardware_monitor, 8.dp, navCtrl, false) { + Text(stringResource(R.string.refresh_interval), style = typography.titleLarge, modifier = Modifier.padding(vertical = 4.dp)) + Slider(refreshInterval, { refreshInterval = it }, valueRange = 0.5F..2F, steps = 14) + Text("${refreshIntervalMs}ms") + Spacer(Modifier.padding(vertical = 10.dp)) + temperatures.forEach { tempMapItem -> + Text(stringResource(tempTypeMap[tempMapItem.key]!!), style = typography.titleLarge, modifier = Modifier.padding(vertical = 4.dp)) + if(tempMapItem.value.isEmpty()) { + Text(stringResource(R.string.unsupported)) + } else { + tempMapItem.value.forEachIndexed { index, temp -> + Row(modifier = Modifier.padding(vertical = 4.dp)) { + Text(index.toString(), style = typography.titleMedium, modifier = Modifier.padding(start = 8.dp, end = 12.dp)) + Text(if(temp == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) stringResource(R.string.undefined) else temp.toString()) + } + } + } + Spacer(Modifier.padding(vertical = 10.dp)) + } + Text(stringResource(R.string.cpu_usages), style = typography.titleLarge, modifier = Modifier.padding(vertical = 4.dp)) + if(cpuUsages.isEmpty()) { + Text(stringResource(R.string.unsupported)) + } else { + cpuUsages.forEachIndexed { index, usage -> + Row(modifier = Modifier.padding(vertical = 4.dp)) { + Text(index.toString(), style = typography.titleMedium, modifier = Modifier.padding(start = 8.dp, end = 12.dp)) + Column { + Text(stringResource(R.string.active) + ": " + usage.first + "ms") + Text(stringResource(R.string.total) + ": " + usage.second + "ms") + } + } + } + } + Spacer(Modifier.padding(vertical = 10.dp)) + Text(stringResource(R.string.fan_speeds), style = typography.titleLarge, modifier = Modifier.padding(vertical = 4.dp)) + if(fanSpeeds.isEmpty()) { + Text(stringResource(R.string.unsupported)) + } else { + fanSpeeds.forEachIndexed { index, speed -> + Row(modifier = Modifier.padding(vertical = 4.dp)) { + Text(index.toString(), style = typography.titleMedium, modifier = Modifier.padding(start = 8.dp, end = 12.dp)) + Text("$speed RPM") + } + } + } + } +} + @OptIn(ExperimentalMaterial3Api::class) @SuppressLint("NewApi") @Composable diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 376bc56..5cde12b 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -136,7 +136,19 @@ Отключить USB-сигнал Блокировка экрана Заблокировать экран сейчас - Удалить ключ шифрования учетных данных + Удалить ключ шифрования учетных данных + + Hardware monitor + Refresh interval + CPU temperatures + GPU temperatures + Battery temperatures + Skin temperatures + Undefined + CPU usages + Active + Total + Fan speeds Отчет об ошибке Запросить отчет об ошибке? Перезагрузить diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index f376da7..96bfcc3 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -137,7 +137,19 @@ USB sinyali Ekran kilidi Ekranı şimdi kilitle - Kimlik doğrulama şifreleme anahtarını çıkar + Kimlik doğrulama şifreleme anahtarını çıkar + + Hardware monitor + Refresh interval + CPU temperatures + GPU temperatures + Battery temperatures + Skin temperatures + Undefined + CPU usages + Active + Total + Fan speeds Hata raporu Hata raporu iste? Yeniden başlat diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e2085f3..bce5a97 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -131,7 +131,18 @@ 禁用USB信号 锁屏 立即锁屏 - 移除凭证加密密钥 + 移除凭证加密密钥 + 硬件监视器 + 刷新间隔 + CPU温度 + GPU温度 + 电池温度 + 表面温度 + 未定义 + CPU使用情况 + 活动 + 总计 + Fan speeds 错误报告 请求错误报告? 重启 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1d9ab20..f54c1a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -145,7 +145,18 @@ Disable USB signal Keyguard Lock screen now - Evict credential encryption key + Evict credential encryption key + Hardware monitor + Refresh interval + CPU temperatures + GPU temperatures + Battery temperatures + Skin temperatures + Undefined + CPU usages + Active + Total + Fan speeds Bug report Request bug report? Reboot