diff --git a/BuildInfo新增功能使用示例.md b/BuildInfo新增功能使用示例.md new file mode 100644 index 0000000..bc65a26 --- /dev/null +++ b/BuildInfo新增功能使用示例.md @@ -0,0 +1,403 @@ +# BuildInfo 新增功能使用示例 + +## 概述 +BuildInfo类已新增了大量系统信息获取功能,包括Treble支持、无缝更新、Root检测、Google Play服务、系统工具、SSL版本、语言时区、USB调试、内核信息和设备标识符等。 + +## 新增功能列表 + +### 1. Treble 和系统更新 +- ✅ **Treble支持检测** - `isTrebleEnabled` +- ✅ **Treble版本** - `trebleVersion` +- ✅ **无缝更新(A/B)支持** - `isSeamlessUpdateSupported` +- ✅ **当前活动插槽** - `currentSlot` +- ✅ **虚拟A/B支持** - `isVirtualABEnabled` + +### 2. Root 权限和安全 +- ✅ **Root状态检测** - `isRooted` +- ✅ **SELinux状态** - `seLinuxStatus` +- ✅ **dm-verity状态** - `isDmVerityEnabled` + +### 3. Google Play 服务 +- ✅ **Play服务版本名称** - `googlePlayServicesVersion` +- ✅ **Play服务版本代码** - `googlePlayServicesVersionCode` +- ✅ **Play商店版本** - `googlePlayStoreVersion` +- ✅ **Google Services Framework版本** - `googleServicesFrameworkVersion` + +### 4. 系统工具版本 +- ✅ **Toybox版本** - `toyboxVersion` +- ✅ **Toolbox版本** - `toolboxVersion` +- ✅ **BusyBox版本** - `busyboxVersion` + +### 5. SSL/TLS 信息 +- ✅ **OpenSSL版本** - `openSslVersion` +- ✅ **BoringSSL版本** - `boringSslVersion` +- ✅ **TLS支持版本** - `tlsVersion` + +### 6. 语言和时区 +- ✅ **系统语言** - `systemLanguage` +- ✅ **语言代码** - `languageCode` +- ✅ **国家/地区** - `country` +- ✅ **国家/地区代码** - `countryCode` +- ✅ **系统时区** - `timeZone` +- ✅ **时区显示名称** - `timeZoneDisplayName` +- ✅ **UTC偏移** - `timeZoneOffset` + +### 7. 开发者选项和调试 +- ✅ **USB调试状态** - `isUsbDebuggingEnabled` +- ✅ **开发者选项状态** - `isDevelopmentSettingsEnabled` +- ✅ **未知来源安装** - `isUnknownSourcesEnabled` + +### 8. 内核信息 +- ✅ **内核版本号** - `kernelVersion` +- ✅ **内核架构** - `kernelArchitecture` +- ✅ **内核名称** - `kernelName` +- ✅ **内核命令行参数** - `kernelCommandLine` +- ✅ **CPU信息(/proc/cpuinfo)** - `procCpuInfo` +- ✅ **内存信息(/proc/meminfo)** - `procMemInfo` + +### 9. 设备标识符 +- ✅ **Android ID** - `androidId` +- ✅ **序列号** - `serialNumber` +- ✅ **设备唯一ID** - `deviceUniqueId` + +## 使用示例 + +### 初始化 +```kotlin +import com.xyzshell.andinfo.AndInfo + +// 在Application或Activity中初始化 +AndInfo.init(applicationContext) + +// 获取BuildInfo实例 +val buildInfo = AndInfo.instance.build +``` + +### 1. Treble 和系统更新信息 +```kotlin +// 检查Treble支持 +val isTrebleSupported = buildInfo.isTrebleEnabled +println("Treble支持: ${if (isTrebleSupported) "是" else "否"}") + +// Treble版本 +buildInfo.trebleVersion?.let { version -> + println("Treble版本: $version") +} + +// 检查无缝更新(A/B)支持 +val isABUpdateSupported = buildInfo.isSeamlessUpdateSupported +println("无缝更新(A/B): ${if (isABUpdateSupported) "支持" else "不支持"}") + +// 当前活动插槽 +buildInfo.currentSlot?.let { slot -> + println("当前活动插槽: $slot") +} + +// 虚拟A/B支持 +val isVirtualAB = buildInfo.isVirtualABEnabled +println("虚拟A/B: ${if (isVirtualAB) "支持" else "不支持"}") +``` + +### 2. Root 权限和安全检测 +```kotlin +// Root状态检测 +val isRooted = buildInfo.isRooted +println("Root状态: ${if (isRooted) "已Root" else "未Root"}") + +// SELinux状态 +val seLinuxStatus = buildInfo.seLinuxStatus +println("SELinux状态: $seLinuxStatus") + +// dm-verity状态 +val isDmVerity = buildInfo.isDmVerityEnabled +println("dm-verity: ${if (isDmVerity) "启用" else "禁用"}") +``` + +### 3. Google Play 服务信息 +```kotlin +// Google Play 服务版本 +buildInfo.googlePlayServicesVersion?.let { version -> + println("Play服务版本: $version") +} + +// Google Play 服务版本代码 +buildInfo.googlePlayServicesVersionCode?.let { versionCode -> + println("Play服务版本代码: $versionCode") +} + +// Google Play 商店版本 +buildInfo.googlePlayStoreVersion?.let { version -> + println("Play商店版本: $version") +} + +// Google Services Framework 版本 +buildInfo.googleServicesFrameworkVersion?.let { version -> + println("GSF版本: $version") +} +``` + +### 4. 系统工具版本 +```kotlin +// Toybox版本 +buildInfo.toyboxVersion?.let { version -> + println("Toybox: $version") +} + +// Toolbox版本 +buildInfo.toolboxVersion?.let { version -> + println("Toolbox: $version") +} + +// BusyBox版本(如果安装) +buildInfo.busyboxVersion?.let { version -> + println("BusyBox: $version") +} +``` + +### 5. SSL/TLS 信息 +```kotlin +// OpenSSL版本 +buildInfo.openSslVersion?.let { version -> + println("OpenSSL: $version") +} + +// BoringSSL版本 +buildInfo.boringSslVersion?.let { version -> + println("BoringSSL: $version") +} + +// TLS支持版本 +buildInfo.tlsVersion?.let { version -> + println("TLS支持: $version") + // 输出示例: "TLSv1, TLSv1.1, TLSv1.2, TLSv1.3" +} +``` + +### 6. 语言和时区信息 +```kotlin +// 系统语言 +val language = buildInfo.systemLanguage +val languageCode = buildInfo.languageCode +println("系统语言: $language ($languageCode)") + +// 国家/地区 +val country = buildInfo.country +val countryCode = buildInfo.countryCode +println("国家/地区: $country ($countryCode)") + +// 时区信息 +val timeZone = buildInfo.timeZone +val timeZoneDisplay = buildInfo.timeZoneDisplayName +val utcOffset = buildInfo.timeZoneOffset / 3600000 // 转换为小时 +println("时区: $timeZone") +println("时区显示: $timeZoneDisplay") +println("UTC偏移: ${if (utcOffset >= 0) "+" else ""}${utcOffset}小时") +``` + +### 7. 开发者选项和调试 +```kotlin +// USB调试状态 +val isUsbDebugEnabled = buildInfo.isUsbDebuggingEnabled +println("USB调试: ${if (isUsbDebugEnabled) "启用" else "禁用"}") + +// 开发者选项状态 +val isDeveloperEnabled = buildInfo.isDevelopmentSettingsEnabled +println("开发者选项: ${if (isDeveloperEnabled) "启用" else "禁用"}") + +// 未知来源安装 +val isUnknownSourcesEnabled = buildInfo.isUnknownSourcesEnabled +println("未知来源: ${if (isUnknownSourcesEnabled) "允许" else "禁止"}") +``` + +### 8. 内核信息 +```kotlin +// 内核基本信息 +buildInfo.kernelName?.let { println("内核名称: $it") } +buildInfo.kernelVersion?.let { println("内核版本: $it") } +buildInfo.kernelArchitecture?.let { println("内核架构: $it") } +buildInfo.kernelCompleteVersion?.let { println("完整版本: $it") } + +// 内核命令行参数 +buildInfo.kernelCommandLine?.let { cmdline -> + println("内核命令行:") + println(cmdline) +} + +// CPU信息(/proc/cpuinfo) +buildInfo.procCpuInfo?.let { cpuInfo -> + println("CPU信息:") + println(cpuInfo) +} + +// 内存信息(/proc/meminfo) +buildInfo.procMemInfo?.let { memInfo -> + println("内存信息:") + println(memInfo) +} +``` + +### 9. 设备标识符 +```kotlin +// Android ID +val androidId = buildInfo.androidId +println("Android ID: $androidId") + +// 序列号 +val serialNumber = buildInfo.serialNumber +println("序列号: $serialNumber") + +// 设备唯一ID(基于多个参数生成) +val deviceUniqueId = buildInfo.deviceUniqueId +println("设备唯一ID: $deviceUniqueId") +``` + +### 10. 完整信息输出 +```kotlin +// 使用text()方法获取格式化的完整信息 +val fullInfo = buildInfo.text() +println(fullInfo) +``` + +## 示例输出 + +``` +=== Treble 和系统更新 === +Treble支持: 是 +Treble版本: 1 +无缝更新(A/B): 是 +当前活动插槽: a +虚拟A/B: 否 + +=== Root 和安全 === +Root状态: 未Root +SELinux状态: Enforcing +dm-verity: 启用 + +=== Google 服务 === +Play服务版本: 23.45.12 (190400-582679489) +Play服务版本代码: 234512023 +Play商店版本: 38.6.21-29 [0] [PR] 593153572 +GSF版本: 13-9684448 + +=== 系统工具 === +Toybox: 0.8.9-android13 +Toolbox: 未找到 +BusyBox: 未安装 + +=== SSL/TLS === +OpenSSL: OpenSSL 1.1.1t 7 Feb 2023 +BoringSSL: BoringCrypto +TLS支持: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 + +=== 语言和时区 === +系统语言: 中文(简体) (zh) +国家/地区: 中国 (CN) +时区: Asia/Shanghai +时区显示: 中国标准时间 +UTC偏移: +8小时 + +=== 开发者选项 === +USB调试: 启用 +开发者选项: 启用 +未知来源: 允许 + +=== 内核信息 === +内核名称: Linux +内核版本: 5.10.157 +内核架构: aarch64 +完整版本: 5.10.157-android13-4-00001-gf0123456789a-ab9876543 + +=== 设备标识符 === +Android ID: 1234567890abcdef +序列号: ABC123456789 +设备唯一ID: 123456789 +``` + +## 注意事项 + +1. **权限要求**: + - 序列号 (`serialNumber`) 在 Android 8.0+ 需要 `READ_PHONE_STATE` 权限 + - 大部分其他功能不需要特殊权限 + +2. **设备差异**: + - 不同设备支持的功能可能不同 + - 某些属性可能返回 `null` + +3. **安全和隐私**: + - Android ID 和序列号属于设备标识符,使用时需要注意隐私保护 + - Root检测方法可能无法检测到所有Root工具 + +4. **系统版本**: + - 某些功能仅在特定 Android 版本上可用 + - Treble 功能需要 Android 8.0+ + - 虚拟A/B 需要 Android 11+ + +5. **Root检测**: + - `isRooted` 检测常见的Root工具和文件 + - 高级隐藏Root的设备可能检测不到 + +6. **Google服务**: + - 如果设备未安装Google服务,相关属性将返回 `null` + - 国内Android设备通常没有Google服务 + +## 典型应用场景 + +### 系统信息页面 +```kotlin +class SystemInfoActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val buildInfo = AndInfo.instance.build + + // 显示完整系统信息 + val textView = findViewById(R.id.systemInfo) + textView.text = buildInfo.text() + } +} +``` + +### 安全检查 +```kotlin +fun checkDeviceSecurity(): SecurityReport { + val buildInfo = AndInfo.instance.build + + return SecurityReport( + isRooted = buildInfo.isRooted, + seLinuxEnabled = buildInfo.seLinuxStatus == "Enforcing", + dmVerityEnabled = buildInfo.isDmVerityEnabled, + usbDebuggingEnabled = buildInfo.isUsbDebuggingEnabled + ) +} +``` + +### 兼容性检查 +```kotlin +fun checkSystemCompatibility(): Boolean { + val buildInfo = AndInfo.instance.build + + // 检查是否支持必要的功能 + val hasTreble = buildInfo.isTrebleEnabled + val hasABUpdate = buildInfo.isSeamlessUpdateSupported + val hasGoogleServices = buildInfo.googlePlayServicesVersion != null + + return hasTreble && hasABUpdate && hasGoogleServices +} +``` + +## 完成度 + +✅ **100%** - 所有请求的功能都已实现并添加详细注释 +- Treble支持检测 ✅ +- 无缝更新检测 ✅ +- 活动插槽信息 ✅ +- Root权限检测 ✅ +- Google Play服务版本 ✅ +- Toybox信息 ✅ +- SSL版本信息 ✅ +- 语言和时区 ✅ +- USB调试状态 ✅ +- 内核信息 ✅ +- 设备标识符 ✅ +- 详细中文注释 ✅ + diff --git a/DRMInfo使用示例.md b/DRMInfo使用示例.md new file mode 100644 index 0000000..d67c833 --- /dev/null +++ b/DRMInfo使用示例.md @@ -0,0 +1,235 @@ +# DRMInfo 使用示例 + +## 概述 +DRMInfo类提供了获取设备支持的DRM(数字版权管理)方案的详细信息,包括Widevine、PlayReady等。 + +## 主要功能 +1. 获取所有支持的DRM方案列表 +2. 获取指定DRM方案的详细信息(类型、供应商、版本、算法、设备ID、安全级别、最高HDCP级别等) +3. 获取所有DRM方案的详细信息 + +## 使用方法 + +### 1. 初始化AndInfo +```kotlin +import com.xyzshell.andinfo.AndInfo + +// 在Application或Activity中初始化 +AndInfo.init(applicationContext) +``` + +### 2. 获取DRMInfo实例 +```kotlin +val drmInfo = AndInfo.instance.drm +``` + +### 3. 获取所有支持的DRM方案 +```kotlin +// 获取所有支持的DRM UUID列表 +val supportedDrmSchemes = drmInfo.getSupportedDrmSchemes() + +supportedDrmSchemes.forEach { uuid -> + println("支持的DRM方案: $uuid") +} +``` + +### 4. 获取指定DRM方案的详细信息 +```kotlin +import com.xyzshell.andinfo.libs.DRMInfo + +// 获取Widevine DRM详细信息 +val widevineDrmDetail = drmInfo.getDrmDetail(DRMInfo.WIDEVINE_UUID) + +widevineDrmDetail?.let { detail -> + println("DRM名称: ${detail.name}") + println("UUID: ${detail.uuid}") + println("供应商: ${detail.vendor}") + println("版本: ${detail.version}") + println("描述: ${detail.description}") + println("支持的算法: ${detail.algorithms?.joinToString(", ")}") + println("设备唯一ID: ${detail.deviceUniqueId}") + println("安全级别: ${detail.securityLevel}") // L1, L3等 + println("系统ID: ${detail.systemId}") + println("当前打开的会话数: ${detail.openSessionCount}") + println("最大会话数: ${detail.maxSessionCount}") + println("当前连接的HDCP级别: ${detail.connectedHdcpLevel}") + println("最高支持的HDCP级别: ${detail.maxHdcpLevel}") + + // 获取HDCP级别描述 + detail.maxHdcpLevel?.let { level -> + val hdcpDescription = drmInfo.getHdcpLevelDescription(level) + println("最高HDCP级别描述: $hdcpDescription") + } +} +``` + +### 5. 获取所有DRM方案的详细信息 +```kotlin +val allDrmDetails = drmInfo.getAllDrmDetails() + +allDrmDetails.forEach { detail -> + println("=== ${detail.name} ===") + println("UUID: ${detail.uuid}") + println("供应商: ${detail.vendor}") + println("版本: ${detail.version}") + println("安全级别: ${detail.securityLevel}") + println("最高HDCP级别: ${detail.maxHdcpLevel?.let { drmInfo.getHdcpLevelDescription(it) }}") + println() +} +``` + +### 6. 在Android UI中显示DRM信息 +```kotlin +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import com.xyzshell.andinfo.AndInfo +import com.xyzshell.andinfo.libs.DRMInfo + +class DRMInfoActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // 获取DRMInfo实例 + val drmInfo = AndInfo.instance.drm + + // 获取所有支持的DRM方案 + val allDrmDetails = drmInfo.getAllDrmDetails() + + // 显示每个DRM方案的信息 + allDrmDetails.forEach { detail -> + displayDrmInfo(detail) + } + } + + private fun displayDrmInfo(detail: DRMInfo.DRMDetail) { + // 在UI中显示DRM信息 + val info = buildString { + appendLine("DRM名称: ${detail.name}") + appendLine("UUID: ${detail.uuid}") + appendLine("供应商: ${detail.vendor ?: "未知"}") + appendLine("版本: ${detail.version ?: "未知"}") + appendLine("描述: ${detail.description ?: "无"}") + appendLine("支持的算法: ${detail.algorithms?.joinToString(", ") ?: "无"}") + appendLine("设备唯一ID: ${detail.deviceUniqueId ?: "不可用"}") + appendLine("安全级别: ${detail.securityLevel ?: "未知"}") + appendLine("系统ID: ${detail.systemId ?: "未知"}") + + detail.openSessionCount?.let { + appendLine("当前打开的会话数: $it") + } + detail.maxSessionCount?.let { + appendLine("最大会话数: $it") + } + detail.connectedHdcpLevel?.let { + appendLine("当前HDCP级别: ${AndInfo.instance.drm.getHdcpLevelDescription(it)}") + } + detail.maxHdcpLevel?.let { + appendLine("最高HDCP级别: ${AndInfo.instance.drm.getHdcpLevelDescription(it)}") + } + } + + println(info) + } +} +``` + +## DRMDetail 数据类说明 + +```kotlin +data class DRMDetail( + val uuid: String, // DRM方案的UUID + val name: String, // DRM方案名称(如"Widevine Content Protection") + val vendor: String?, // 供应商(如"Google") + val version: String?, // 版本号 + val description: String?, // 描述信息 + val algorithms: List?, // 支持的加密算法列表(如["AES/CBC/NoPadding"]) + val deviceUniqueId: String?, // 设备唯一ID(十六进制字符串) + val securityLevel: String?, // 安全级别(如"L1"、"L3") + val systemId: String?, // 系统ID + val openSessionCount: Int?, // 当前打开的会话数(Android 9及以上) + val maxSessionCount: Int?, // 最大会话数(Android 9及以上) + val connectedHdcpLevel: Int?, // 当前连接的HDCP级别(Android 9及以上) + val maxHdcpLevel: Int?, // 最高支持的HDCP级别(Android 9及以上) +) +``` + +## HDCP级别说明 + +HDCP (High-bandwidth Digital Content Protection) 高带宽数字内容保护 + +| 级别 | 名称 | 说明 | +|-----|------|------| +| 0 | HDCP_NONE | 无HDCP保护 | +| 1 | HDCP_V1 | HDCP 1.x | +| 2 | HDCP_V2 | HDCP 2.0 | +| 3 | HDCP_V2_1 | HDCP 2.1 | +| 4 | HDCP_V2_2 | HDCP 2.2 | +| 5 | HDCP_V2_3 | HDCP 2.3 | +| 255 | HDCP_NO_DIGITAL_OUTPUT | 无数字输出 | + +## 常用DRM方案UUID + +```kotlin +// Widevine DRM (Google) +DRMInfo.WIDEVINE_UUID = "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" + +// Microsoft PlayReady +DRMInfo.PLAYREADY_UUID = "9a04f079-9840-4286-ab92-e65be0885f95" + +// ClearKey DASH-IF +DRMInfo.CLEARKEY_UUID = "e2719d58-a985-b3c9-781a-b030af78d30e" +``` + +## 支持的DRM方案 + +DRMInfo支持以下29种DRM方案的识别: + +1. ABV DRM (MoDRM) +2. Adobe Primetime DRM v4 +3. Alticast +4. Apple FairPlay +5. Arris Titanium +6. ChinaDRM +7. ClearKey (多种变体) +8. CMLA (OMA DRM) +9. Commscope Titanium V3 +10. CoreCrypt +11. DigiCAP SmartXess +12. DivX DRM Series 5 +13. Irdeto Content Protection +14. Marlin Adaptive Streaming +15. Microsoft PlayReady +16. MobiTV DRM +17. Nagra MediaAccess PRM 3.0 +18. SecureMedia +19. Synamedia/Cisco/NDS VideoGuard DRM +20. Unitend DRM (UDRM) +21. Verimatrix VCAS +22. Viaccess-Orca DRM (VODRM) +23. VisionCrypt +24. W3C Common PSSH box +25. Widevine Content Protection + +## 注意事项 + +1. 不同设备支持的DRM方案可能不同 +2. 某些DRM信息可能需要特定权限才能访问 +3. Android 9 (API 28) 以下版本不支持会话数和HDCP级别信息 +4. 设备唯一ID可能在某些设备上不可用 +5. Widevine安全级别: + - L1: 最高安全级别,支持硬件级别的内容保护 + - L3: 软件级别的内容保护 + +## 示例输出 + +``` +=== Widevine Content Protection === +UUID: edef8ba9-79d6-4ace-a3c8-27dcd51d21ed +供应商: Google +版本: 16.1.0 +安全级别: L1 +最高HDCP级别: HDCP_V2_2 (2.2) +支持的算法: AES/CBC/NoPadding +设备唯一ID: a1b2c3d4e5f6... +``` + diff --git a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/AndInfo.kt b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/AndInfo.kt index d6be7d1..668d243 100644 --- a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/AndInfo.kt +++ b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/AndInfo.kt @@ -12,6 +12,7 @@ import com.xyzshell.andinfo.libs.InputInfo import com.xyzshell.andinfo.libs.CameraInfo import com.xyzshell.andinfo.libs.BluetoothInfo import com.xyzshell.andinfo.libs.StorageInfo +import com.xyzshell.andinfo.libs.DRMInfo class AndInfo private constructor(private val applicationContext: Context) { @@ -42,6 +43,7 @@ class AndInfo private constructor(private val applicationContext: Context) { private val _bluetooth: BluetoothInfo private val _storage: StorageInfo private val _app: AppInfo + private val _drm: DRMInfo init { _cpu = CpuInfo() @@ -55,6 +57,7 @@ class AndInfo private constructor(private val applicationContext: Context) { _bluetooth = BluetoothInfo(applicationContext) _storage = StorageInfo(applicationContext) _app = AppInfo(applicationContext) + _drm = DRMInfo(applicationContext) } val cpu get() = _cpu @@ -69,5 +72,6 @@ class AndInfo private constructor(private val applicationContext: Context) { val storage get() = _storage val context get() = applicationContext val app get() = _app + val drm get() = _drm } diff --git a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/BuildInfo.kt b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/BuildInfo.kt index a3aa6fc..89abd9b 100644 --- a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/BuildInfo.kt +++ b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/BuildInfo.kt @@ -1,11 +1,18 @@ package com.xyzshell.andinfo.libs import android.content.Context +import android.content.pm.PackageManager import android.os.Build +import android.provider.Settings // import androidx.security.state.SecurityStateManagerCompat +import java.io.BufferedReader +import java.io.File +import java.io.InputStreamReader import java.util.Date +import java.util.Locale +import java.util.TimeZone -/** + /** * 系统构建信息工具类 * 提供 Android 系统构建版本、编译信息、安全补丁、JVM 信息等 */ @@ -212,13 +219,6 @@ class BuildInfo(private val context: Context) { val vendorSecurityPatchLevel: String? get() = null // globalSecurityState.getString(SecurityStateManagerCompat.KEY_VENDOR_SPL) - /** - * 内核版本 - * 需要 SecurityStateManagerCompat 支持 - * 示例: "5.10.157" - */ - val kernelVersion: String? - get() = null // globalSecurityState.getString(SecurityStateManagerCompat.KEY_KERNEL_VERSION) /** * 完整内核版本 @@ -270,6 +270,408 @@ class BuildInfo(private val context: Context) { */ data class PartitionInfo(val name: String, val fingerprint: String) + // ==================== Treble 和系统更新 ==================== + + /** + * 是否支持 Treble + * Android 8.0+ 引入的项目,将供应商实现与 Android OS 框架分离 + * 通过检查 ro.treble.enabled 属性判断 + */ + val isTrebleEnabled: Boolean + get() = getSystemProperty("ro.treble.enabled") == "true" + + /** + * Treble 版本 + * 返回 Treble 的版本号 + */ + val trebleVersion: String? + get() = getSystemProperty("ro.treble.version") + + /** + * 是否支持无缝更新(A/B 系统更新) + * Android 7.0+ 可用 + * 允许在后台安装更新,重启后即可使用新版本 + */ + val isSeamlessUpdateSupported: Boolean + get() = getSystemProperty("ro.build.ab_update") == "true" + + /** + * 当前活动插槽 + * A/B 系统分区中当前活动的插槽(slot_a 或 slot_b) + * 仅在支持 A/B 更新的设备上有效 + */ + val currentSlot: String? + get() = getSystemProperty("ro.boot.slot_suffix")?.removePrefix("_") + + /** + * 虚拟 A/B 支持 + * Android 11+ 的新功能,使用动态分区实现 A/B 更新 + */ + val isVirtualABEnabled: Boolean + get() = getSystemProperty("ro.virtual_ab.enabled") == "true" + + // ==================== Root 权限和安全 ==================== + + /** + * 检查设备是否已 Root + * 通过多种方法检测 Root 状态 + */ + val isRooted: Boolean + get() = checkRootAccess() + + /** + * Root 检测方法 + * 检查常见的 Root 工具和文件 + */ + private fun checkRootAccess(): Boolean { + // 检查常见的 Root 二进制文件 + val rootPaths = arrayOf( + "/system/app/Superuser.apk", + "/sbin/su", + "/system/bin/su", + "/system/xbin/su", + "/data/local/xbin/su", + "/data/local/bin/su", + "/system/sd/xbin/su", + "/system/bin/failsafe/su", + "/data/local/su", + "/su/bin/su" + ) + + for (path in rootPaths) { + if (File(path).exists()) { + return true + } + } + + // 尝试执行 su 命令 + return try { + Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su")) + true + } catch (_: Exception) { + false + } + } + + /** + * SELinux 状态 + * 返回 SELinux 的当前模式:Enforcing、Permissive 或 Disabled + */ + val seLinuxStatus: String + get() = getSystemProperty("ro.build.selinux") ?: "Unknown" + + /** + * 是否启用 dm-verity + * 验证系统分区完整性的内核功能 + */ + val isDmVerityEnabled: Boolean + get() = getSystemProperty("ro.boot.veritymode") == "enforcing" + + // ==================== Google Play 服务 ==================== + + /** + * Google Play 服务版本名称 + * 示例: "23.45.12 (190400-582679489)" + */ + val googlePlayServicesVersion: String? + get() = getPackageVersion("com.google.android.gms") + + /** + * Google Play 服务版本代码 + */ + val googlePlayServicesVersionCode: Long? + get() = getPackageVersionCode("com.google.android.gms") + + /** + * Google Play Store 版本 + */ + val googlePlayStoreVersion: String? + get() = getPackageVersion("com.android.vending") + + /** + * Google Services Framework 版本 + */ + val googleServicesFrameworkVersion: String? + get() = getPackageVersion("com.google.android.gsf") + + /** + * 获取包版本名称 + */ + private fun getPackageVersion(packageName: String): String? { + return try { + val packageInfo = context.packageManager.getPackageInfo(packageName, 0) + packageInfo.versionName + } catch (_: PackageManager.NameNotFoundException) { + null + } + } + + /** + * 获取包版本代码 + */ + private fun getPackageVersionCode(packageName: String): Long? { + return try { + val packageInfo = context.packageManager.getPackageInfo(packageName, 0) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + packageInfo.longVersionCode + } else { + @Suppress("DEPRECATION") + packageInfo.versionCode.toLong() + } + } catch (_: PackageManager.NameNotFoundException) { + null + } + } + + // ==================== Toybox 和工具版本 ==================== + + /** + * Toybox 版本 + * Toybox 是 Android 的 Unix 命令行工具集合 + */ + val toyboxVersion: String? + get() = executeCommand("toybox --version")?.trim() + + /** + * Toolbox 版本(旧版 Android 使用) + */ + val toolboxVersion: String? + get() = executeCommand("toolbox --version")?.trim() + + /** + * BusyBox 版本(如果安装) + */ + val busyboxVersion: String? + get() = executeCommand("busybox --version")?.split("\n")?.firstOrNull()?.trim() + + // ==================== SSL/TLS 信息 ==================== + + /** + * OpenSSL 版本 + * 示例: "OpenSSL 1.1.1t 7 Feb 2023" + */ + val openSslVersion: String? + get() = executeCommand("openssl version")?.trim() + + /** + * BoringSSL 版本信息 + * Android 使用 Google 的 BoringSSL + */ + val boringSslVersion: String? + get() = getSystemProperty("ro.build.version.boringssl") + + /** + * TLS 版本支持 + * 从系统属性获取支持的 TLS 版本 + */ + val tlsVersion: String? + get() = try { + javax.net.ssl.SSLContext.getDefault().supportedSSLParameters.protocols.joinToString(", ") + } catch (_: Exception) { + null + } + + // ==================== 语言和时区 ==================== + + /** + * 系统语言 + * 示例: "中文(简体)", "English" + */ + val systemLanguage: String + get() = Locale.getDefault().displayLanguage + + /** + * 语言代码 + * 示例: "zh", "en" + */ + val languageCode: String + get() = Locale.getDefault().language + + /** + * 国家/地区 + * 示例: "中国", "United States" + */ + val country: String + get() = Locale.getDefault().displayCountry + + /** + * 国家/地区代码 + * 示例: "CN", "US" + */ + val countryCode: String + get() = Locale.getDefault().country + + /** + * 系统时区 + * 示例: "Asia/Shanghai", "America/New_York" + */ + val timeZone: String + get() = TimeZone.getDefault().id + + /** + * 时区显示名称 + * 示例: "中国标准时间", "Eastern Standard Time" + */ + val timeZoneDisplayName: String + get() = TimeZone.getDefault().displayName + + /** + * UTC 偏移(毫秒) + */ + val timeZoneOffset: Int + get() = TimeZone.getDefault().rawOffset + + // ==================== 开发者选项和调试 ==================== + + /** + * USB 调试是否启用 + * 需要在开发者选项中开启 + */ + val isUsbDebuggingEnabled: Boolean + get() = Settings.Global.getInt(context.contentResolver, Settings.Global.ADB_ENABLED, 0) == 1 + + /** + * 开发者选项是否启用 + */ + val isDevelopmentSettingsEnabled: Boolean + get() = Settings.Global.getInt( + context.contentResolver, + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, + 0 + ) == 1 + + /** + * 是否允许未知来源安装 + * Android 8.0+ 改为针对每个应用 + */ + val isUnknownSourcesEnabled: Boolean + get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + context.packageManager.canRequestPackageInstalls() + } else { + @Suppress("DEPRECATION") + Settings.Secure.getInt(context.contentResolver, Settings.Secure.INSTALL_NON_MARKET_APPS, 0) == 1 + } + + // ==================== 内核信息 ==================== + + /** + * 内核版本号 + * 示例: "5.10.157" + */ + val kernelVersion: String? + get() = kernelCompleteVersion?.split("-")?.firstOrNull() + + /** + * 内核架构 + * 示例: "aarch64", "x86_64" + */ + val kernelArchitecture: String? + get() = System.getProperty("os.arch") + + /** + * 内核名称 + * 通常为 "Linux" + */ + val kernelName: String? + get() = System.getProperty("os.name") + + /** + * 命令行参数 + * 内核启动时的命令行参数 + */ + val kernelCommandLine: String? + get() = readFile("/proc/cmdline") + + /** + * CPU 信息(从 /proc/cpuinfo) + */ + val procCpuInfo: String? + get() = readFile("/proc/cpuinfo") + + /** + * 内存信息(从 /proc/meminfo) + */ + val procMemInfo: String? + get() = readFile("/proc/meminfo") + + // ==================== 设备标识符 ==================== + + /** + * Android ID + * 64位十六进制字符串,设备首次启动时随机生成 + * 出厂重置后会改变 + */ + val androidId: String + get() = Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID) ?: "unknown" + + /** + * 构建序列号 + * Android 8.0+ 需要 READ_PHONE_STATE 权限 + */ + val serialNumber: String + get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try { + @Suppress("MissingPermission", "HardwareIds") + Build.getSerial() + } catch (_: SecurityException) { + "需要权限" + } + } else { + @Suppress("DEPRECATION", "HardwareIds") + Build.SERIAL + } + + /** + * 设备唯一标识符(基于多个参数生成) + */ + val deviceUniqueId: String + get() = "${Build.BOARD}:${Build.BRAND}:${Build.DEVICE}:${androidId}".hashCode().toString() + + // ==================== 辅助方法 ==================== + + /** + * 获取系统属性 + * 使用反射调用 SystemProperties.get() + */ + private fun getSystemProperty(key: String): String? { + return try { + @Suppress("PrivateApi") + val systemProperties = Class.forName("android.os.SystemProperties") + val method = systemProperties.getMethod("get", String::class.java) + method.invoke(null, key) as? String + } catch (_: Exception) { + null + } + } + + /** + * 执行 shell 命令并返回输出 + */ + private fun executeCommand(command: String): String? { + return try { + val process = Runtime.getRuntime().exec(command) + val reader = BufferedReader(InputStreamReader(process.inputStream)) + val output = reader.readText() + process.waitFor() + reader.close() + output.takeIf { it.isNotEmpty() } + } catch (_: Exception) { + null + } + } + + /** + * 读取文件内容 + */ + private fun readFile(path: String): String? { + return try { + File(path).readText().trim() + } catch (_: Exception) { + null + } + } + + // ==================== 辅助方法 ==================== /** @@ -306,6 +708,53 @@ class BuildInfo(private val context: Context) { sb.append("基础OS: $baseOs\n") } + // Treble 和系统更新 + sb.append("\n=== Treble 和系统更新 ===\n") + sb.append("Treble支持: ${if (isTrebleEnabled) "是" else "否"}\n") + trebleVersion?.let { sb.append("Treble版本: $it\n") } + sb.append("无缝更新(A/B): ${if (isSeamlessUpdateSupported) "是" else "否"}\n") + currentSlot?.let { sb.append("当前活动插槽: $it\n") } + sb.append("虚拟A/B: ${if (isVirtualABEnabled) "是" else "否"}\n") + + // Root 和安全 + sb.append("\n=== Root 和安全 ===\n") + sb.append("Root状态: ${if (isRooted) "已Root" else "未Root"}\n") + sb.append("SELinux状态: $seLinuxStatus\n") + sb.append("dm-verity: ${if (isDmVerityEnabled) "启用" else "禁用"}\n") + + // Google 服务 + sb.append("\n=== Google 服务 ===\n") + googlePlayServicesVersion?.let { sb.append("Play服务版本: $it\n") } + googlePlayServicesVersionCode?.let { sb.append("Play服务版本代码: $it\n") } + googlePlayStoreVersion?.let { sb.append("Play商店版本: $it\n") } + googleServicesFrameworkVersion?.let { sb.append("GSF版本: $it\n") } + + // 工具版本 + sb.append("\n=== 系统工具 ===\n") + toyboxVersion?.let { sb.append("Toybox: $it\n") } + toolboxVersion?.let { sb.append("Toolbox: $it\n") } + busyboxVersion?.let { sb.append("BusyBox: $it\n") } + + // SSL/TLS + sb.append("\n=== SSL/TLS ===\n") + openSslVersion?.let { sb.append("OpenSSL: $it\n") } + boringSslVersion?.let { sb.append("BoringSSL: $it\n") } + tlsVersion?.let { sb.append("TLS支持: $it\n") } + + // 语言和时区 + sb.append("\n=== 语言和时区 ===\n") + sb.append("系统语言: $systemLanguage ($languageCode)\n") + sb.append("国家/地区: $country ($countryCode)\n") + sb.append("时区: $timeZone\n") + sb.append("时区显示: $timeZoneDisplayName\n") + sb.append("UTC偏移: ${timeZoneOffset / 3600000}小时\n") + + // 开发者选项 + sb.append("\n=== 开发者选项 ===\n") + sb.append("USB调试: ${if (isUsbDebuggingEnabled) "启用" else "禁用"}\n") + sb.append("开发者选项: ${if (isDevelopmentSettingsEnabled) "启用" else "禁用"}\n") + sb.append("未知来源: ${if (isUnknownSourcesEnabled) "允许" else "禁止"}\n") + // JVM 信息 sb.append("\n=== JVM 信息 ===\n") jvmName?.let { sb.append("JVM名称: $it\n") } @@ -315,11 +764,23 @@ class BuildInfo(private val context: Context) { jvmSpecificationName?.let { sb.append("规范名称: $it\n") } jvmSpecificationVersion?.let { sb.append("规范版本: $it\n") } + // 内核信息 + sb.append("\n=== 内核信息 ===\n") + kernelName?.let { sb.append("内核名称: $it\n") } + kernelVersion?.let { sb.append("内核版本: $it\n") } + kernelArchitecture?.let { sb.append("内核架构: $it\n") } + kernelCompleteVersion?.let { sb.append("完整版本: $it\n") } + // 硬件信息 sb.append("\n=== 硬件信息 ===\n") sb.append("Bootloader: $bootloaderVersion\n") radioVersion?.let { sb.append("基带版本: $it\n") } - kernelCompleteVersion?.let { sb.append("内核版本: $it\n") } + + // 设备标识符 + sb.append("\n=== 设备标识符 ===\n") + sb.append("Android ID: $androidId\n") + sb.append("序列号: $serialNumber\n") + sb.append("设备唯一ID: $deviceUniqueId\n") // 分区信息 if (fingerprintedPartitions.isNotEmpty()) { diff --git a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DRMInfo.kt b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DRMInfo.kt new file mode 100644 index 0000000..39ac5af --- /dev/null +++ b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DRMInfo.kt @@ -0,0 +1,231 @@ +package com.xyzshell.andinfo.libs + +import android.content.Context +import android.media.MediaDrm +import android.os.Build +import java.util.UUID + +/** + * DRM(数字版权管理)信息工具类 + * 提供设备支持的DRM方案信息,包括Widevine、PlayReady等 + */ +class DRMInfo(private val context: Context) { + + /** + * DRM详细信息数据类 + */ + data class DRMDetail( + val uuid: String, // DRM方案的UUID + val name: String, // DRM方案名称 + val vendor: String?, // 供应商 + val version: String?, // 版本号 + val description: String?, // 描述信息 + val algorithms: List?, // 支持的加密算法列表 + val deviceUniqueId: String?, // 设备唯一ID(十六进制) + val securityLevel: String?, // 安全级别(如L1、L3等) + val systemId: String?, // 系统ID + val openSessionCount: Int?, // 当前打开的会话数(Android 9及以上) + val maxSessionCount: Int?, // 最大会话数(Android 9及以上) + val connectedHdcpLevel: Int?, // 当前连接的HDCP级别(Android 9及以上) + val maxHdcpLevel: Int?, // 最高支持的HDCP级别(Android 9及以上) + ) + + /** + * 获取所有支持的DRM方案列表 + * @return DRM UUID列表 + */ + fun getSupportedDrmSchemes(): List { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // Android 11及以上使用官方API + MediaDrm.getSupportedCryptoSchemes().toList() + } else { + // Android 11以下遍历已知的DRM方案 + CONTENT_PROTECTION_SCHEMES.keys.filter { uuid -> + try { + val mediaDrm = MediaDrm(uuid) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + mediaDrm.close() + } else { + @Suppress("DEPRECATION") + mediaDrm.release() + } + true + } catch (e: Exception) { + false + } + } + } + } + + /** + * 获取指定UUID的DRM详细信息 + * @param uuid DRM方案的UUID + * @return DRM详细信息,如果不支持则返回null + */ + fun getDrmDetail(uuid: UUID): DRMDetail? { + val mediaDrm = try { + MediaDrm(uuid) + } catch (e: Exception) { + return null + } + + return try { + val name = CONTENT_PROTECTION_SCHEMES[uuid] ?: "Unknown DRM Scheme" + + DRMDetail( + uuid = uuid.toString(), + name = name, + vendor = getPropertyStringSafe(mediaDrm, MediaDrm.PROPERTY_VENDOR), + version = getPropertyStringSafe(mediaDrm, MediaDrm.PROPERTY_VERSION), + description = getPropertyStringSafe(mediaDrm, MediaDrm.PROPERTY_DESCRIPTION), + algorithms = getPropertyStringSafe(mediaDrm, MediaDrm.PROPERTY_ALGORITHMS) + ?.split(",") + ?.filter { it.isNotEmpty() }, + deviceUniqueId = getPropertyByteArraySafe(mediaDrm, MediaDrm.PROPERTY_DEVICE_UNIQUE_ID) + ?.toHexString(), + securityLevel = getPropertyStringSafe(mediaDrm, "securityLevel"), + systemId = getPropertyStringSafe(mediaDrm, "systemId"), + openSessionCount = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + mediaDrm.openSessionCount + } catch (e: Exception) { + null + } + } else null, + maxSessionCount = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + mediaDrm.maxSessionCount + } catch (e: Exception) { + null + } + } else null, + connectedHdcpLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + mediaDrm.connectedHdcpLevel + } catch (e: Exception) { + null + } + } else null, + maxHdcpLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + try { + mediaDrm.maxHdcpLevel + } catch (e: Exception) { + null + } + } else null, + ) + } finally { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + mediaDrm.close() + } else { + @Suppress("DEPRECATION") + mediaDrm.release() + } + } + } + + /** + * 获取所有支持的DRM方案的详细信息 + * @return DRM详细信息列表 + */ + fun getAllDrmDetails(): List { + return getSupportedDrmSchemes().mapNotNull { uuid -> + getDrmDetail(uuid) + } + } + + /** + * 安全地获取MediaDrm字符串属性 + */ + private fun getPropertyStringSafe(mediaDrm: MediaDrm, property: String): String? { + return try { + mediaDrm.getPropertyString(property) + } catch (e: Exception) { + null + } + } + + /** + * 安全地获取MediaDrm字节数组属性 + */ + private fun getPropertyByteArraySafe(mediaDrm: MediaDrm, property: String): ByteArray? { + return try { + mediaDrm.getPropertyByteArray(property) + } catch (e: Exception) { + null + } + } + + /** + * 字节数组转十六进制字符串 + */ + private fun ByteArray.toHexString(): String { + return joinToString("") { "%02x".format(it) } + } + + /** + * 根据HDCP级别获取描述 + */ + fun getHdcpLevelDescription(level: Int): String { + return HDCP_LEVEL_NAMES[level] ?: "Unknown ($level)" + } + + companion object { + /** + * 已知的内容保护方案UUID和名称映射 + * 来源: DASH-IF (https://dashif.org/identifiers/content_protection/) + */ + val CONTENT_PROTECTION_SCHEMES = mapOf( + UUID.fromString("6dd8b3c3-45f4-4a68-bf3a-64168d01a4a6") to "ABV DRM (MoDRM)", + UUID.fromString("f239e769-efa3-4850-9c16-a903c6932efb") to "Adobe Primetime DRM v4", + UUID.fromString("616c7469-6361-7374-2d50-726f74656374") to "Alticast", + UUID.fromString("94ce86fb-07ff-4f43-adb8-93d2fa968ca2") to "Apple FairPlay", + UUID.fromString("29701fe4-3cc7-4a34-8c5b-ae90c7439a47") to "Apple FairPlay (非官方)", + UUID.fromString("279fe473-512c-48fe-ade8-d176fee6b40f") to "Arris Titanium", + UUID.fromString("3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c") to "ChinaDRM", + UUID.fromString("3ea8778f-7742-4bf9-b18b-e834b2acbd47") to "ClearKey AES-128", + UUID.fromString("be58615b-19c4-4684-88b3-c8c57e99e957") to "ClearKey SAMPLE-AES", + UUID.fromString("e2719d58-a985-b3c9-781a-b030af78d30e") to "ClearKey DASH-IF", + UUID.fromString("644fe7b5-260f-4fad-949a-0762ffb054B4") to "CMLA (OMA DRM)", + UUID.fromString("37c33258-7b99-4c7e-b15d-19af74482154") to "Commscope Titanium V3", + UUID.fromString("45d481cb-8fe0-49c0-ada9-ab2d2455b2f2") to "CoreCrypt", + UUID.fromString("dcf4e3e3-62f1-5818-7ba6-0a6fe33ff3dd") to "DigiCAP SmartXess", + UUID.fromString("35bf197b-530e-42d7-8b65-1b4bf415070f") to "DivX DRM Series 5", + UUID.fromString("80a6be7e-1448-4c37-9e70-d5aebe04c8d2") to "Irdeto Content Protection", + UUID.fromString("5e629af5-38da-4063-8977-97ffbd9902d4") to "Marlin Adaptive Streaming Simple Profile V1.0", + UUID.fromString("9a04f079-9840-4286-ab92-e65be0885f95") to "Microsoft PlayReady", + UUID.fromString("6a99532d-869f-5922-9a91-113ab7b1e2f3") to "MobiTV DRM", + UUID.fromString("adb41c24-2dbf-4a6d-958b-4457c0d27b95") to "Nagra MediaAccess PRM 3.0", + UUID.fromString("1f83e1e8-6ee9-4f0d-ba2f-5ec4e3ed1a66") to "SecureMedia", + UUID.fromString("992c46e6-c437-4899-b6a0-50fa91ad0e39") to "SecureMedia SteelKnot", + UUID.fromString("a68129d3-575b-4f1a-9cba-3223846cf7c3") to "Synamedia/Cisco/NDS VideoGuard DRM", + UUID.fromString("aa11967f-cc01-4a4a-8e99-c5d3dddfea2d") to "Unitend DRM (UDRM)", + UUID.fromString("9a27dd82-fde2-4725-8cbc-4234aa06ec09") to "Verimatrix VCAS", + UUID.fromString("b4413586-c58c-ffb0-94a5-d4896c1af6c3") to "Viaccess-Orca DRM (VODRM)", + UUID.fromString("793b7956-9f94-4946-a942-23e7ef7e44b4") to "VisionCrypt", + UUID.fromString("1077efec-c0b2-4d02-ace3-3c1e52e2fb4b") to "W3C Common PSSH box", + UUID.fromString("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed") to "Widevine Content Protection", + ) + + /** + * HDCP级别名称映射 + * HDCP (High-bandwidth Digital Content Protection) 高带宽数字内容保护 + */ + val HDCP_LEVEL_NAMES = mapOf( + 0 to "HDCP_NONE (无)", + 1 to "HDCP_V1 (1.x)", + 2 to "HDCP_V2 (2.0)", + 3 to "HDCP_V2_1 (2.1)", + 4 to "HDCP_V2_2 (2.2)", + 5 to "HDCP_V2_3 (2.3)", + 255 to "HDCP_NO_DIGITAL_OUTPUT (无数字输出)", + ) + + /** + * 常用的DRM UUID常量 + */ + val WIDEVINE_UUID = UUID.fromString("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed") + val PLAYREADY_UUID = UUID.fromString("9a04f079-9840-4286-ab92-e65be0885f95") + val CLEARKEY_UUID = UUID.fromString("e2719d58-a985-b3c9-781a-b030af78d30e") + } +} \ No newline at end of file diff --git a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DeviceInfo.kt b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DeviceInfo.kt index 74b114b..223b268 100644 --- a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DeviceInfo.kt +++ b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/DeviceInfo.kt @@ -4,43 +4,60 @@ import android.app.ActivityManager import android.content.Context import android.os.Build +// 设备信息工具类 class DeviceInfo(private val context: Context) { + // ActivityManager 用于获取内存等系统服务 private val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager + // 设备代号 val device: String get() = Build.DEVICE + // 品牌 val brand: String get() = Build.BRAND + // 机型 val model: String get() = Build.MODEL + // 制造商 val manufacturer: String get() = Build.MANUFACTURER + // 产品名称 val productName: String get() = Build.PRODUCT + // 硬件名称 val hardwareName: String get() = Build.HARDWARE + // 主板名称 val boardName: String get() = Build.BOARD + // 硬件SKU(Android 12及以上) val hardwareSku: String? get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SKU else null + // ODM SKU(Android 12及以上) val odmSku: String? get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.ODM_SKU else null + // SoC制造商(Android 12及以上) val socManufacturer: String? get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MANUFACTURER else null + // SoC型号(Android 12及以上) val socModel: String? get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MODEL else null + /** + * 获取内存信息 + * @return ActivityManager.MemoryInfo 内存信息对象 + */ fun getMemoryInfo(): ActivityManager.MemoryInfo { val memoryInfo = ActivityManager.MemoryInfo() activityManager.getMemoryInfo(memoryInfo) diff --git a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/SensorInfo.kt b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/SensorInfo.kt index f79a836..6c18661 100644 --- a/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/SensorInfo.kt +++ b/myphoneinfo/andinfo/src/main/java/com/xyzshell/andinfo/libs/SensorInfo.kt @@ -7,37 +7,52 @@ import android.hardware.SensorManager import android.os.Build import androidx.annotation.RequiresApi +// 传感器信息工具类 class SensorInfo(private val context: Context) { + // 传感器管理器 private val sensorManager = context.getSystemService(SensorManager::class.java) + /** + * 获取所有传感器列表 + * @return 传感器列表 + */ fun getAllSensors(): List { return sensorManager.getSensorList(Sensor.TYPE_ALL) } + /** + * 获取单个传感器的详细信息 + * @param sensor 传感器对象 + * @return 传感器详细信息数据类 + */ fun getSensorDetail(sensor: Sensor): SensorDetail { return SensorDetail( - name = sensor.name, - id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.id.takeIf { it > 0 } else null, - stringType = sensor.stringType, - type = sensor.type, - vendor = sensor.vendor, - version = sensor.version, - isDynamicSensor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isDynamicSensor else false, - isWakeUpSensor = sensor.isWakeUpSensor, - fifoMaxEventCount = sensor.fifoMaxEventCount, - fifoReservedEventCount = sensor.fifoReservedEventCount, - minDelay = sensor.minDelay, - maxDelay = sensor.maxDelay, - maximumRange = sensor.maximumRange, - power = sensor.power, - reportingMode = sensor.reportingMode, - resolution = sensor.resolution, - isAdditionalInfoSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isAdditionalInfoSupported else false, - highestDirectReportRateLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) sensor.highestDirectReportRateLevel else SensorDirectChannel.RATE_STOP + name = sensor.name, // 传感器名称 + id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.id.takeIf { it > 0 } else null, // 传感器ID(Android N及以上) + stringType = sensor.stringType, // 传感器类型字符串 + type = sensor.type, // 传感器类型 + vendor = sensor.vendor, // 供应商 + version = sensor.version, // 版本号 + isDynamicSensor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isDynamicSensor else false, // 是否为动态传感器 + isWakeUpSensor = sensor.isWakeUpSensor, // 是否为唤醒传感器 + fifoMaxEventCount = sensor.fifoMaxEventCount, // FIFO最大事件数 + fifoReservedEventCount = sensor.fifoReservedEventCount, // FIFO保留事件数 + minDelay = sensor.minDelay, // 最小延迟(微秒) + maxDelay = sensor.maxDelay, // 最大延迟(微秒) + maximumRange = sensor.maximumRange, // 最大量程 + power = sensor.power, // 功耗(mA) + reportingMode = sensor.reportingMode, // 报告模式 + resolution = sensor.resolution, // 分辨率 + isAdditionalInfoSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isAdditionalInfoSupported else false, // 是否支持附加信息 + highestDirectReportRateLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) sensor.highestDirectReportRateLevel else SensorDirectChannel.RATE_STOP // 最高直报速率等级 ) } + /** + * 判断是否支持动态传感器发现 + * @return 是否支持 + */ fun isDynamicSensorDiscoverySupported(): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { sensorManager.isDynamicSensorDiscoverySupported @@ -46,28 +61,32 @@ class SensorInfo(private val context: Context) { } } + /** + * 传感器详细信息数据类 + */ data class SensorDetail( - val name: String, - val id: Int?, - val stringType: String, - val type: Int, - val vendor: String, - val version: Int, - val isDynamicSensor: Boolean, - val isWakeUpSensor: Boolean, - val fifoMaxEventCount: Int, - val fifoReservedEventCount: Int, - val minDelay: Int, - val maxDelay: Int, - val maximumRange: Float, - val power: Float, - val reportingMode: Int, - val resolution: Float, - val isAdditionalInfoSupported: Boolean, - val highestDirectReportRateLevel: Int + val name: String, // 传感器名称 + val id: Int?, // 传感器ID + val stringType: String, // 类型字符串 + val type: Int, // 类型 + val vendor: String, // 供应商 + val version: Int, // 版本 + val isDynamicSensor: Boolean, // 是否动态 + val isWakeUpSensor: Boolean, // 是否唤醒 + val fifoMaxEventCount: Int, // FIFO最大事件数 + val fifoReservedEventCount: Int, // FIFO保留事件数 + val minDelay: Int, // 最小延迟 + val maxDelay: Int, // 最大延迟 + val maximumRange: Float, // 最大量程 + val power: Float, // 功耗 + val reportingMode: Int, // 报告模式 + val resolution: Float, // 分辨率 + val isAdditionalInfoSupported: Boolean, // 是否支持附加信息 + val highestDirectReportRateLevel: Int // 最高直报速率等级 ) companion object { + // 传感器报告模式对应中文 val sensorReportingModeToStringResId = mapOf( Sensor.REPORTING_MODE_CONTINUOUS to "连续", Sensor.REPORTING_MODE_ON_CHANGE to "变化时", @@ -75,6 +94,7 @@ class SensorInfo(private val context: Context) { Sensor.REPORTING_MODE_SPECIAL_TRIGGER to "特殊触发", ) + // 直通通道速率等级对应中文(Android O及以上) @RequiresApi(Build.VERSION_CODES.O) val sensorDirectReportModeRatesToStringResId = mapOf( SensorDirectChannel.RATE_STOP to "停止",