完善注释,系统信息
This commit is contained in:
parent
22f16d7595
commit
8bb298599b
403
BuildInfo新增功能使用示例.md
Normal file
403
BuildInfo新增功能使用示例.md
Normal file
@ -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<TextView>(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调试状态 ✅
|
||||||
|
- 内核信息 ✅
|
||||||
|
- 设备标识符 ✅
|
||||||
|
- 详细中文注释 ✅
|
||||||
|
|
||||||
235
DRMInfo使用示例.md
Normal file
235
DRMInfo使用示例.md
Normal file
@ -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<String>?, // 支持的加密算法列表(如["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...
|
||||||
|
```
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ import com.xyzshell.andinfo.libs.InputInfo
|
|||||||
import com.xyzshell.andinfo.libs.CameraInfo
|
import com.xyzshell.andinfo.libs.CameraInfo
|
||||||
import com.xyzshell.andinfo.libs.BluetoothInfo
|
import com.xyzshell.andinfo.libs.BluetoothInfo
|
||||||
import com.xyzshell.andinfo.libs.StorageInfo
|
import com.xyzshell.andinfo.libs.StorageInfo
|
||||||
|
import com.xyzshell.andinfo.libs.DRMInfo
|
||||||
|
|
||||||
class AndInfo private constructor(private val applicationContext: Context) {
|
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 _bluetooth: BluetoothInfo
|
||||||
private val _storage: StorageInfo
|
private val _storage: StorageInfo
|
||||||
private val _app: AppInfo
|
private val _app: AppInfo
|
||||||
|
private val _drm: DRMInfo
|
||||||
|
|
||||||
init {
|
init {
|
||||||
_cpu = CpuInfo()
|
_cpu = CpuInfo()
|
||||||
@ -55,6 +57,7 @@ class AndInfo private constructor(private val applicationContext: Context) {
|
|||||||
_bluetooth = BluetoothInfo(applicationContext)
|
_bluetooth = BluetoothInfo(applicationContext)
|
||||||
_storage = StorageInfo(applicationContext)
|
_storage = StorageInfo(applicationContext)
|
||||||
_app = AppInfo(applicationContext)
|
_app = AppInfo(applicationContext)
|
||||||
|
_drm = DRMInfo(applicationContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cpu get() = _cpu
|
val cpu get() = _cpu
|
||||||
@ -69,5 +72,6 @@ class AndInfo private constructor(private val applicationContext: Context) {
|
|||||||
val storage get() = _storage
|
val storage get() = _storage
|
||||||
val context get() = applicationContext
|
val context get() = applicationContext
|
||||||
val app get() = _app
|
val app get() = _app
|
||||||
|
val drm get() = _drm
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
package com.xyzshell.andinfo.libs
|
package com.xyzshell.andinfo.libs
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.provider.Settings
|
||||||
// import androidx.security.state.SecurityStateManagerCompat
|
// import androidx.security.state.SecurityStateManagerCompat
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStreamReader
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.TimeZone
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统构建信息工具类
|
* 系统构建信息工具类
|
||||||
@ -212,13 +219,6 @@ class BuildInfo(private val context: Context) {
|
|||||||
val vendorSecurityPatchLevel: String?
|
val vendorSecurityPatchLevel: String?
|
||||||
get() = null // globalSecurityState.getString(SecurityStateManagerCompat.KEY_VENDOR_SPL)
|
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)
|
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")
|
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 信息
|
// JVM 信息
|
||||||
sb.append("\n=== JVM 信息 ===\n")
|
sb.append("\n=== JVM 信息 ===\n")
|
||||||
jvmName?.let { sb.append("JVM名称: $it\n") }
|
jvmName?.let { sb.append("JVM名称: $it\n") }
|
||||||
@ -315,11 +764,23 @@ class BuildInfo(private val context: Context) {
|
|||||||
jvmSpecificationName?.let { sb.append("规范名称: $it\n") }
|
jvmSpecificationName?.let { sb.append("规范名称: $it\n") }
|
||||||
jvmSpecificationVersion?.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("\n=== 硬件信息 ===\n")
|
||||||
sb.append("Bootloader: $bootloaderVersion\n")
|
sb.append("Bootloader: $bootloaderVersion\n")
|
||||||
radioVersion?.let { sb.append("基带版本: $it\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()) {
|
if (fingerprintedPartitions.isNotEmpty()) {
|
||||||
|
|||||||
@ -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<String>?, // 支持的加密算法列表
|
||||||
|
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<UUID> {
|
||||||
|
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<DRMDetail> {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,43 +4,60 @@ import android.app.ActivityManager
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
|
||||||
|
// 设备信息工具类
|
||||||
class DeviceInfo(private val context: Context) {
|
class DeviceInfo(private val context: Context) {
|
||||||
|
|
||||||
|
// ActivityManager 用于获取内存等系统服务
|
||||||
private val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
private val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||||
|
|
||||||
|
// 设备代号
|
||||||
val device: String
|
val device: String
|
||||||
get() = Build.DEVICE
|
get() = Build.DEVICE
|
||||||
|
|
||||||
|
// 品牌
|
||||||
val brand: String
|
val brand: String
|
||||||
get() = Build.BRAND
|
get() = Build.BRAND
|
||||||
|
|
||||||
|
// 机型
|
||||||
val model: String
|
val model: String
|
||||||
get() = Build.MODEL
|
get() = Build.MODEL
|
||||||
|
|
||||||
|
// 制造商
|
||||||
val manufacturer: String
|
val manufacturer: String
|
||||||
get() = Build.MANUFACTURER
|
get() = Build.MANUFACTURER
|
||||||
|
|
||||||
|
// 产品名称
|
||||||
val productName: String
|
val productName: String
|
||||||
get() = Build.PRODUCT
|
get() = Build.PRODUCT
|
||||||
|
|
||||||
|
// 硬件名称
|
||||||
val hardwareName: String
|
val hardwareName: String
|
||||||
get() = Build.HARDWARE
|
get() = Build.HARDWARE
|
||||||
|
|
||||||
|
// 主板名称
|
||||||
val boardName: String
|
val boardName: String
|
||||||
get() = Build.BOARD
|
get() = Build.BOARD
|
||||||
|
|
||||||
|
// 硬件SKU(Android 12及以上)
|
||||||
val hardwareSku: String?
|
val hardwareSku: String?
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SKU else null
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SKU else null
|
||||||
|
|
||||||
|
// ODM SKU(Android 12及以上)
|
||||||
val odmSku: String?
|
val odmSku: String?
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.ODM_SKU else null
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.ODM_SKU else null
|
||||||
|
|
||||||
|
// SoC制造商(Android 12及以上)
|
||||||
val socManufacturer: String?
|
val socManufacturer: String?
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MANUFACTURER else null
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MANUFACTURER else null
|
||||||
|
|
||||||
|
// SoC型号(Android 12及以上)
|
||||||
val socModel: String?
|
val socModel: String?
|
||||||
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MODEL else null
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Build.SOC_MODEL else null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取内存信息
|
||||||
|
* @return ActivityManager.MemoryInfo 内存信息对象
|
||||||
|
*/
|
||||||
fun getMemoryInfo(): ActivityManager.MemoryInfo {
|
fun getMemoryInfo(): ActivityManager.MemoryInfo {
|
||||||
val memoryInfo = ActivityManager.MemoryInfo()
|
val memoryInfo = ActivityManager.MemoryInfo()
|
||||||
activityManager.getMemoryInfo(memoryInfo)
|
activityManager.getMemoryInfo(memoryInfo)
|
||||||
|
|||||||
@ -7,37 +7,52 @@ import android.hardware.SensorManager
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
|
||||||
|
// 传感器信息工具类
|
||||||
class SensorInfo(private val context: Context) {
|
class SensorInfo(private val context: Context) {
|
||||||
|
|
||||||
|
// 传感器管理器
|
||||||
private val sensorManager = context.getSystemService(SensorManager::class.java)
|
private val sensorManager = context.getSystemService(SensorManager::class.java)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有传感器列表
|
||||||
|
* @return 传感器列表
|
||||||
|
*/
|
||||||
fun getAllSensors(): List<Sensor> {
|
fun getAllSensors(): List<Sensor> {
|
||||||
return sensorManager.getSensorList(Sensor.TYPE_ALL)
|
return sensorManager.getSensorList(Sensor.TYPE_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单个传感器的详细信息
|
||||||
|
* @param sensor 传感器对象
|
||||||
|
* @return 传感器详细信息数据类
|
||||||
|
*/
|
||||||
fun getSensorDetail(sensor: Sensor): SensorDetail {
|
fun getSensorDetail(sensor: Sensor): SensorDetail {
|
||||||
return SensorDetail(
|
return SensorDetail(
|
||||||
name = sensor.name,
|
name = sensor.name, // 传感器名称
|
||||||
id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.id.takeIf { it > 0 } else null,
|
id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.id.takeIf { it > 0 } else null, // 传感器ID(Android N及以上)
|
||||||
stringType = sensor.stringType,
|
stringType = sensor.stringType, // 传感器类型字符串
|
||||||
type = sensor.type,
|
type = sensor.type, // 传感器类型
|
||||||
vendor = sensor.vendor,
|
vendor = sensor.vendor, // 供应商
|
||||||
version = sensor.version,
|
version = sensor.version, // 版本号
|
||||||
isDynamicSensor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isDynamicSensor else false,
|
isDynamicSensor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isDynamicSensor else false, // 是否为动态传感器
|
||||||
isWakeUpSensor = sensor.isWakeUpSensor,
|
isWakeUpSensor = sensor.isWakeUpSensor, // 是否为唤醒传感器
|
||||||
fifoMaxEventCount = sensor.fifoMaxEventCount,
|
fifoMaxEventCount = sensor.fifoMaxEventCount, // FIFO最大事件数
|
||||||
fifoReservedEventCount = sensor.fifoReservedEventCount,
|
fifoReservedEventCount = sensor.fifoReservedEventCount, // FIFO保留事件数
|
||||||
minDelay = sensor.minDelay,
|
minDelay = sensor.minDelay, // 最小延迟(微秒)
|
||||||
maxDelay = sensor.maxDelay,
|
maxDelay = sensor.maxDelay, // 最大延迟(微秒)
|
||||||
maximumRange = sensor.maximumRange,
|
maximumRange = sensor.maximumRange, // 最大量程
|
||||||
power = sensor.power,
|
power = sensor.power, // 功耗(mA)
|
||||||
reportingMode = sensor.reportingMode,
|
reportingMode = sensor.reportingMode, // 报告模式
|
||||||
resolution = sensor.resolution,
|
resolution = sensor.resolution, // 分辨率
|
||||||
isAdditionalInfoSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) sensor.isAdditionalInfoSupported else false,
|
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
|
highestDirectReportRateLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) sensor.highestDirectReportRateLevel else SensorDirectChannel.RATE_STOP // 最高直报速率等级
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否支持动态传感器发现
|
||||||
|
* @return 是否支持
|
||||||
|
*/
|
||||||
fun isDynamicSensorDiscoverySupported(): Boolean {
|
fun isDynamicSensorDiscoverySupported(): Boolean {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
sensorManager.isDynamicSensorDiscoverySupported
|
sensorManager.isDynamicSensorDiscoverySupported
|
||||||
@ -46,28 +61,32 @@ class SensorInfo(private val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 传感器详细信息数据类
|
||||||
|
*/
|
||||||
data class SensorDetail(
|
data class SensorDetail(
|
||||||
val name: String,
|
val name: String, // 传感器名称
|
||||||
val id: Int?,
|
val id: Int?, // 传感器ID
|
||||||
val stringType: String,
|
val stringType: String, // 类型字符串
|
||||||
val type: Int,
|
val type: Int, // 类型
|
||||||
val vendor: String,
|
val vendor: String, // 供应商
|
||||||
val version: Int,
|
val version: Int, // 版本
|
||||||
val isDynamicSensor: Boolean,
|
val isDynamicSensor: Boolean, // 是否动态
|
||||||
val isWakeUpSensor: Boolean,
|
val isWakeUpSensor: Boolean, // 是否唤醒
|
||||||
val fifoMaxEventCount: Int,
|
val fifoMaxEventCount: Int, // FIFO最大事件数
|
||||||
val fifoReservedEventCount: Int,
|
val fifoReservedEventCount: Int, // FIFO保留事件数
|
||||||
val minDelay: Int,
|
val minDelay: Int, // 最小延迟
|
||||||
val maxDelay: Int,
|
val maxDelay: Int, // 最大延迟
|
||||||
val maximumRange: Float,
|
val maximumRange: Float, // 最大量程
|
||||||
val power: Float,
|
val power: Float, // 功耗
|
||||||
val reportingMode: Int,
|
val reportingMode: Int, // 报告模式
|
||||||
val resolution: Float,
|
val resolution: Float, // 分辨率
|
||||||
val isAdditionalInfoSupported: Boolean,
|
val isAdditionalInfoSupported: Boolean, // 是否支持附加信息
|
||||||
val highestDirectReportRateLevel: Int
|
val highestDirectReportRateLevel: Int // 最高直报速率等级
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
// 传感器报告模式对应中文
|
||||||
val sensorReportingModeToStringResId = mapOf(
|
val sensorReportingModeToStringResId = mapOf(
|
||||||
Sensor.REPORTING_MODE_CONTINUOUS to "连续",
|
Sensor.REPORTING_MODE_CONTINUOUS to "连续",
|
||||||
Sensor.REPORTING_MODE_ON_CHANGE to "变化时",
|
Sensor.REPORTING_MODE_ON_CHANGE to "变化时",
|
||||||
@ -75,6 +94,7 @@ class SensorInfo(private val context: Context) {
|
|||||||
Sensor.REPORTING_MODE_SPECIAL_TRIGGER to "特殊触发",
|
Sensor.REPORTING_MODE_SPECIAL_TRIGGER to "特殊触发",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 直通通道速率等级对应中文(Android O及以上)
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
val sensorDirectReportModeRatesToStringResId = mapOf(
|
val sensorDirectReportModeRatesToStringResId = mapOf(
|
||||||
SensorDirectChannel.RATE_STOP to "停止",
|
SensorDirectChannel.RATE_STOP to "停止",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user