1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <thread>
17 #include "media_key_system_impl.h"
18 #include "imedia_key_system_service.h"
19 #include "drm_error_code.h"
20 #include "drm_trace.h"
21 #include "napi_param_utils.h"
22
23 namespace OHOS {
24 namespace DrmStandard {
MediaKeySystemImpl(sptr<IMediaKeySystemService> & mediaKeysystem)25 MediaKeySystemImpl::MediaKeySystemImpl(sptr<IMediaKeySystemService> &mediaKeysystem) : serviceProxy_(mediaKeysystem)
26 {
27 DRM_DEBUG_LOG(
28 "MediaKeySystemImpl:0x %{public}06" PRIXPTR "MediaKeySystemImpl Instances create", FAKE_POINTER(this));
29
30 sptr<IRemoteObject> object = serviceProxy_->AsObject();
31 pid_t pid = 0;
32 deathRecipient_ = new (std::nothrow) DrmDeathRecipient(pid);
33 DRM_CHECK_AND_RETURN_LOG(deathRecipient_ != nullptr, "failed to new DrmDeathRecipient.");
34
35 deathRecipient_->SetNotifyCb([this](pid_t pid) { this->MediaKeySystemServerDied(pid); });
36 bool result = object->AddDeathRecipient(deathRecipient_);
37 if (!result) {
38 DRM_ERR_LOG("failed to add deathRecipient");
39 return;
40 }
41 }
42
~MediaKeySystemImpl()43 MediaKeySystemImpl::~MediaKeySystemImpl()
44 {
45 Release();
46 std::lock_guard<std::recursive_mutex> lock(mutex_);
47 serviceProxy_ = nullptr;
48 }
49
MediaKeySystemServerDied(pid_t pid)50 void MediaKeySystemImpl::MediaKeySystemServerDied(pid_t pid)
51 {
52 DRM_ERR_LOG("MediaKeySystem server has died, pid:%{public}d!", pid);
53 std::lock_guard<std::recursive_mutex> lock(mutex_);
54 if (serviceProxy_ != nullptr && serviceProxy_->AsObject() != nullptr) {
55 (void)serviceProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
56 serviceProxy_ = nullptr;
57 deathRecipient_ = nullptr;
58 }
59 }
60
Release()61 int32_t MediaKeySystemImpl::Release()
62 {
63 DRM_INFO_LOG("Release enter.");
64 if (serviceCallback_ != nullptr) {
65 serviceCallback_->Release();
66 serviceCallback_ = nullptr;
67 }
68 std::lock_guard<std::recursive_mutex> lock(mutex_);
69 int32_t ret = DRM_INNER_ERR_UNKNOWN;
70 if (serviceProxy_ != nullptr) {
71 sptr<IRemoteObject> object = serviceProxy_->AsObject();
72 if (object != nullptr && deathRecipient_ != nullptr) {
73 object->RemoveDeathRecipient(deathRecipient_);
74 deathRecipient_ = nullptr;
75 }
76 ret = serviceProxy_->Release();
77 if (ret != DRM_INNER_ERR_OK) {
78 DRM_ERR_LOG("Failed to Release keySystem!, errCode:%{public}d", ret);
79 return ret;
80 }
81 serviceProxy_ = nullptr;
82 } else {
83 DRM_ERR_LOG("serviceProxy_ is nullptr");
84 return ret;
85 }
86 return DRM_INNER_ERR_OK;
87 }
88
GenerateKeySystemRequest(std::vector<uint8_t> & request,std::string & defaultUrl)89 int32_t MediaKeySystemImpl::GenerateKeySystemRequest(std::vector<uint8_t> &request, std::string &defaultUrl)
90 {
91 DrmTrace trace("MediaKeySystemImpl::GenerateKeySystemRequest");
92 DRM_INFO_LOG("GenerateKeySystemRequest enter.");
93 std::lock_guard<std::recursive_mutex> lock(mutex_);
94 int32_t ret = DRM_INNER_ERR_OK;
95
96 if (serviceProxy_ == nullptr) {
97 DRM_ERR_LOG("GenerateKeySystemRequest serviceProxy_ is null");
98 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
99 }
100 ret = serviceProxy_->GenerateKeySystemRequest(request, defaultUrl);
101 if (ret != DRM_INNER_ERR_OK) {
102 DRM_ERR_LOG("GenerateKeySystemRequest failed, ret: %{public}d", ret);
103 return DRM_INNER_ERR_BASE;
104 }
105 return DRM_INNER_ERR_OK;
106 }
107
ProcessKeySystemResponse(const std::vector<uint8_t> & response)108 int32_t MediaKeySystemImpl::ProcessKeySystemResponse(const std::vector<uint8_t> &response)
109 {
110 DrmTrace trace("MediaKeySystemImpl::ProcessKeySystemResponse");
111 DRM_INFO_LOG("ProcessKeySystemResponse enter.");
112 std::lock_guard<std::recursive_mutex> lock(mutex_);
113 int32_t ret = DRM_INNER_ERR_OK;
114
115 if (serviceProxy_ == nullptr) {
116 DRM_ERR_LOG("ProcessKeySystemResponse serviceProxy_ is null");
117 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
118 }
119 ret = serviceProxy_->ProcessKeySystemResponse(response);
120 if (ret != DRM_INNER_ERR_OK) {
121 DRM_ERR_LOG("ProcessKeySystemResponse failed, ret: %{public}d", ret);
122 return DRM_INNER_ERR_BASE;
123 }
124 return DRM_INNER_ERR_OK;
125 }
126
SetConfigurationString(std::string & configName,std::string & value)127 int32_t MediaKeySystemImpl::SetConfigurationString(std::string &configName, std::string &value)
128 {
129 DRM_INFO_LOG("SetConfiguration enter, configName:%{public}s, value:%{public}s.", configName.c_str(), value.c_str());
130 std::lock_guard<std::recursive_mutex> lock(mutex_);
131 int32_t ret = DRM_INNER_ERR_OK;
132
133 if (serviceProxy_ == nullptr) {
134 DRM_ERR_LOG("SetConfiguration serviceProxy_ is null");
135 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
136 }
137 ret = serviceProxy_->SetConfigurationString(configName, value);
138 if (ret != DRM_INNER_ERR_OK) {
139 DRM_ERR_LOG("SetConfiguration failed, ret: %{public}d", ret);
140 return DRM_INNER_ERR_BASE;
141 }
142 return DRM_INNER_ERR_OK;
143 }
144
GetConfigurationString(std::string & configName,std::string & value)145 int32_t MediaKeySystemImpl::GetConfigurationString(std::string &configName, std::string &value)
146 {
147 DRM_INFO_LOG("GetConfiguration enter, configName:%{public}s.", configName.c_str());
148 std::lock_guard<std::recursive_mutex> lock(mutex_);
149 int32_t ret = DRM_INNER_ERR_OK;
150
151 if (serviceProxy_ == nullptr) {
152 DRM_ERR_LOG("GetConfiguration serviceProxy_ is null");
153 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
154 }
155 ret = serviceProxy_->GetConfigurationString(configName, value);
156 if (ret != DRM_INNER_ERR_OK) {
157 DRM_ERR_LOG("GetConfiguration failed, ret: %{public}d", ret);
158 return DRM_INNER_ERR_BASE;
159 }
160 return DRM_INNER_ERR_OK;
161 }
162
SetConfigurationByteArray(std::string & configName,std::vector<uint8_t> & value)163 int32_t MediaKeySystemImpl::SetConfigurationByteArray(std::string &configName, std::vector<uint8_t> &value)
164 {
165 DRM_INFO_LOG("SetConfiguration enter, configName:%{public}s.", configName.c_str());
166 std::lock_guard<std::recursive_mutex> lock(mutex_);
167 int32_t ret = DRM_INNER_ERR_OK;
168
169 if (serviceProxy_ == nullptr) {
170 DRM_ERR_LOG("SetConfiguration serviceProxy_ is null");
171 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
172 }
173 ret = serviceProxy_->SetConfigurationByteArray(configName, value);
174 if (ret != DRM_INNER_ERR_OK) {
175 DRM_ERR_LOG("SetConfiguration failed, ret: %{public}d", ret);
176 return DRM_INNER_ERR_BASE;
177 }
178 return DRM_INNER_ERR_OK;
179 }
180
GetConfigurationByteArray(std::string & configName,std::vector<uint8_t> & value)181 int32_t MediaKeySystemImpl::GetConfigurationByteArray(std::string &configName, std::vector<uint8_t> &value)
182 {
183 DRM_INFO_LOG("GetConfiguration enter, configName:%{public}s.", configName.c_str());
184 std::lock_guard<std::recursive_mutex> lock(mutex_);
185 int32_t ret = DRM_INNER_ERR_OK;
186
187 if (serviceProxy_ == nullptr) {
188 DRM_ERR_LOG("GetConfiguration serviceProxy_ is null");
189 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
190 }
191 ret = serviceProxy_->GetConfigurationByteArray(configName, value);
192 if (ret != DRM_INNER_ERR_OK) {
193 DRM_ERR_LOG("GetConfiguration failed, ret: %{public}d", ret);
194 return DRM_INNER_ERR_BASE;
195 }
196
197 return DRM_INNER_ERR_OK;
198 }
199
CreateMediaKeySession(ContentProtectionLevel securityLevel,sptr<MediaKeySessionImpl> * keySessionImpl)200 int32_t MediaKeySystemImpl::CreateMediaKeySession(
201 ContentProtectionLevel securityLevel, sptr<MediaKeySessionImpl> *keySessionImpl)
202 {
203 DrmTrace trace("MediaKeySystemImpl::CreateMediaKeySession");
204 DRM_INFO_LOG("CreateMediaKeySession enter.");
205 std::lock_guard<std::recursive_mutex> lock(mutex_);
206 sptr<IMediaKeySessionService> keySessionProxy = nullptr;
207 sptr<MediaKeySessionImpl> localMediaKeySessionImpl = nullptr;
208 int32_t ret = DRM_INNER_ERR_OK;
209 if (serviceProxy_ == nullptr) {
210 DRM_ERR_LOG("serviceProxy_ == nullptr");
211 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
212 }
213
214 ret = serviceProxy_->CreateMediaKeySession(securityLevel, keySessionProxy);
215 if (ret == DRM_INNER_ERR_OK) {
216 if (keySessionProxy != nullptr) {
217 localMediaKeySessionImpl = new (std::nothrow) MediaKeySessionImpl(keySessionProxy);
218 if (localMediaKeySessionImpl == nullptr) {
219 DRM_ERR_LOG("Failed to new MediaKeySessionImpl");
220 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
221 }
222 } else {
223 DRM_ERR_LOG("Service faltal error");
224 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
225 }
226 } else {
227 if (ret == DRM_INNER_ERR_MAX_SESSION_NUM_REACHED) {
228 DRM_ERR_LOG("The number of MediaKeySession is greater than 64");
229 return DRM_INNER_ERR_MAX_SESSION_NUM_REACHED;
230 }
231 DRM_ERR_LOG("Failed to get session object from mediakeysystem service!, %{public}d", ret);
232 return ret;
233 }
234 *keySessionImpl = localMediaKeySessionImpl;
235 return DRM_INNER_ERR_OK;
236 }
237
GetStatistics(std::vector<MetircKeyValue> & metrics)238 int32_t MediaKeySystemImpl::GetStatistics(std::vector<MetircKeyValue> &metrics)
239 {
240 DRM_INFO_LOG("GetStatistics enter.");
241 std::lock_guard<std::recursive_mutex> lock(mutex_);
242 int32_t ret = DRM_INNER_ERR_OK;
243
244 if (serviceProxy_ == nullptr) {
245 DRM_ERR_LOG("GetStatistics serviceProxy_ is null");
246 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
247 }
248 ret = serviceProxy_->GetStatistics(metrics);
249 if (ret != DRM_INNER_ERR_OK) {
250 DRM_ERR_LOG("GetStatistics failed, ret: %{public}d", ret);
251 return DRM_INNER_ERR_BASE;
252 }
253 return DRM_INNER_ERR_OK;
254 }
255
GetMaxContentProtectionLevel(ContentProtectionLevel * securityLevel)256 int32_t MediaKeySystemImpl::GetMaxContentProtectionLevel(ContentProtectionLevel *securityLevel)
257 {
258 DRM_INFO_LOG("GetMaxContentProtectionLevel enter.");
259 std::lock_guard<std::recursive_mutex> lock(mutex_);
260 int32_t ret = DRM_INNER_ERR_OK;
261 ContentProtectionLevel protectionLevel;
262
263 if (serviceProxy_ == nullptr) {
264 DRM_ERR_LOG("GetMaxContentProtectionLevel serviceProxy_ is null");
265 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
266 }
267 ret = serviceProxy_->GetMaxContentProtectionLevel(protectionLevel);
268 *securityLevel = protectionLevel;
269 if (ret != DRM_INNER_ERR_OK) {
270 DRM_ERR_LOG("GetMaxContentProtectionLevel failed, ret: %{public}d", ret);
271 return DRM_INNER_ERR_BASE;
272 }
273 return DRM_INNER_ERR_OK;
274 }
275
GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> & licenseIds)276 int32_t MediaKeySystemImpl::GetOfflineMediaKeyIds(std::vector<std::vector<uint8_t>> &licenseIds)
277 {
278 DRM_INFO_LOG("GetOfflineMediaKeyIds enter.");
279 std::lock_guard<std::recursive_mutex> lock(mutex_);
280 int32_t ret = DRM_INNER_ERR_OK;
281
282 if (serviceProxy_ == nullptr) {
283 DRM_ERR_LOG("GetOfflineMediaKeyIds serviceProxy_ is null");
284 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
285 }
286 ret = serviceProxy_->GetOfflineMediaKeyIds(licenseIds);
287 if (ret != DRM_INNER_ERR_OK) {
288 DRM_ERR_LOG("GetOfflineMediaKeyIds failed, ret: %{public}d", ret);
289 return DRM_INNER_ERR_BASE;
290 }
291 return DRM_INNER_ERR_OK;
292 }
293
GetOfflineMediaKeyStatus(std::vector<uint8_t> & licenseId,OfflineMediaKeyStatus & status)294 int32_t MediaKeySystemImpl::GetOfflineMediaKeyStatus(std::vector<uint8_t> &licenseId, OfflineMediaKeyStatus &status)
295 {
296 DRM_INFO_LOG("GetOfflineMediaKeyStatus enter.");
297 std::lock_guard<std::recursive_mutex> lock(mutex_);
298 int32_t ret = DRM_INNER_ERR_OK;
299
300 if (serviceProxy_ == nullptr) {
301 DRM_ERR_LOG("GetOfflineMediaKeyStatus serviceProxy_ is null");
302 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
303 }
304 ret = serviceProxy_->GetOfflineMediaKeyStatus(licenseId, status);
305 if (ret != DRM_INNER_ERR_OK) {
306 DRM_ERR_LOG("GetOfflineMediaKeyStatus failed, ret: %{public}d", ret);
307 return DRM_INNER_ERR_BASE;
308 }
309 return DRM_INNER_ERR_OK;
310 }
311
ClearOfflineMediaKeys(std::vector<uint8_t> & licenseId)312 int32_t MediaKeySystemImpl::ClearOfflineMediaKeys(std::vector<uint8_t> &licenseId)
313 {
314 DRM_INFO_LOG("ClearOfflineMediaKeys enter.");
315 std::lock_guard<std::recursive_mutex> lock(mutex_);
316 int32_t ret = DRM_INNER_ERR_OK;
317 if (serviceProxy_ == nullptr) {
318 DRM_ERR_LOG("ClearOfflineMediaKeys serviceProxy_ is null");
319 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
320 }
321 ret = serviceProxy_->ClearOfflineMediaKeys(licenseId);
322 if (ret != DRM_INNER_ERR_OK) {
323 DRM_ERR_LOG("ClearOfflineMediaKeys failed, ret: %{public}d", ret);
324 return DRM_INNER_ERR_BASE;
325 }
326 return DRM_INNER_ERR_OK;
327 }
328
GetCertificateStatus(CertificateStatus * certStatus)329 int32_t MediaKeySystemImpl::GetCertificateStatus(CertificateStatus *certStatus)
330 {
331 DRM_INFO_LOG("GetCertificateStatus enter.");
332 std::lock_guard<std::recursive_mutex> lock(mutex_);
333 int32_t ret = DRM_INNER_ERR_OK;
334 CertificateStatus certificateStatus;
335
336 if (serviceProxy_ == nullptr) {
337 DRM_ERR_LOG("GetCertificateStatus serviceProxy_ is null");
338 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
339 }
340 ret = serviceProxy_->GetCertificateStatus(certificateStatus);
341 *certStatus = certificateStatus;
342 if (ret != DRM_INNER_ERR_OK) {
343 DRM_ERR_LOG("GetCertificateStatus failed, ret: %{public}d", ret);
344 return DRM_INNER_ERR_BASE;
345 }
346 return DRM_INNER_ERR_OK;
347 }
348
SetCallback(const sptr<MediaKeySystemImplCallback> & callback)349 int32_t MediaKeySystemImpl::SetCallback(const sptr<MediaKeySystemImplCallback> &callback)
350 {
351 DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " SetCallback in", FAKE_POINTER(this));
352 DRM_CHECK_AND_RETURN_RET_LOG(callback != nullptr, DRM_INNER_ERR_INVALID_VAL, "callback is nullptr");
353 std::lock_guard<std::recursive_mutex> lock(mutex_);
354 mediaKeySystemApplicationCallback_ = callback;
355
356 int32_t ret = DRM_INNER_ERR_BASE;
357 serviceCallback_ = new (std::nothrow) MediaKeySystemCallback(this);
358 if (serviceCallback_ == nullptr) {
359 DRM_ERR_LOG("MediaKeySystemCallback alloc failed.");
360 return ret;
361 }
362 serviceCallback_->Init();
363 if (serviceProxy_ == nullptr) {
364 DRM_ERR_LOG("SetCallback serviceProxy_ is null");
365 return DRM_INNER_ERR_SERVICE_FATAL_ERROR;
366 }
367 ret = serviceProxy_->SetCallback(serviceCallback_);
368 if (ret != DRM_INNER_ERR_OK) {
369 DRM_ERR_LOG("SetCallback failed, ret: %{public}d", ret);
370 return DRM_INNER_ERR_BASE;
371 }
372 return ret;
373 }
374
GetApplicationCallback()375 sptr<MediaKeySystemImplCallback> MediaKeySystemImpl::GetApplicationCallback()
376 {
377 DRM_INFO_LOG("GetApplicationCallback");
378 return mediaKeySystemApplicationCallback_;
379 }
380
~MediaKeySystemCallback()381 MediaKeySystemCallback::~MediaKeySystemCallback()
382 {
383 DRM_INFO_LOG("~MediaKeySystemCallback");
384 Release();
385 }
386
Init()387 void MediaKeySystemCallback::Init()
388 {
389 DRM_INFO_LOG("MediaKeySystemCallback::Init");
390 serviceThreadRunning = true;
391 eventQueueThread = std::thread([this] { this->ProcessEventMessage(); });
392 DRM_INFO_LOG("MediaKeySystemCallback::Init exit");
393 }
394
Release()395 void MediaKeySystemCallback::Release()
396 {
397 DRM_INFO_LOG("Release Enter");
398 serviceThreadRunning = false;
399 {
400 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
401 cv.notify_all();
402 }
403 if (eventQueueThread.joinable()) {
404 DRM_INFO_LOG("MediaKeySystemCallback join");
405 eventQueueThread.join();
406 }
407 std::lock_guard<std::recursive_mutex> lock(mutex_);
408 systemImpl_ = nullptr;
409 }
410
InitEventMap()411 void MediaKeySystemCallback::InitEventMap()
412 {
413 DRM_INFO_LOG("MediaKeySystemCallback InitEventMap");
414 std::lock_guard<std::recursive_mutex> lock(mutex_);
415 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_PROVISION_REQUIRED)] =
416 MediaKeySystemEvent::EVENT_STR_PROVISION_REQUIRED;
417 }
418
GetEventName(DrmEventType event)419 std::string MediaKeySystemCallback::GetEventName(DrmEventType event)
420 {
421 DRM_INFO_LOG("MediaKeySystemCallback GetEventName");
422 std::string eventName = "";
423 std::lock_guard<std::recursive_mutex> lock(mutex_);
424 int32_t eventType = static_cast<int32_t>(event);
425 if (eventMap_.find(eventType) == eventMap_.end()) {
426 return eventName;
427 }
428 return eventMap_[eventType];
429 }
430
SendEvent(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)431 int32_t MediaKeySystemCallback::SendEvent(DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
432 {
433 DRM_INFO_LOG("SendEvent enter");
434 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
435 MediaKeySystemEventMessage message(event, extra, data);
436 eventQueue.push(message);
437 cv.notify_all();
438 return DRM_INNER_ERR_OK;
439 }
440
SendEventHandler(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)441 int32_t MediaKeySystemCallback::SendEventHandler(DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
442 {
443 DRM_INFO_LOG("SendEventHandler enter");
444 std::string eventName = GetEventName(event);
445 std::lock_guard<std::recursive_mutex> lock(mutex_);
446 if (systemImpl_ != nullptr && eventName.length() != 0) {
447 sptr<MediaKeySystemImplCallback> applicationCallback = systemImpl_->GetApplicationCallback();
448 if (applicationCallback != nullptr) {
449 applicationCallback->SendEvent(eventName, extra, data);
450 return DRM_INNER_ERR_OK;
451 }
452 }
453 DRM_DEBUG_LOG("SendEventHandler failed");
454 return DRM_INNER_ERR_BASE;
455 }
456
ProcessEventMessage()457 void MediaKeySystemCallback::ProcessEventMessage()
458 {
459 DRM_INFO_LOG("ProcessEventMessage msg enter");
460 while (serviceThreadRunning) {
461 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
462 cv.wait_for(queueMutexLock, std::chrono::milliseconds(100L)); // 100ms
463 std::queue<MediaKeySystemEventMessage> localQueue;
464 localQueue.swap(eventQueue);
465 queueMutexLock.unlock();
466 while (!localQueue.empty()) {
467 auto e = localQueue.front();
468 localQueue.pop();
469 SendEventHandler(e.event, e.extra, e.data);
470 }
471 }
472 DRM_INFO_LOG("ProcessEventMessage msg exit");
473 }
474 } // namespace DrmStandard
475 } // namespace OHOS
476