README_zh.md
1# ClearPlay
2
3## 概述
4
5OpenHarmony ClearPlay驱动对上实现媒体版权保护(DRM)的HDI(Hardware Device Interface)接口,
6为DRM框架提供DRM版权保护的具体实现;作为DRM插件适配样例,指导用户适配其他产商的DRM插件。
7
8## 目录
9
10- ClearPlay模块目录表如下:
11
12 ```
13/drivers/peripheral/ClearPlay
14├── bundle.json # ClearPlay驱动构建脚本
15├── hdi_service # ClearPlay驱动服务功能实现代码
16│ ├── common # ClearPlay驱动服务依赖的工具类代码,包含json解析、base64编解码
17│ ├── include # ClearPlay驱动服务头文件
18│ └── src # ClearPlay驱动服务具体实现代码
19├── interfaces # ClearPlay驱动能力接口
20│ ├── include # ClearPlay驱动能力接口头文件
21│ └── src # ClearPlay驱动能力接口实现
22└── test # ClearPlay驱动测试代码
23 ├── sample # ClearPlay驱动功能验证demo
24 │ ├── include # ClearPlay驱动功能验证demo头文件
25 │ └── src # ClearPlay驱动功能验证demo具体实现
26 └── unittest # ClearPlay驱动UT用例
27 ├── include # ClearPlay驱动UT用例头文件
28 └── src # ClearPlay驱动UT用例实现
29 ```
30
31## ClearPlay驱动能力接口说明
32
33- imedia_key_system_factory.h
34
35 | 功能描述 | 接口名称 |
36 | -------------------------------- | ------------------------------------------------------------ |
37 | 查询设备是否支持uuid/媒体类型/安全级别对应的插件 | int32_t IsMediaKeySystemSupported(const std::string& uuid, const std::string& mimeType, ContentProtectionLevel level, bool& isSupported) |
38 | 创建MediaKeySysem对象 | int32_t CreateMediaKeySystem(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystem>& mediaKeySystem) |
39 | 获取插件版本 | int32_t GetVersion(uint32_t& majorVer, uint32_t& minorVer) |
40
41
42 - imedia_key_system.h
43
44 | 功能描述 | 接口名称 |
45 | -------------------------------- | ------------------------------------------------------------ |
46 | 根据配置类型和属性名获取对应配置值,包括输出保护状态、设备属性、支持的最大会话数、当前会话数 | int32_t GetConfigurationString(const std::string& name, std::string& value) |
47 | 根据配置类型和属性名设置对应配置值 | int32_t SetConfigurationString(const std::string& name, const std::string& value) |
48 | 根据配置类型和属性名获取对应配置值,包括输出保护状态、设备属性、支持的最大会话数、当前会话数 | int32_t GetConfigurationByteArray(const std::string& name, std::vector<uint8_t>& value) |
49 | 根据配置类型和属性名设置对应配置值 | int32_t SetConfigurationByteArray(const std::string& name, const std::vector<uint8_t>& value) |
50 | 获取DRM度量值 | int32_t GetMetrics(std::map<std::string, std::string>& metrics) |
51 | 获取MediaKeySystem最大安全级别 | int32_t GetMaxContentProtectionLevel(ContentProtectionLevel& level) |
52 | 生成设备证书获取请求 | int32_t GenerateKeySystemRequest(std::string& defaultUrl, std::vector<uint8_t>& request) |
53 | 解析设备证书获取响应 | int32_t ProcessKeySystemResponse(const std::vector<uint8_t>& response) |
54 | 获取证书状态 | int32_t GetOemCertificateStatus(CertificateStatus& status) |
55 | 注册和取消注册MediaKeySystem监听时事件 | int32_t SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemCallback>& callback) |
56 | 根据安全级别创建会话 | int32_t CreateMediaKeySession(ContentProtectionLevel level,
57 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession>& keySession) |
58 | 创建会话 | int32_t CreateMediaKeySessionDefault(sptr<OHOS::HDI::Drm::V1_0::IMediaKeySession>& keySession) |
59 | 获取所有离线密钥或密钥组索引 | int32_t GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>>& mediakeyIds) |
60 | 获取所有离线密钥或密钥组索引 | int32_t GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>>& mediakeyIds) |
61 | 获取指定离线密钥或密钥组状态 | int32_t GetOfflineMediaKeyStatus(const std::vector<uint8_t>& mediakeyId, OfflineMediaKeyStatus& mediakeyStatus) |
62 | 获取OEM证书 | int32_t GetOemCertificate(sptr<OHOS::HDI::Drm::V1_0::IOemCertificate>& oemCert) |
63 | 释放MediaKeySystem | int32_t Destroy() |
64
65
66 - ikey_session.h
67
68 | 功能描述 | 接口名称 |
69 | -------------------------------- | ------------------------------------------------------------ |
70 | 生成一个许可证获取请求 | int32_t GenerateMediaKeyRequest(const MediaKeyRequestInfo& mediakeyRequestInfo,
71 MediaKeyRequest& mediakeyRequest) |
72 | 解析许可证获取响应 | int32_t ProcessMediaKeyResponse(const std::vector<uint8_t>& mediakeyResponse, std::vector<uint8_t>& mediakeyId) |
73 | 检查当前会话的许可证状态 | int32_t CheckMediaKeyStatus(std::map<std::string, OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus>& mediakeyStatus) |
74 | 移除当前会话下所有许可证 | int32_t RemoveMediaKey() |
75 | 生成离线密钥释放请求 | int32_t GetOfflineReleaseRequest(const std::vector<uint8_t>& mediakeyId, std::vector<uint8_t>& releaseRequest) |
76 | 解析离线密钥释放响应 | int32_t ProcessOfflineReleaseResponse(const std::vector<uint8_t>& mediakeyId, const std::vector<uint8_t>& response) |
77 | 恢复离线密钥和密钥组,并加载到当前会话中 | int32_t RestoreOfflineMediaKey(const std::vector<uint8_t>& mediakeyId) |
78 | 获取KeySession安全级别 | int32_t GetContentProtectionLevel(ContentProtectionLevel& level) |
79 | 查询是否支持安全解码 | int32_t RequiresSecureDecoderModule(const std::string& mimeType, bool& required) |
80 | 注册和取消注册监听事件 | int32_t SetCallback(const sptr<OHOS::HDI::Drm::V1_0::IMediaKeySessionCallback>& callback) |
81 | 获取解密模块 | int32_t GetMediaDecryptModule(sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule>& decryptModule) |
82 | 释放当前会话 | int32_t Destroy() |
83
84
85 - imedia_decrypt_module.h
86
87 | 功能描述 | 接口名称 |
88 | -------------------------------- | ------------------------------------------------------------ |
89 | 解密媒体数据 | int32_t DecryptMediaData(bool secure, const AVBuffer& srcBuffer, const AVBuffer& destBuffer) |
90 | 解密模块资源释放 | int32_t Release() |
91
92
93 - ikey_session_callback.h
94
95 | 功能描述 | 接口名称 |
96 | ------------------------------| ------------------------------------------------------------ |
97 | HDI MediaKeySession事件监听接口 | int32_t SendEvent(EventType eventType, int32_t extra, const std::vector<uint8_t>& data) |
98 | HDI MediaKeySession事件监听接口,密钥状态改变 | int32_t SendEventKeyChange(const std::map<std::vector<uint8_t>, OHOS::HDI::Drm::V1_0::MediaKeySessionKeyStatus>& keyStatus, bool hasNewGoodMediaKey) |
99
100- imedia_key_system_callback.h
101
102 | 功能描述 | 接口名称 |
103 | ------------------------------| ----------------------------------------------------------- |
104 | MediaKeySystem事件监听回调 | int32_t SendEvent(EventType eventType, int32_t extra, const std::vector<uint8_t>& data) |
105
106 - ioem_certificate.h
107
108 | 功能描述 | 接口名称 |
109 | --------------------------------| ------------------------------------------------------------ |
110 | 设备证书provision请求 | int32_t GetOemProvisionRequest(std::string& defaultUrl, std::vector<uint8_t>& request) |
111 | 设备证书provision请求响应 | int32_t ProvideOemProvisionResponse(const std::vector<uint8_t>& response) |
112
113
114## 使用方法
115
116在/drivers/peripheral/ClearPlay/test目录下有一个关于ClearPlay的sample,该sample可以验证ClearPlay证书下载、解密播放等基础功能。下面我们就以此sample为例讲述怎样用HDI接口去编写MediaKeySystem的创建、会话管理、证书管理、许可证管理、数据解密等功能的用例。
117sample编译命令:./build.sh --product-name rk3568 --build-target clearplay_test_entry
118编译产物路径:./out/rk3568/exe.unstripped/hdf/drivers_peripheral_clearplay
119
120
1211. 在clearplay_sample_media_key_system_factory.cpp的main函数中构造一个media_key_system_factory 对象,该对象中有查询设备所支持插件类型、创建和销毁MediaKeySystem的方法。
122
123 ```
124int main(int argc, char *argv[])
125{
126 // data init
127 std::string clearPlayUuid = "com.drm.clearplay";
128 bool isSupported = false;
129
130 // create key system factory
131 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemFactory> media_key_system_factory = new MediaKeySystemFactoryService();
132
133 // IsMediaKeySystemSupported case 1
134 media_key_system_factory->IsMediaKeySystemSupported(clearPlayUuid, isoVideoMimeType, SECURE_UNKNOWN, isSupported);
135 printf("IsMediaKeySystemSupported: %d, expect 1\n", isSupported);
136 // IsMediaKeySystemSupported case 2
137 clearPlayUuid = "E79628B6406A6724DCD5A1DA50B53E81"; // wrong uuid
138 media_key_system_factory->IsMediaKeySystemSupported(clearPlayUuid, isoVideoMimeType, SECURE_UNKNOWN, isSupported);
139 printf("IsMediaKeySystemSupported: %d, expect 0\n", isSupported);
140
141 // CreateMediaKeySystem
142 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystem> media_key_system;
143 media_key_system_factory->CreateMediaKeySystem(media_key_system);
144 printf("CreateMediaKeySystem\n");
145
146 // MediaKeySystem Close
147 media_key_system->Close();
148 printf("Close\n");
149 return 0;
150} ```
151
1522. clearplay_sample_media_key_system.cpp的main函数中构造一个media_key_system_factory 对象,用该对象创建一个media_key_system对象,使用media_key_system验证设备证书请求、设备证书响应、多会话、属性获取与设置、安全级别获取、DRM度量等功能。
153
154 ```
155int main(int argc, char *argv[])
156{
157 // data init
158 std::vector<uint8_t> inputValue;
159 std::vector<uint8_t> outputValue;
160 std::map<std::string, std::string> metric;
161 ContentProtectionLevel level = SECURE_UNKNOWN;
162 sptr<OHOS::HDI::Drm::V1_0::IKeySession> key_session_1;
163 sptr<OHOS::HDI::Drm::V1_0::IKeySession> key_session_2;
164 sptr<OHOS::HDI::Drm::V1_0::IKeySession> key_session_3;
165 sptr<OHOS::HDI::Drm::V1_0::IKeySession> key_session_4;
166
167 // create key system factory
168 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemFactory> media_key_system_factory = new MediaKeySystemFactoryService();
169
170 // CreateMediaKeySystem
171 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystem> media_key_system;
172 media_key_system_factory->CreateMediaKeySystem(media_key_system);
173 printf("CreateMediaKeySystem\n");
174
175 // set and get configuration
176 printf("\ntest set and get configuration\n");
177 inputValue.push_back('v');
178 inputValue.push_back('a');
179 inputValue.push_back('l');
180 inputValue.push_back('u');
181 inputValue.push_back('e');
182 media_key_system->SetConfiguration(CONFIG_TYPE_KEY_SESSION, "name1", inputValue);
183 media_key_system->SetConfiguration(CONFIG_TYPE_KEY_SESSION, "name2", inputValue);
184 media_key_system->SetConfiguration(CONFIG_TYPE_KEY_SESSION, "name3", inputValue);
185
186 media_key_system->GetConfiguration(CONFIG_TYPE_KEY_SESSION, "name1", outputValue);
187 printf("outputValue: %s, expect: value\n", outputValue.data());
188
189 // GetMetric
190 printf("\ntest GetMetric\n");
191 media_key_system->GetMetric(metric); // 当前可度量信息:插件版本信息、会话数量、解密次数、解密失败次数
192 for (auto& pair:metric) {
193 printf("key: %s, value: %s\n", pair.first.c_str(), pair.second.c_str());
194 }
195
196 // GetContentProtectionLevel
197 printf("result of GetContentProtectionLevel: %d, expect: -1\n", media_key_system->GetContentProtectionLevel(level));
198
199 // CreateKeySession
200 /*
201 SECURE_UNKNOWN = 0,
202 SW_SECURE_CRYPTO = 1,
203 SW_SECURE_DECODE = 2,
204 HW_SECURE_CRYPTO = 3,
205 HW_SECURE_DECODE = 4,
206 HW_SECURE_ALL = 5,
207 */
208 printf("\ntest CreateKeySession\n");
209 media_key_system->CreateKeySession(SW_SECURE_CRYPTO, key_session_1);
210 media_key_system->CreateKeySession(SW_SECURE_DECODE, key_session_2);
211 media_key_system->CreateKeySession(HW_SECURE_CRYPTO, key_session_3);
212 media_key_system->CreateKeySession(HW_SECURE_DECODE, key_session_4);
213 printf("CreateKeySession\n");
214
215 // GetContentProtectionLevel
216 printf("\ntest GetContentProtectionLevel\n");
217 media_key_system->GetContentProtectionLevel(level);
218 printf("level: %d, expect: 4\n", level);
219 key_session_4->Close();
220 media_key_system->GetContentProtectionLevel(level);
221 printf("level: %d, expect: 3\n", level);
222
223 // GenerateKeySystemRequest
224 std::vector<uint8_t> request;
225 std::string defaultUrl;
226 media_key_system->GenerateKeySystemRequest(REQUEST_TYPE_INITIAL, defaultUrl, request);
227 // std::string requestString(request.begin(), request.end());
228 printf("request: %s, expect: REQUEST_TYPE_INITIAL\n", request.data());
229
230 // ProcessKeySystemResponse
231 media_key_system->ProcessKeySystemResponse(REQUEST_TYPE_INITIAL, request);
232
233 // MediaKeySystem Close
234 media_key_system->Close();
235 printf("Close\n");
236 return 0;
237} ```
238
2392. clearplay_sample_media_key_system.cpp的main函数中构造一个media_key_system_factory 对象,用该对象创建一个media_key_system对象,使用media_key_system对象创建key_session对象,使用key_session对象验证许可证获取请求、解析许可证响应、获取解密模块对象以及数据解密和释放解密模块功能。
240
241 ```
242int main(int argc, char *argv[])
243{
244 // create key system factory
245 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystemFactory> media_key_system_factory = new MediaKeySystemFactoryService();
246
247 // CreateMediaKeySystem
248 sptr<OHOS::HDI::Drm::V1_0::IMediaKeySystem> media_key_system;
249 media_key_system_factory->CreateMediaKeySystem(media_key_system);
250 printf("CreateMediaKeySystem\n");
251
252 // CreateKeySession
253 printf("\ntest CreateKeySession\n");
254 sptr<OHOS::HDI::Drm::V1_0::IKeySession> key_session;
255 media_key_system->CreateKeySession(SECURE_UNKNOWN, key_session);
256 printf("CreateKeySession\n");
257
258 // ProcessMediaKeyResponse
259 printf("\ntest ProcessMediaKeyResponse\n");
260 std::string responseString = "key1:1234567812345678";
261 std::vector<uint8_t> response(responseString.begin(), responseString.end());
262 std::vector<uint8_t> keyId;
263
264 key_session->ProcessMediaKeyResponse(response, keyId);
265 printf("keyid: %s, expect: key1\n", keyId.data());
266
267 // GetMediaDecryptModule
268 sptr<OHOS::HDI::Drm::V1_0::IMediaDecryptModule> decryptModule;
269 key_session->GetMediaDecryptModule(decryptModule);
270
271 // DecryptData
272 printf("\nDecryptData\n");
273 CryptoInfo info;
274 info.type = ALGTYPE_AES_CBC;
275 info.keyIdLen = 4;
276 info.keyId = keyId;
277 info.ivLen = 16;
278 info.iv = { // 网络安全,设置默认值,实际调用由DRM框架传真实值
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
281 };
282 info.pattern.encryptBlocks = 0;
283 info.pattern.skipBlocks = 0;
284 SubSample subSample;
285 subSample.clearHeaderLen = 0;
286 subSample.payLoadLen = 16;
287 info.subSamples.push_back(subSample);
288 info.subSampleNum = 1;
289 std::vector<uint8_t> srcBuffer = { // 网络安全,设置默认值,实际调用由DRM框架传真实值
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
292 };
293 std::vector<uint8_t> dstBuffer = { // 网络安全,设置默认值,实际调用由DRM框架传真实值
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
296 };
297 decryptModule->DecryptData(false, info, srcBuffer, dstBuffer);
298 for (size_t i = 0; i < dstBuffer.size(); ++i) {
299 printf("%02x ", dstBuffer[i]);
300 }
301 printf("\n\n");
302
303 media_key_system->Close();
304 printf("Close\n");
305 return 0;
306} ```
307
308```
309