Android DRM框架分析

  • 1. DRM框架
  • 2.DRM架构
  • 3.DRM插件
  • 4. 实现
  • 5.DRM插件详情
  • 6.MediaDrm
  • 7.MediaCrypto
  • 8.参考链接

1. DRM框架

Android DRM框架全称Android数字版权管理框架, DRM插件必须实现DRM框架提供的接口。Android DRM框架有很好的扩展性,支持应用根据与受版权保护的内容关联的许可限制条件来管理这些内容。DRM框架支持多种DRM方案,设备具体支持哪些DRM方案由设备制造商决定。
DRM 框架为受保护和不受保护的内容提供了一致的操作模式。DRM 方案可以定义复杂的许可元数据使用模型。DRM 框架提供了 DRM 内容与许可之间的关联,并处理权限管理。这样可以将媒体播放器从受 DRM 保护或不受保护的内容中提取出来。
MediaDrm 提供了获取用于解密受保护的媒体流的密钥。

为保证内容的广泛覆盖面,Android 开发者和数字内容发布者需要在整个 Android 生态系统中实现受支持的一致的 DRM。为了让这类数字内容适用于 Android 设备,并确保至少有一个一致的 DRM 可用于所有设备,Google 会在兼容的 Android 设备上提供无需支付许可费用的 DRM。DRM 插件会与 Android DRM 框架集成在一起,并可使用受硬件支持的保护功能来确保付费内容和用户凭据的安全。

DRM 插件提供的内容保护功能取决于底层硬件平台的安全和内容保护功能。设备的硬件功能应包括硬件安全启动,可建立加密密钥的安全和保护功能的信任链。设备的内容保护功能应包括设备内加密帧的保护和通过可信输出保护机制实现的内容保护。并非所有硬件平台都支持上述所有的安全和内容保护功能。安全功能绝不会在堆栈的单个位置实现,而是依赖于硬件、软件和服务的集成。将硬件安全功能、可信启动机制以及用于处理安全功能的隔离安全操作系统组合使用是保障安全设备的关键。

2.DRM架构

DRM框架与实现无关,DRM插件有自己特定的实现。DRM框架包括以下可执行的简单API:处理复杂的DRM操作,获取许可,配置设备,将DRM内容与其许可相关联, 以及最终解密DRM内容。

Android DRM是在以下两个架构层中实现的:

  • DRM frameowork API:通过Android应用框架提供给应用。
  • 本机代码DRM框架:为DRM插件(代理)提供接口,以便处理各种DRM方案的版权管理和解密操作。


如需了解详情,请参阅MediaDrm 和MediaCrypto。

3.DRM插件

系统启动时候,DRM框架会扫描HAL实例/服务(如.rc文件所述),并通过HIDL注册表发现插件。媒体DRM服务器(mediadrmserver)创建CryptoHalDrmHal对象。然后,CryptoHalDrmHal使用供应商专用实现来调用发现的插件。

插件应实现绑定式HAL。绑定式HAL使用 HAL 接口定义语言 (HIDL), HIDL支持在不重新构建HAL的情况下替换框架。

插件有供应商或SOC制造商构建,放置在设备的/vendor分区中。Android8.0或更高版本的设备必须支持HIDL语言编写的绑定式HAL。

4. 实现

要通过插件实现新的DRM框架API,请执行以下操作:

  1. 将插件服务添加到设备的构建文件中。
  2. 更新设备清单。
  3. 添加 SELinux 权限。
  4. 在 /vendor 下创建 .rc 文件。
  5. 实现插件。

新的 API 在 iDrmPlugin.hal 和 iCryptoPlugin.hal 中定义。

PLATFORM_ROOT/hardware/interfaces/drm/VERSION/

将插件服务添加到设备的构建文件中

例如,要添加接口 1.2 支持,VENDOR DEVICE/device.mk 文件必须包含 android.hardware.drm@1.2-service.* 软件包:

PRODUCT_PACKAGES += \android.hardware.drm@1.0-impl \android.hardware.drm@1.0-service \android.hardware.drm@1.2-service.clearkey \android.hardware.drm@1.2-service.widevine

更新设备清单
设备的 vendor manifest.xml 文件必须包含以下条目:

<hal format="hidl"><name>android.hardware.drm</name><transport>hwbinder</transport><version>1.0</version><interface><name>ICryptoFactory</name><instance>default</instance></interface><interface><name>IDrmFactory</name><instance>default</instance></interface><fqname>@1.2::ICryptoFactory/clearkey</fqname><fqname>@1.2::IDrmFactory/clearkey</fqname><fqname>@1.2::ICryptoFactory/widevine</fqname><fqname>@1.2::IDrmFactory/widevine</fqname></hal>

添加 SELinux 权限

    1. 添加到 VENDOR DEVICE/sepolicy/vendor/file.te
type mediadrm_vendor_data_file, file_type, data_file_type;
    1. 添加到 VENDOR DEVICE/sepolicy/vendor/file_contexts
