Hardware monitor

This commit is contained in:
BinTianqi
2024-12-31 20:32:40 +08:00
parent 937afe9417
commit ec6bccc0b5
6 changed files with 142 additions and 5 deletions

View File

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

View File

@@ -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<Int, List<Float>>() }
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<Pair<Long, Long>>() }
val fanSpeeds = remember { mutableStateListOf<Float>() }
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

View File

@@ -136,7 +136,19 @@
<string name="disable_usb_signal">Отключить USB-сигнал</string>
<string name="keyguard">Блокировка экрана</string>
<string name="lock_now">Заблокировать экран сейчас</string>
<string name="evict_credential_encryptoon_key">Удалить ключ шифрования учетных данных</string>
<string name="evict_credential_encryption_key">Удалить ключ шифрования учетных данных</string>
<!--TODO: the following 11 strings-->
<string name="hardware_monitor">Hardware monitor</string>
<string name="refresh_interval">Refresh interval</string>
<string name="cpu_temp">CPU temperatures</string>
<string name="gpu_temp">GPU temperatures</string>
<string name="battery_temp">Battery temperatures</string>
<string name="skin_temp">Skin temperatures</string>
<string name="undefined">Undefined</string>
<string name="cpu_usages">CPU usages</string>
<string name="active">Active</string>
<string name="total">Total</string>
<string name="fan_speeds">Fan speeds</string>
<string name="bug_report">Отчет об ошибке</string>
<string name="confirm_bug_report">Запросить отчет об ошибке?</string>
<string name="reboot">Перезагрузить</string>

View File

@@ -137,7 +137,19 @@
<string name="disable_usb_signal">USB sinyali</string> <!--TODO-->
<string name="keyguard">Ekran kilidi</string>
<string name="lock_now">Ekranı şimdi kilitle</string>
<string name="evict_credential_encryptoon_key">Kimlik doğrulama şifreleme anahtarını çıkar</string>
<string name="evict_credential_encryption_key">Kimlik doğrulama şifreleme anahtarını çıkar</string>
<!--TODO: the following 11 strings-->
<string name="hardware_monitor">Hardware monitor</string>
<string name="refresh_interval">Refresh interval</string>
<string name="cpu_temp">CPU temperatures</string>
<string name="gpu_temp">GPU temperatures</string>
<string name="battery_temp">Battery temperatures</string>
<string name="skin_temp">Skin temperatures</string>
<string name="undefined">Undefined</string>
<string name="cpu_usages">CPU usages</string>
<string name="active">Active</string>
<string name="total">Total</string>
<string name="fan_speeds">Fan speeds</string>
<string name="bug_report">Hata raporu</string>
<string name="confirm_bug_report">Hata raporu iste?</string>
<string name="reboot">Yeniden başlat</string>

View File

@@ -131,7 +131,18 @@
<string name="disable_usb_signal">禁用USB信号</string>
<string name="keyguard">锁屏</string>
<string name="lock_now">立即锁屏</string>
<string name="evict_credential_encryptoon_key">移除凭证加密密钥</string>
<string name="evict_credential_encryption_key">移除凭证加密密钥</string>
<string name="hardware_monitor">硬件监视器</string>
<string name="refresh_interval">刷新间隔</string>
<string name="cpu_temp">CPU温度</string>
<string name="gpu_temp">GPU温度</string>
<string name="battery_temp">电池温度</string>
<string name="skin_temp">表面温度</string>
<string name="undefined">未定义</string>
<string name="cpu_usages">CPU使用情况</string>
<string name="active">活动</string>
<string name="total">总计</string>
<string name="fan_speeds">Fan speeds</string>
<string name="bug_report">错误报告</string>
<string name="confirm_bug_report">请求错误报告?</string>
<string name="reboot">重启</string>

View File

@@ -145,7 +145,18 @@
<string name="disable_usb_signal">Disable USB signal</string>
<string name="keyguard">Keyguard</string>
<string name="lock_now">Lock screen now</string>
<string name="evict_credential_encryptoon_key">Evict credential encryption key</string>
<string name="evict_credential_encryption_key">Evict credential encryption key</string>
<string name="hardware_monitor">Hardware monitor</string>
<string name="refresh_interval">Refresh interval</string>
<string name="cpu_temp">CPU temperatures</string>
<string name="gpu_temp">GPU temperatures</string>
<string name="battery_temp">Battery temperatures</string>
<string name="skin_temp">Skin temperatures</string>
<string name="undefined">Undefined</string>
<string name="cpu_usages">CPU usages</string>
<string name="active">Active</string>
<string name="total">Total</string>
<string name="fan_speeds">Fan speeds</string>
<string name="bug_report">Bug report</string>
<string name="confirm_bug_report">Request bug report?</string>
<string name="reboot">Reboot</string>