完善cpu信息
This commit is contained in:
parent
985eba8516
commit
25b5d7b977
@ -1,5 +1,6 @@
|
|||||||
package com.xyzshell.andinfo.libs
|
package com.xyzshell.andinfo.libs
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import com.xyzshell.andinfo.libs.cpu.models.Cache
|
import com.xyzshell.andinfo.libs.cpu.models.Cache
|
||||||
import com.xyzshell.andinfo.libs.cpu.models.Cluster
|
import com.xyzshell.andinfo.libs.cpu.models.Cluster
|
||||||
import com.xyzshell.andinfo.libs.cpu.models.Core
|
import com.xyzshell.andinfo.libs.cpu.models.Core
|
||||||
@ -7,60 +8,640 @@ import com.xyzshell.andinfo.libs.cpu.models.Package
|
|||||||
import com.xyzshell.andinfo.libs.cpu.models.Processor
|
import com.xyzshell.andinfo.libs.cpu.models.Processor
|
||||||
import com.xyzshell.andinfo.libs.cpu.models.UarchInfo
|
import com.xyzshell.andinfo.libs.cpu.models.UarchInfo
|
||||||
import com.xyzshell.andinfo.libs.cpu.utils.CpuInfoUtils
|
import com.xyzshell.andinfo.libs.cpu.utils.CpuInfoUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU 信息类
|
||||||
|
* 用于获取设备处理器的详细信息,包括核心数、频率、架构、缓存等
|
||||||
|
*/
|
||||||
class CpuInfo {
|
class CpuInfo {
|
||||||
|
|
||||||
|
// ==================== 基础处理器信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有逻辑处理器列表
|
||||||
|
* @return 逻辑处理器列表
|
||||||
|
*/
|
||||||
val processors: List<Processor>
|
val processors: List<Processor>
|
||||||
get() = CpuInfoUtils.getProcessors()
|
get() = CpuInfoUtils.getProcessors()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有物理核心列表
|
||||||
|
* @return 物理核心列表
|
||||||
|
*/
|
||||||
val cores: List<Core>
|
val cores: List<Core>
|
||||||
get() = CpuInfoUtils.getCores()
|
get() = CpuInfoUtils.getCores()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有核心集群列表(大小核分组)
|
||||||
|
* @return 集群列表
|
||||||
|
*/
|
||||||
val clusters: List<Cluster>
|
val clusters: List<Cluster>
|
||||||
get() = CpuInfoUtils.getClusters()
|
get() = CpuInfoUtils.getClusters()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有物理封装(芯片)列表
|
||||||
|
* @return 封装列表
|
||||||
|
*/
|
||||||
val packages: List<Package>
|
val packages: List<Package>
|
||||||
get() = CpuInfoUtils.getPackages()
|
get() = CpuInfoUtils.getPackages()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有微架构信息列表
|
||||||
|
* @return 微架构信息列表
|
||||||
|
*/
|
||||||
val uarchs: List<UarchInfo>
|
val uarchs: List<UarchInfo>
|
||||||
get() = CpuInfoUtils.getUarchs()
|
get() = CpuInfoUtils.getUarchs()
|
||||||
|
|
||||||
|
// ==================== 缓存信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L1 指令缓存列表
|
||||||
|
* @return L1i 缓存列表
|
||||||
|
*/
|
||||||
val l1iCaches: List<Cache>
|
val l1iCaches: List<Cache>
|
||||||
get() = CpuInfoUtils.getL1iCaches()
|
get() = CpuInfoUtils.getL1iCaches()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L1 数据缓存列表
|
||||||
|
* @return L1d 缓存列表
|
||||||
|
*/
|
||||||
val l1dCaches: List<Cache>
|
val l1dCaches: List<Cache>
|
||||||
get() = CpuInfoUtils.getL1dCaches()
|
get() = CpuInfoUtils.getL1dCaches()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L2 缓存列表
|
||||||
|
* @return L2 缓存列表
|
||||||
|
*/
|
||||||
val l2Caches: List<Cache>
|
val l2Caches: List<Cache>
|
||||||
get() = CpuInfoUtils.getL2Caches()
|
get() = CpuInfoUtils.getL2Caches()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L3 缓存列表
|
||||||
|
* @return L3 缓存列表
|
||||||
|
*/
|
||||||
val l3Caches: List<Cache>
|
val l3Caches: List<Cache>
|
||||||
get() = CpuInfoUtils.getL3Caches()
|
get() = CpuInfoUtils.getL3Caches()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L4 缓存列表
|
||||||
|
* @return L4 缓存列表
|
||||||
|
*/
|
||||||
val l4Caches: List<Cache>
|
val l4Caches: List<Cache>
|
||||||
get() = CpuInfoUtils.getL4Caches()
|
get() = CpuInfoUtils.getL4Caches()
|
||||||
|
|
||||||
fun hardware(): String {
|
// ==================== 处理器名称和供应商 ====================
|
||||||
return if (processors.isNotEmpty()) {
|
|
||||||
processors[0].cpuPackage?.name ?: "未知"
|
/**
|
||||||
|
* 获取处理器名称(SoC 型号)
|
||||||
|
* @return 处理器名称,例如 "Qualcomm Snapdragon 888"
|
||||||
|
*/
|
||||||
|
fun getProcessorName(): String {
|
||||||
|
return if (packages.isNotEmpty()) {
|
||||||
|
packages[0].name
|
||||||
} else {
|
} else {
|
||||||
"未知"
|
"未知"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取处理器供应商
|
||||||
|
* @return 供应商名称,例如 "Qualcomm", "ARM", "Intel" 等
|
||||||
|
*/
|
||||||
|
fun getVendor(): String {
|
||||||
|
return if (cores.isNotEmpty()) {
|
||||||
|
cores[0].vendor.name
|
||||||
|
} else {
|
||||||
|
"未知"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 核心数量信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取物理核心总数
|
||||||
|
* @return 核心数量
|
||||||
|
*/
|
||||||
|
fun getCoreCount(): Int {
|
||||||
|
return cores.size
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取逻辑处理器总数
|
||||||
|
* @return 逻辑处理器数量
|
||||||
|
*/
|
||||||
|
fun getProcessorCount(): Int {
|
||||||
|
return processors.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 大小核信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大小核信息数据类
|
||||||
|
* @property bigCoreCount 大核数量
|
||||||
|
* @property midCoreCount 中核数量
|
||||||
|
* @property littleCoreCount 小核数量
|
||||||
|
* @property bigCoreFreq 大核最高频率(Hz)
|
||||||
|
* @property midCoreFreq 中核最高频率(Hz)
|
||||||
|
* @property littleCoreFreq 小核最高频率(Hz)
|
||||||
|
*/
|
||||||
|
data class ClusterInfo(
|
||||||
|
val bigCoreCount: Int,
|
||||||
|
val midCoreCount: Int,
|
||||||
|
val littleCoreCount: Int,
|
||||||
|
val bigCoreFreq: ULong,
|
||||||
|
val midCoreFreq: ULong,
|
||||||
|
val littleCoreFreq: ULong
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取大小核信息
|
||||||
|
* @return 大小核信息对象
|
||||||
|
*/
|
||||||
|
fun getClusterInfo(): ClusterInfo {
|
||||||
|
if (clusters.isEmpty()) {
|
||||||
|
return ClusterInfo(0, 0, 0, 0UL, 0UL, 0UL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按频率排序集群
|
||||||
|
val sortedClusters = clusters.sortedByDescending { cluster ->
|
||||||
|
cores.filter { it.cluster.clusterId == cluster.clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (sortedClusters.size) {
|
||||||
|
1 -> ClusterInfo(
|
||||||
|
0, 0, sortedClusters[0].coreCount.toInt(),
|
||||||
|
0UL, 0UL,
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL
|
||||||
|
)
|
||||||
|
2 -> ClusterInfo(
|
||||||
|
sortedClusters[0].coreCount.toInt(),
|
||||||
|
0,
|
||||||
|
sortedClusters[1].coreCount.toInt(),
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL,
|
||||||
|
0UL,
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[1].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL
|
||||||
|
)
|
||||||
|
else -> ClusterInfo(
|
||||||
|
sortedClusters[0].coreCount.toInt(),
|
||||||
|
sortedClusters[1].coreCount.toInt(),
|
||||||
|
sortedClusters[2].coreCount.toInt(),
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL,
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[1].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL,
|
||||||
|
cores.filter { it.cluster.clusterId == sortedClusters[2].clusterId }
|
||||||
|
.maxOfOrNull { it.frequency } ?: 0UL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 制程和架构 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 制程信息数据类
|
||||||
|
* @property process 制程工艺,例如 "4nm", "5nm", "7nm" 等
|
||||||
|
* @property foundry 代工厂,例如 "台积电", "三星" 等
|
||||||
|
* @property node 详细制程节点,例如 "TSMC N4P", "Samsung 4LPE" 等
|
||||||
|
*/
|
||||||
|
data class ProcessInfo(
|
||||||
|
val process: String,
|
||||||
|
val foundry: String,
|
||||||
|
val node: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取制程信息(根据 SoC 型号查询)
|
||||||
|
* @return 制程信息对象,包含制程工艺和代工厂
|
||||||
|
*/
|
||||||
|
fun getProcessInfo(): ProcessInfo {
|
||||||
|
val processorName = getProcessorName().lowercase()
|
||||||
|
|
||||||
|
return when {
|
||||||
|
// 高通 Snapdragon 8 系列
|
||||||
|
"snapdragon 8 gen 3" in processorName || "sm8650" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4P")
|
||||||
|
"snapdragon 8 gen 2" in processorName || "sm8550" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"snapdragon 8 gen 1" in processorName || "sm8450" in processorName ->
|
||||||
|
ProcessInfo("4nm", "三星", "Samsung 4LPE")
|
||||||
|
"snapdragon 888+" in processorName || "sm8350-ab" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"snapdragon 888" in processorName || "sm8350" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"snapdragon 870" in processorName || "sm8250-ac" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7P")
|
||||||
|
"snapdragon 865+" in processorName || "sm8250-ab" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7P")
|
||||||
|
"snapdragon 865" in processorName || "sm8250" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7P")
|
||||||
|
|
||||||
|
// 高通 Snapdragon 7 系列
|
||||||
|
"snapdragon 7+ gen 2" in processorName || "sm7475" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"snapdragon 778g" in processorName || "sm7325" in processorName ->
|
||||||
|
ProcessInfo("6nm", "台积电", "TSMC N6")
|
||||||
|
|
||||||
|
// 高通 Snapdragon 6 系列
|
||||||
|
"snapdragon 695" in processorName || "sm6375" in processorName ->
|
||||||
|
ProcessInfo("6nm", "台积电", "TSMC N6")
|
||||||
|
|
||||||
|
// 联发科 Dimensity 9000 系列
|
||||||
|
"dimensity 9300" in processorName || "mt6989" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4P")
|
||||||
|
"dimensity 9200+" in processorName || "mt6985" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"dimensity 9200" in processorName || "mt6983" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"dimensity 9000+" in processorName || "mt6985" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"dimensity 9000" in processorName || "mt6983" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
|
||||||
|
// 联发科 Dimensity 8000 系列
|
||||||
|
"dimensity 8300" in processorName || "mt6897" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"dimensity 8200" in processorName || "mt6896" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"dimensity 8100" in processorName || "mt6895" in processorName ->
|
||||||
|
ProcessInfo("5nm", "台积电", "TSMC N5")
|
||||||
|
|
||||||
|
// 联发科 Dimensity 1000 系列
|
||||||
|
"dimensity 1200" in processorName || "mt6893" in processorName ->
|
||||||
|
ProcessInfo("6nm", "台积电", "TSMC N6")
|
||||||
|
"dimensity 1080" in processorName || "mt6877" in processorName ->
|
||||||
|
ProcessInfo("6nm", "台积电", "TSMC N6")
|
||||||
|
|
||||||
|
// 联发科 Helio 系列
|
||||||
|
"helio g99" in processorName || "mt6789" in processorName ->
|
||||||
|
ProcessInfo("6nm", "台积电", "TSMC N6")
|
||||||
|
|
||||||
|
// 三星 Exynos
|
||||||
|
"exynos 2400" in processorName || "s5e9945" in processorName ->
|
||||||
|
ProcessInfo("4nm", "三星", "Samsung 4LPP+")
|
||||||
|
"exynos 2200" in processorName || "s5e9925" in processorName ->
|
||||||
|
ProcessInfo("4nm", "三星", "Samsung 4LPE")
|
||||||
|
"exynos 2100" in processorName || "s5e9840" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"exynos 1080" in processorName || "s5e1080" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"exynos 1380" in processorName || "s5e8835" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"exynos 1280" in processorName || "s5e8825" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
|
||||||
|
// 谷歌 Tensor
|
||||||
|
"tensor g3" in processorName || "gs301" in processorName ->
|
||||||
|
ProcessInfo("4nm", "三星", "Samsung 4LPP+")
|
||||||
|
"tensor g2" in processorName || "gs201" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"tensor g1" in processorName || "gs101" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
"tensor" in processorName ->
|
||||||
|
ProcessInfo("5nm", "三星", "Samsung 5LPE")
|
||||||
|
|
||||||
|
// 华为麒麟
|
||||||
|
"kirin 9000" in processorName ->
|
||||||
|
ProcessInfo("5nm", "台积电", "TSMC N5")
|
||||||
|
"kirin 9000e" in processorName ->
|
||||||
|
ProcessInfo("5nm", "台积电", "TSMC N5")
|
||||||
|
"kirin 990" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7+")
|
||||||
|
"kirin 980" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7")
|
||||||
|
"kirin 810" in processorName ->
|
||||||
|
ProcessInfo("7nm", "台积电", "TSMC N7")
|
||||||
|
|
||||||
|
// 苹果 A 系列(参考)
|
||||||
|
"apple a17" in processorName ->
|
||||||
|
ProcessInfo("3nm", "台积电", "TSMC N3B")
|
||||||
|
"apple a16" in processorName ->
|
||||||
|
ProcessInfo("4nm", "台积电", "TSMC N4")
|
||||||
|
"apple a15" in processorName ->
|
||||||
|
ProcessInfo("5nm", "台积电", "TSMC N5P")
|
||||||
|
"apple a14" in processorName ->
|
||||||
|
ProcessInfo("5nm", "台积电", "TSMC N5")
|
||||||
|
|
||||||
|
// 默认情况
|
||||||
|
else -> ProcessInfo("未知", "未知", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取制程信息(字符串格式,兼容旧版本)
|
||||||
|
* @return 制程信息,例如 "5nm", "7nm" 等
|
||||||
|
*/
|
||||||
|
fun getProcess(): String {
|
||||||
|
return getProcessInfo().process
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取代工厂信息
|
||||||
|
* @return 代工厂名称,例如 "台积电", "三星" 等
|
||||||
|
*/
|
||||||
|
fun getFoundry(): String {
|
||||||
|
return getProcessInfo().foundry
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取详细制程节点
|
||||||
|
* @return 制程节点,例如 "TSMC N4P", "Samsung 5LPE" 等
|
||||||
|
*/
|
||||||
|
fun getProcessNode(): String {
|
||||||
|
return getProcessInfo().node.ifEmpty { getProcessInfo().process }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 CPU 架构
|
||||||
|
* @return 架构名称,例如 "Cortex-A78", "Cortex-X1" 等
|
||||||
|
*/
|
||||||
|
fun getArchitecture(): String {
|
||||||
|
return if (cores.isNotEmpty()) {
|
||||||
|
cores[0].uarch.name
|
||||||
|
} else {
|
||||||
|
"未知"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有核心的架构列表(去重)
|
||||||
|
* @return 架构列表
|
||||||
|
*/
|
||||||
|
fun getAllArchitectures(): List<String> {
|
||||||
|
return cores.map { it.uarch.name }.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== ABI 信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前设备的主 ABI
|
||||||
|
* @return ABI 字符串,例如 "arm64-v8a", "armeabi-v7a" 等
|
||||||
|
*/
|
||||||
|
fun getAbi(): String {
|
||||||
|
return Build.SUPPORTED_ABIS.firstOrNull() ?: "未知"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有支持的 ABI 列表
|
||||||
|
* @return ABI 列表
|
||||||
|
*/
|
||||||
|
fun getSupportedAbis(): List<String> {
|
||||||
|
return Build.SUPPORTED_ABIS.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 频率信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个核心的频率信息
|
||||||
|
* @property coreId 核心 ID
|
||||||
|
* @property currentFreq 当前频率(KHz)
|
||||||
|
* @property minFreq 最小频率(KHz)
|
||||||
|
* @property maxFreq 最大频率(KHz)
|
||||||
|
* @property availableFreqs 可用频率列表(KHz)
|
||||||
|
*/
|
||||||
|
data class CoreFrequencyInfo(
|
||||||
|
val coreId: Int,
|
||||||
|
val currentFreq: Long,
|
||||||
|
val minFreq: Long,
|
||||||
|
val maxFreq: Long,
|
||||||
|
val availableFreqs: List<Long>
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有核心的详细频率信息
|
||||||
|
* @return 核心频率信息列表
|
||||||
|
*/
|
||||||
|
fun getCoreFrequencies(): List<CoreFrequencyInfo> {
|
||||||
|
val result = mutableListOf<CoreFrequencyInfo>()
|
||||||
|
|
||||||
|
for (i in 0 until getCoreCount()) {
|
||||||
|
val currentFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/scaling_cur_freq")
|
||||||
|
val minFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/cpuinfo_min_freq")
|
||||||
|
val maxFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/cpuinfo_max_freq")
|
||||||
|
val availableFreqs = readAvailableFrequencies("/sys/devices/system/cpu/cpu$i/cpufreq/scaling_available_frequencies")
|
||||||
|
|
||||||
|
result.add(CoreFrequencyInfo(i, currentFreq, minFreq, maxFreq, availableFreqs))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取频率值
|
||||||
|
* @param path 频率文件路径
|
||||||
|
* @return 频率值(KHz),失败返回 0
|
||||||
|
*/
|
||||||
|
private fun readFrequency(path: String): Long {
|
||||||
|
return try {
|
||||||
|
File(path).readText().trim().toLongOrNull() ?: 0L
|
||||||
|
} catch (e: Exception) {
|
||||||
|
0L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取可用频率列表
|
||||||
|
* @param path 可用频率文件路径
|
||||||
|
* @return 频率列表(KHz)
|
||||||
|
*/
|
||||||
|
private fun readAvailableFrequencies(path: String): List<Long> {
|
||||||
|
return try {
|
||||||
|
File(path).readText().trim()
|
||||||
|
.split("\\s+".toRegex())
|
||||||
|
.mapNotNull { it.toLongOrNull() }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 调频器信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定核心的调频器
|
||||||
|
* @param coreId 核心 ID
|
||||||
|
* @return 调频器名称,例如 "schedutil", "interactive" 等
|
||||||
|
*/
|
||||||
|
fun getGovernor(coreId: Int): String {
|
||||||
|
return try {
|
||||||
|
File("/sys/devices/system/cpu/cpu$coreId/cpufreq/scaling_governor")
|
||||||
|
.readText().trim()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"未知"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有核心的调频器
|
||||||
|
* @return 调频器列表
|
||||||
|
*/
|
||||||
|
fun getAllGovernors(): List<String> {
|
||||||
|
return (0 until getCoreCount()).map { getGovernor(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取可用的调频器列表
|
||||||
|
* @param coreId 核心 ID
|
||||||
|
* @return 可用调频器列表
|
||||||
|
*/
|
||||||
|
fun getAvailableGovernors(coreId: Int = 0): List<String> {
|
||||||
|
return try {
|
||||||
|
File("/sys/devices/system/cpu/cpu$coreId/cpufreq/scaling_available_governors")
|
||||||
|
.readText().trim()
|
||||||
|
.split("\\s+".toRegex())
|
||||||
|
} catch (e: Exception) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== CPU 特性 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 CPU 特性列表(从 /proc/cpuinfo 读取 Features)
|
||||||
|
* @return CPU 特性列表
|
||||||
|
*/
|
||||||
|
fun getCpuFeatures(): List<String> {
|
||||||
|
return try {
|
||||||
|
File("/proc/cpuinfo").readLines()
|
||||||
|
.find { it.startsWith("Features") }
|
||||||
|
?.substringAfter(":")
|
||||||
|
?.trim()
|
||||||
|
?.split("\\s+".toRegex()) ?: emptyList()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== /proc/cpuinfo 原始信息 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 /proc/cpuinfo 的完整内容
|
||||||
|
* @return /proc/cpuinfo 文件内容
|
||||||
|
*/
|
||||||
|
fun getProcCpuInfo(): String {
|
||||||
|
return try {
|
||||||
|
File("/proc/cpuinfo").readText()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"无法读取 /proc/cpuinfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 /proc/cpuinfo 为键值对映射
|
||||||
|
* @return 解析后的映射表
|
||||||
|
*/
|
||||||
|
fun parseProcCpuInfo(): Map<String, String> {
|
||||||
|
val result = mutableMapOf<String, String>()
|
||||||
|
try {
|
||||||
|
File("/proc/cpuinfo").readLines().forEach { line ->
|
||||||
|
if (line.contains(":")) {
|
||||||
|
val parts = line.split(":", limit = 2)
|
||||||
|
if (parts.size == 2) {
|
||||||
|
result[parts[0].trim()] = parts[1].trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// 忽略错误
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 兼容性方法 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取硬件名称(兼容旧版本)
|
||||||
|
* @return 处理器名称
|
||||||
|
*/
|
||||||
|
@Deprecated("使用 getProcessorName() 替代", ReplaceWith("getProcessorName()"))
|
||||||
|
fun hardware(): String {
|
||||||
|
return getProcessorName()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文本格式的 CPU 信息摘要
|
||||||
|
* @return 格式化的文本信息
|
||||||
|
*/
|
||||||
fun text(): String {
|
fun text(): String {
|
||||||
val stringBuilder = StringBuilder()
|
val sb = StringBuilder()
|
||||||
stringBuilder.append("处理器数量: ${processors.size}\n")
|
|
||||||
processors.forEachIndexed { index, processor ->
|
// 基本信息
|
||||||
stringBuilder.append(" 处理器 ${index}: ${processor.cpuPackage?.name ?: "未知"}\n")
|
sb.append("=== CPU 基本信息 ===\n")
|
||||||
stringBuilder.append(" 核心: ${processor.core?.coreId ?: "未知"}\n")
|
sb.append("处理器名称: ${getProcessorName()}\n")
|
||||||
stringBuilder.append(" 集群: ${processor.cluster?.clusterId ?: "未知"}\n")
|
sb.append("供应商: ${getVendor()}\n")
|
||||||
|
val processInfo = getProcessInfo()
|
||||||
|
sb.append("制程工艺: ${processInfo.process}\n")
|
||||||
|
sb.append("代工厂: ${processInfo.foundry}\n")
|
||||||
|
if (processInfo.node.isNotEmpty()) {
|
||||||
|
sb.append("制程节点: ${processInfo.node}\n")
|
||||||
}
|
}
|
||||||
stringBuilder.append("核心数量: ${cores.size}\n")
|
sb.append("物理核心数: ${getCoreCount()}\n")
|
||||||
cores.forEachIndexed { index, core ->
|
sb.append("逻辑处理器数: ${getProcessorCount()}\n")
|
||||||
stringBuilder.append(" 核心 ${index}: ID=${core.coreId}, 频率=${core.frequency}Hz\n")
|
|
||||||
|
// 大小核信息
|
||||||
|
val clusterInfo = getClusterInfo()
|
||||||
|
sb.append("\n=== 大小核配置 ===\n")
|
||||||
|
if (clusterInfo.bigCoreCount > 0) {
|
||||||
|
sb.append("大核: ${clusterInfo.bigCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.bigCoreFreq)}\n")
|
||||||
|
}
|
||||||
|
if (clusterInfo.midCoreCount > 0) {
|
||||||
|
sb.append("中核: ${clusterInfo.midCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.midCoreFreq)}\n")
|
||||||
|
}
|
||||||
|
if (clusterInfo.littleCoreCount > 0) {
|
||||||
|
sb.append("小核: ${clusterInfo.littleCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.littleCoreFreq)}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 架构信息
|
||||||
|
sb.append("\n=== 架构信息 ===\n")
|
||||||
|
sb.append("架构: ${getAllArchitectures().joinToString(", ")}\n")
|
||||||
|
sb.append("ABI: ${getAbi()}\n")
|
||||||
|
sb.append("支持的 ABI: ${getSupportedAbis().joinToString(", ")}\n")
|
||||||
|
|
||||||
|
// 调频器
|
||||||
|
sb.append("\n=== 调频器 ===\n")
|
||||||
|
sb.append("当前调频器: ${getGovernor(0)}\n")
|
||||||
|
sb.append("可用调频器: ${getAvailableGovernors().joinToString(", ")}\n")
|
||||||
|
|
||||||
|
// 核心详细频率
|
||||||
|
sb.append("\n=== 核心频率信息 ===\n")
|
||||||
|
getCoreFrequencies().forEach { freq ->
|
||||||
|
sb.append("CPU${freq.coreId}: 当前=${formatFrequency(freq.currentFreq.toULong() * 1000UL)}, ")
|
||||||
|
sb.append("范围=${formatFrequency(freq.minFreq.toULong() * 1000UL)}-${formatFrequency(freq.maxFreq.toULong() * 1000UL)}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存信息
|
||||||
|
sb.append("\n=== 缓存信息 ===\n")
|
||||||
|
sb.append("L1i 缓存: ${l1iCaches.size} 个\n")
|
||||||
|
sb.append("L1d 缓存: ${l1dCaches.size} 个\n")
|
||||||
|
sb.append("L2 缓存: ${l2Caches.size} 个\n")
|
||||||
|
sb.append("L3 缓存: ${l3Caches.size} 个\n")
|
||||||
|
|
||||||
|
// CPU 特性
|
||||||
|
val features = getCpuFeatures()
|
||||||
|
if (features.isNotEmpty()) {
|
||||||
|
sb.append("\n=== CPU 特性 ===\n")
|
||||||
|
sb.append(features.joinToString(" "))
|
||||||
|
sb.append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化频率显示
|
||||||
|
* @param freqHz 频率(Hz)
|
||||||
|
* @return 格式化后的频率字符串
|
||||||
|
*/
|
||||||
|
private fun formatFrequency(freqHz: ULong): String {
|
||||||
|
return when {
|
||||||
|
freqHz >= 1_000_000_000UL -> String.format("%.2f GHz", freqHz.toDouble() / 1_000_000_000)
|
||||||
|
freqHz >= 1_000_000UL -> String.format("%.0f MHz", freqHz.toDouble() / 1_000_000)
|
||||||
|
freqHz >= 1_000UL -> String.format("%.0f KHz", freqHz.toDouble() / 1_000)
|
||||||
|
else -> "$freqHz Hz"
|
||||||
}
|
}
|
||||||
// 可以根据需要添加更多详细信息
|
|
||||||
return stringBuilder.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@ -6,11 +6,20 @@ import android.os.Build
|
|||||||
import android.view.Display
|
import android.view.Display
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示信息类,用于获取设备屏幕相关信息
|
||||||
|
*/
|
||||||
class DisplayInfo(private val context: Context) {
|
class DisplayInfo(private val context: Context) {
|
||||||
|
|
||||||
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取默认显示器信息
|
||||||
|
* @return 默认显示器信息对象,如果获取失败返回 null
|
||||||
|
*/
|
||||||
fun getDefaultDisplayInfo(): DefaultDisplayInfo? {
|
fun getDefaultDisplayInfo(): DefaultDisplayInfo? {
|
||||||
val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: return null
|
val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: return null
|
||||||
|
|
||||||
@ -22,13 +31,24 @@ class DisplayInfo(private val context: Context) {
|
|||||||
|
|
||||||
val mode = defaultDisplay.mode
|
val mode = defaultDisplay.mode
|
||||||
val refreshRate = mode.refreshRate
|
val refreshRate = mode.refreshRate
|
||||||
|
// 计算 PPI (每英寸像素数)
|
||||||
val isHdr = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
val ppi = calculatePPI(displayMetrics.widthPixels, displayMetrics.heightPixels, displayMetrics.densityDpi)
|
||||||
defaultDisplay.hdrCapabilities?.supportedHdrTypes?.isNotEmpty() ?: false
|
// 获取支持的刷新率列表
|
||||||
|
val supportedRefreshRates = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
defaultDisplay.supportedModes.map { it.refreshRate }.distinct().sorted()
|
||||||
} else {
|
} else {
|
||||||
false
|
listOf(refreshRate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否支持 HDR 及 HDR 类型
|
||||||
|
val hdrTypes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
defaultDisplay.mode?.supportedHdrTypes?.map { getHdrTypeName(it) } ?: emptyList()
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
val isHdr = hdrTypes.isNotEmpty()
|
||||||
|
|
||||||
|
// 检查是否支持广色域
|
||||||
val isWideColorGamut = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
val isWideColorGamut = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
defaultDisplay.isWideColorGamut
|
defaultDisplay.isWideColorGamut
|
||||||
} else {
|
} else {
|
||||||
@ -43,22 +63,81 @@ class DisplayInfo(private val context: Context) {
|
|||||||
densityDpi = displayMetrics.densityDpi,
|
densityDpi = displayMetrics.densityDpi,
|
||||||
xdpi = displayMetrics.xdpi,
|
xdpi = displayMetrics.xdpi,
|
||||||
ydpi = displayMetrics.ydpi,
|
ydpi = displayMetrics.ydpi,
|
||||||
|
ppi = ppi,
|
||||||
refreshRate = refreshRate,
|
refreshRate = refreshRate,
|
||||||
|
supportedRefreshRates = supportedRefreshRates,
|
||||||
isHdr = isHdr,
|
isHdr = isHdr,
|
||||||
|
hdrTypes,
|
||||||
isWideColorGamut = isWideColorGamut
|
isWideColorGamut = isWideColorGamut
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 HDR 类型名称
|
||||||
|
* @param hdrType HDR 类型常量
|
||||||
|
* @return HDR 类型名称
|
||||||
|
*/
|
||||||
|
private fun getHdrTypeName(hdrType: Int): String {
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
when (hdrType) {
|
||||||
|
Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION -> "Dolby Vision"
|
||||||
|
Display.HdrCapabilities.HDR_TYPE_HDR10 -> "HDR10"
|
||||||
|
Display.HdrCapabilities.HDR_TYPE_HLG -> "HLG"
|
||||||
|
Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS -> "HDR10+"
|
||||||
|
else -> "Unknown HDR Type ($hdrType)"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 计算屏幕 PPI (每英寸像素数)
|
||||||
|
* @param widthPixels 屏幕宽度像素
|
||||||
|
* @param heightPixels 屏幕高度像素
|
||||||
|
* @param densityDpi 屏幕密度 DPI
|
||||||
|
* @return PPI 值
|
||||||
|
*/
|
||||||
|
private fun calculatePPI(widthPixels: Int, heightPixels: Int, densityDpi: Int): Double {
|
||||||
|
// 使用勾股定理计算对角线像素数
|
||||||
|
val diagonalPixels = sqrt((widthPixels * widthPixels + heightPixels * heightPixels).toDouble())
|
||||||
|
|
||||||
|
// 通过 densityDpi 计算屏幕对角线英寸数
|
||||||
|
// 160 DPI 是 Android 的基准密度 (mdpi)
|
||||||
|
val diagonalInches = diagonalPixels / densityDpi
|
||||||
|
|
||||||
|
// PPI = 对角线像素数 / 对角线英寸数
|
||||||
|
return diagonalPixels / diagonalInches
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认显示器信息数据类
|
||||||
|
* @property id 显示器 ID
|
||||||
|
* @property name 显示器名称
|
||||||
|
* @property widthPixels 屏幕宽度(像素)
|
||||||
|
* @property heightPixels 屏幕高度(像素)
|
||||||
|
* @property densityDpi 屏幕密度 DPI
|
||||||
|
* @property xdpi X 轴每英寸像素数
|
||||||
|
* @property ydpi Y 轴每英寸像素数
|
||||||
|
* @property ppi 屏幕 PPI(每英寸像素数)
|
||||||
|
* @property refreshRate 当前刷新率(Hz)
|
||||||
|
* @property supportedRefreshRates 支持的刷新率列表(Hz)
|
||||||
|
* @property isHdr 是否支持 HDR
|
||||||
|
* @property hdrTypes 支持的 HDR 类型列表
|
||||||
|
* @property isWideColorGamut 是否支持广色域
|
||||||
|
*/
|
||||||
data class DefaultDisplayInfo(
|
data class DefaultDisplayInfo(
|
||||||
val id: Int,
|
val id: Int, // 显示器 ID
|
||||||
val name: String,
|
val name: String, // 显示器名称
|
||||||
val widthPixels: Int,
|
val widthPixels: Int, // 屏幕宽度(像素)
|
||||||
val heightPixels: Int,
|
val heightPixels: Int, // 屏幕高度(像素)
|
||||||
val densityDpi: Int,
|
val densityDpi: Int, // 屏幕密度 DPI
|
||||||
val xdpi: Float,
|
val xdpi: Float, // X 轴 DPI
|
||||||
val ydpi: Float,
|
val ydpi: Float, // Y 轴 DPI
|
||||||
val refreshRate: Float,
|
val ppi: Double, // 屏幕 PPI
|
||||||
val isHdr: Boolean,
|
val refreshRate: Float, // 当前刷新率(Hz)
|
||||||
val isWideColorGamut: Boolean
|
val supportedRefreshRates: List<Float>, // 支持的刷新率列表(Hz)
|
||||||
|
val isHdr: Boolean, // 是否支持 HDR
|
||||||
|
val hdrTypes: List<String>, // 支持的 HDR 类型列表
|
||||||
|
val isWideColorGamut: Boolean // 是否支持广色域
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,32 @@
|
|||||||
package com.xyzshell.andinfo.utils
|
package com.xyzshell.andinfo.utils
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import javax.crypto.Cipher
|
||||||
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
class WebService {
|
class WebService {
|
||||||
private val client = OkHttpClient()
|
private val client = OkHttpClient()
|
||||||
val gson = Gson()
|
val gson = Gson()
|
||||||
|
// AES 密钥 (必须是 16/24/32 字节)
|
||||||
|
private val aesKey = "e67cbcee5e573d1b"
|
||||||
|
|
||||||
|
// AES 加密
|
||||||
|
fun encrypt(plainText: String): String {
|
||||||
|
return try {
|
||||||
|
val secretKey = SecretKeySpec(aesKey.toByteArray(), "AES")
|
||||||
|
val cipher = Cipher.getInstance("AES")
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
|
||||||
|
val encryptedBytes = cipher.doFinal(plainText.toByteArray())
|
||||||
|
Base64.encodeToString(encryptedBytes, Base64.NO_WRAP)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw Exception("加密失败: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
fun postData(url: String, jsonData: String, callback: (String?, Exception?) -> Unit) {
|
fun postData(url: String, jsonData: String, callback: (String?, Exception?) -> Unit) {
|
||||||
val mediaType = "application/json; charset=utf-8".toMediaType()
|
val mediaType = "application/json; charset=utf-8".toMediaType()
|
||||||
val body = jsonData.toRequestBody(mediaType)
|
val body = jsonData.toRequestBody(mediaType)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user