/vendor/bin/hw/android\.hardware\.drm@1\.2-service\.clearkeyu:object_r:hal_drm_clearkey_exec:s0/data/vendor/mediadrm(/.*)? u:object_r:mediadrm_vendor_data_file:s0
    1. 添加到 device/sepolicy/vendor/hal_drm_clearkey.te
allow hal_drm_clearkey mediadrm_vendor_data_file:dir create_dir_perms;allow hal_drm_clearkey mediadrm_vendor_data_file:file create_file_perms;

在 /vendor 下创建 .rc 文件

.rc 文件指定服务启动时要采取的操作。

需如了解.rc文件,请参考 Android Init 语言

实现插件

    1. 在插件服务的 service.cpp 中实现 main() 入口点。
    1. 实现 CryptoFactory 和 DrmFactory。
    1. 在插件中实现新的 API。

5.DRM插件详情

DRM 插件供应商实现了 DrmFactoryCryptoFactory 和 DRM 插件。

DrmFactory

DrmHal 类会搜索已注册的 DRM 插件服务,并通过 DrmFactory 类构建支持给定加密方案的相应插件。

Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>uuid);

确定插件工厂能否构建支持给定加密方案(由 UUID 指定)的 DRM 插件。

Return<bool> isContentTypeSupported(const hidl_string &mimeType);

确定插件工厂能否构建支持给定媒体容器格式(由 mimeType 指定)的 DRM 插件。

Return<void> createPlugin(const hidl_array<uint8_t, 16>uuid,const hidl_string& appPackageName, createPlugin_cb _hidl_cb);

为UUID指定的加密方案构建DRM插件。

CryptoFactory
CryptoHal 类会搜索已注册的 DRM 插件服务,并通过 CryptoFactory 类构建支持给定加密方案的相应插件。

Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>uuid);

确定加密工厂能否构建支持给定加密方案(由 UUID 指定)的加密插件。

Return<void> createPlugin(const hidl_array<uint8_t, 16>uuid,const hidl_vec<uint8_t>initData, createPlugin_cb _hidl_cb)

确定插件工厂能否构建支持给定加密方案(由 UUID 指定)的加密插件。

DRM 插件
API 在 hardware/interfaces/drm/VERSION /IDrmPlugin.hal 中定义。构建完成后,可以在 out/Soong 中找到相应的 IDrmPlugin.h 文件。

6.MediaDrm

MediaDrm可以用于获取Keys,这些Keys可以用于解密受保护的媒体流,结合MediaCrypto。MediaDrm APIs被设计以支持ISO/IEC 23001-7:通用加密标准,同时可能也用于实现其他加密方案。

加密的内容存放在加密服务器的内容库中。加密的内容通过流化或下载的方式从内容服务器传送到客户端设备。用于查看内容的Licenses从License服务器获取。

使用key请求来从license服务器获取Keys。key response传递到客户端app,该response将发起MediaDrm API的调用。
一个Provisioning服务器可能会被需要,用于向设备分发设备唯一凭据。
强制要求依赖于同步播放内容的设备数量,这些要求可以通过密钥更新或使用安全停止方法来完成。

下面的序列图展示了后台播放加密内容涉及的对象之间的交互:

app首先构造MediaExtractorMediaCodec对象。它通常从内容中的元数据访问由UUID标识的DRM方案,并使用此UUID构造MediaDrm对象的实例,该实例能够支持内容所需的DRM方案。加密方案分配了16字节的UUID。isCryptoSchemeSupported(UUID)方法能够用于查询一个给定的DRM方案是否被设备所支持。

app调用openSession()用于生成一个会话Id,这个id将用于后续交互中的唯一会话Id。app下一步将使用MediaDrm对象来获取一个key请求的message并发送到license服务器,然后提供服务端的响应给到MediaDrm对象。

一但app有了会话Id,它就可以UUID和会话Id构造一个MediaCrypto对象。MediaCrypto对象通过MediaCodec#configure方法完成注册,从而使codec具备解密内容的能力。

当app构造完成了MediaExtractorMediaCodecMediaCrypto对象,它继续从extractor中提取样本并将它们放入解码对列中。对于加密的内容,extractor返回的样本保持加密状态,只有当样本被传递到解码器时,它们才被解密。

MediaDrm中的方法抛出MediaDrm.MediaDrmStateException异常,当一个DRM插件或安全硬件中发生了不可恢复的故障时。MediaDrm.MediaDrmStateException继承自IllegalStateException,添加了与异常相关联的开发人员可读的诊断信息字符串。

当MediaDrm对象处于激活状态时,mediaserver处理crash或者重启事件中, MediaDrm方法可能抛出MediaDrmResetException。为了恢复,app必须释放MediaDrm对象,然后重新创建一个新的MediaDrm对象。

由于MediaDrmResetExceptionMediaDrm.MediaDrmStateException都继承自IllegalStateException, 它们应该在IllegalStateException之前捕获异常代码块。注册这些事件监听是通过调用setOnEventListener(MediaDrm.OnEventListener)完成的。

回调

应用程序应该注册信息性事件,以便在回放或流式传输期间通知密钥状态更新。为了接收与此listener关联的相应回调,应用程序需要在自己的循环线程中创建MediaDrm对象(UI线程默认情况下有一个Looper在运行)。

7.MediaCrypto

MediaCrypto类可以用于联合MediaCodec使用用于解码加密的媒体数据。Crypto方案被分配16byte的UUIDs,isCryptoSchemeSupported(UUID)方法可以用于查询一个给定的DRM方案是否被设备所支持。

8.参考链接

MediaDrm
https://developer.android.google.cn/reference/android/media/MediaDrm.html
DRM
https://source.android.google.cn/devices/drm

Android DRM框架分析相关推荐

  1. Android DRM框架与基础知识

    Android DRM框架与基础知识 Android DRM框架 DRM框架的目的:能让安卓设备可以播放更多的内容,不同的内容和硬件设备可能使用的是不同的内容版权保护机制或者没有版权管理机制,但是安卓 ...

  2. Linux内核4.14版本——drm框架分析(1)——drm简介

    目录 1. DRM简介(Direct Rendering Manager) 1.1 DRM发展历史 1.2 DRM架构对比FB架构优势 1.3 DRM图形显示框架 1.4 DRM图形显示框架涉及元素 ...

  3. Android WIFI框架分析(1)

    趁做Android WIFI驱动移植,对Android WIFI框架做了深刻的分析,并做此文档共同学习. 对上层WIFI的应用,基本流程为:(1)WIFI初始化  (2)Wifi启动      (3) ...

  4. MTK Android Led框架分析

    1 驱动部分 这部分主要根据驱动源码的初始化部分进行分析 1.1 mtk_leds_drv 路径:/kernel-4.14/drivers/misc/mediatek/leds/mtk_leds_dr ...

  5. android输入法框架分析,Android与iOS输入法开发框架比较谈

    对于任何一个使用手机的人,有一样工具是不可能缺少的,它既不是微信之类的社交工具,也不是支付宝之类的金融工具(事实上这两个都越界了),而是输入法这样的输入工具.更重要的是,输入法还是一种特权工具,因为它 ...

  6. Android Framework框架分析

    转自:微点阅读  https://www.weidianyuedu.com/content/2617738210126.html Android framework analysis (partI z ...

  7. Android RIL框架分析

    1.RIL框架 RIL,Radio Interface Layer.本层为一个协议转换层,提供Android Telephony与无线通信设备之间的抽象层. Android RIL位于Telephon ...

  8. Android灯光系统框架分析

    首先别人的APP要能直接访问到你写的硬件或者不经过任何修改的APP能直接使用你的驱动,就需要使用系统自带的JNI,所以我们需要写出符合系统自带JNI文件的HAL文件和驱动程序,下面具体分析一个这个HA ...

  9. android输入法框架分析,Android输入法架构.ppt

    Android输入法架构 Android输入法架构 裴润升 oppo开发三部 输入法 为系统中其他模块提供输入功能的模块 1 硬键盘 2 软键盘 3 手写 4 语音输入 问题: 输入法和应用分属不同的 ...

最新文章

  1. 讲解Guitar Pro打谱使用技巧
  2. 前端js vue遇到的一些简单的数据处理-持续更新
  3. GNU make manual 翻译( 一百七十五)
  4. 动画效果-基础动画设置(改变大小,改变透明度,翻转,旋转,复原)
  5. Is it cold in Shinjuku?
  6. Python自学之乐-python中break continue exit() pass浅析
  7. Atitit 函数调用的原理与本质attilax总结 stdcall cdecl区别
  8. vm虚拟机win7安装镜像方法
  9. 在有位图索引的表上进行DML操作与enq: TX - row lock contention等待事件问题分析
  10. 2. webpack 处理 css less sass scss styl 资源
  11. 新华系“雄文”为何引发游戏产业3000亿市值蒸发?
  12. moment系列一:add() 方法和subtract() 方法的使用
  13. OCPC不起量该怎么办?从这四个方面着手,轻松起量
  14. JS ListBox动态加载数据
  15. bash下的特殊符号与通配符
  16. ES分组查询,统计组名
  17. 语音转换主要涉及技术记录
  18. nuc970 nfs启动配置问题
  19. 移动游戏性能优化通用技法
  20. 蓝桥杯试题:神奇算式(C/C++)

热门文章

  1. 中国版权保护中心注册流程(含实名认证)
  2. vscode安装和配置ESLint
  3. 为什么黑客几乎不用鼠标?
  4. 华为5g cpe 虚拟服务器,一图看懂华为5G CPE Pro
  5. lisp读点坐标绘多义线_多段线点导出和导入点坐标成多段线(AutoLISP源码)——好用的AutoCAD点坐标导入导出工具...
  6. android直接连接本地数据库文件,Android 直接连MySQL数据库
  7. 技术的共通性—从姿态估计到自动驾驶
  8. “双一流”霸气官宣:博士生,涨薪!
  9. pytorch学习(二)梯度:什么叫梯度?什么叫梯度下降
  10. MATLAB绘制雷达图并导出矢量图到Visio编辑(论文用图)