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 "key_session_impl.h"
18 #include "drm_log.h"
19 #include "drm_error_code.h"
20 #include "drm_trace.h"
21
22 namespace OHOS {
23 namespace DrmStandard {
24
MediaKeySessionImpl(sptr<IMediaKeySessionService> & keySession)25 MediaKeySessionImpl::MediaKeySessionImpl(sptr<IMediaKeySessionService> &keySession)
26 : keySessionServiceCallback_(nullptr), keySessionServiceProxy_(keySession)
27 {
28 DRM_DEBUG_LOG("0x%{public}06" PRIXPTR "MediaKeySessionImpl Instances create",
29 FAKE_POINTER(this));
30
31 sptr<IRemoteObject> object = keySessionServiceProxy_->AsObject();
32 pid_t pid = 0;
33 deathRecipient_ = new(std::nothrow) DrmDeathRecipient(pid);
34 DRM_CHECK_AND_RETURN_LOG(deathRecipient_ != nullptr, "failed to new DrmDeathRecipient.");
35 deathRecipient_->SetNotifyCb([this] (pid_t pid) {
36 this->MediaKeySessionServerDied(pid);
37 });
38 bool result = object->AddDeathRecipient(deathRecipient_);
39 if (!result) {
40 DRM_ERR_LOG("failed to add deathRecipient");
41 return;
42 }
43 }
44
~MediaKeySessionImpl()45 MediaKeySessionImpl::~MediaKeySessionImpl()
46 {
47 DRM_INFO_LOG("~MediaKeySessionImpl enter.");
48 Release();
49 std::lock_guard<std::recursive_mutex> lock(mutex_);
50 keySessionServiceProxy_ = nullptr;
51 DRM_DEBUG_LOG("0x%{public}06" PRIXPTR "MediaKeySessionImpl Instances release",
52 FAKE_POINTER(this));
53 }
54
MediaKeySessionServerDied(pid_t pid)55 void MediaKeySessionImpl::MediaKeySessionServerDied(pid_t pid)
56 {
57 DRM_ERR_LOG("MediaKeySession server has died, pid:%{public}d!", pid);
58 std::lock_guard<std::recursive_mutex> lock(mutex_);
59 if (keySessionServiceProxy_ != nullptr && keySessionServiceProxy_->AsObject() != nullptr
60 && deathRecipient_ != nullptr) {
61 (void)keySessionServiceProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
62 keySessionServiceProxy_ = nullptr;
63 }
64 deathRecipient_ = nullptr;
65 }
66
Release()67 int32_t MediaKeySessionImpl::Release()
68 {
69 DRM_INFO_LOG("MediaKeySessionImpl Release enter.");
70 if (keySessionServiceCallback_ != nullptr) {
71 keySessionServiceCallback_->Release();
72 keySessionServiceCallback_ = nullptr;
73 }
74 std::lock_guard<std::recursive_mutex> lock(mutex_);
75 int32_t ret = DRM_INNER_ERR_UNKNOWN;
76 if (keySessionServiceProxy_ != nullptr) {
77 sptr<IRemoteObject> object = keySessionServiceProxy_->AsObject();
78 if (object != nullptr && deathRecipient_ != nullptr) {
79 object->RemoveDeathRecipient(deathRecipient_);
80 deathRecipient_ = nullptr;
81 }
82 ret = keySessionServiceProxy_->Release();
83 if (ret != DRM_INNER_ERR_OK) {
84 DRM_ERR_LOG("Failed to Release key session!, %{public}d", ret);
85 }
86 } else {
87 DRM_ERR_LOG("MediaKeySessionServiceProxy_ == nullptr");
88 }
89 keySessionServiceProxy_ = nullptr;
90 return ret;
91 }
92
GenerateMediaKeyRequest(MediaKeyRequestInfo & licenseRequestInfo,MediaKeyRequest & licenseRequest)93 int32_t MediaKeySessionImpl::GenerateMediaKeyRequest(MediaKeyRequestInfo &licenseRequestInfo,
94 MediaKeyRequest &licenseRequest)
95 {
96 DrmTrace trace("GenerateMediaKeyRequest");
97 DRM_INFO_LOG("GenerateMediaKeyRequest enter.");
98 std::lock_guard<std::recursive_mutex> lock(mutex_);
99 int32_t retCode = DRM_INNER_ERR_OK;
100 if (keySessionServiceProxy_ == nullptr) {
101 DRM_ERR_LOG("GenerateMediaKeyRequest keySessionServiceProxy_ is null");
102 return DRM_INNER_ERR_INVALID_KEY_SESSION;
103 }
104 retCode = keySessionServiceProxy_->GenerateMediaKeyRequest(licenseRequestInfo, licenseRequest);
105 if (retCode != DRM_INNER_ERR_OK) {
106 DRM_ERR_LOG("GenerateMediaKeyRequest failed, retCode: %{public}d", retCode);
107 return DRM_INNER_ERR_BASE;
108 }
109 return DRM_INNER_ERR_OK;
110 }
111
ProcessMediaKeyResponse(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & licenseResponse)112 int32_t MediaKeySessionImpl::ProcessMediaKeyResponse(std::vector<uint8_t> &licenseId,
113 std::vector<uint8_t> &licenseResponse)
114 {
115 DrmTrace trace("MediaKeySessionImpl::ProcessMediaKeyResponse");
116 DRM_INFO_LOG("ProcessMediaKeyResponse enter.");
117 std::lock_guard<std::recursive_mutex> lock(mutex_);
118 int32_t retCode = DRM_INNER_ERR_OK;
119
120 if (keySessionServiceProxy_ == nullptr) {
121 DRM_ERR_LOG("ProcessMediaKeyResponse keySessionServiceProxy_ is null");
122 return DRM_INNER_ERR_INVALID_KEY_SESSION;
123 }
124 retCode = keySessionServiceProxy_->ProcessMediaKeyResponse(licenseId, licenseResponse);
125 if (retCode != DRM_INNER_ERR_OK) {
126 DRM_ERR_LOG("ProcessMediaKeyResponse failed, retCode: %{public}d", retCode);
127 return DRM_INNER_ERR_BASE;
128 }
129 return DRM_INNER_ERR_OK;
130 }
131
GenerateOfflineReleaseRequest(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseRequest)132 int32_t MediaKeySessionImpl::GenerateOfflineReleaseRequest(std::vector<uint8_t> &licenseId,
133 std::vector<uint8_t> &releaseRequest)
134 {
135 DRM_INFO_LOG("GenerateOfflineReleaseRequest enter.");
136 std::lock_guard<std::recursive_mutex> lock(mutex_);
137 int32_t retCode = DRM_INNER_ERR_OK;
138 if (keySessionServiceProxy_ == nullptr) {
139 DRM_ERR_LOG("GenerateOfflineReleaseRequest keySessionServiceProxy_ is null");
140 return DRM_INNER_ERR_INVALID_KEY_SESSION;
141 }
142
143 retCode = keySessionServiceProxy_->GenerateOfflineReleaseRequest(licenseId, releaseRequest);
144 if (retCode != DRM_INNER_ERR_OK) {
145 DRM_ERR_LOG("GenerateOfflineReleaseRequest failed, retCode: %{public}d", retCode);
146 return DRM_INNER_ERR_BASE;
147 }
148 return DRM_INNER_ERR_OK;
149 }
150
ProcessOfflineReleaseResponse(std::vector<uint8_t> & licenseId,std::vector<uint8_t> & releaseResponse)151 int32_t MediaKeySessionImpl::ProcessOfflineReleaseResponse(std::vector<uint8_t> &licenseId,
152 std::vector<uint8_t> &releaseResponse)
153 {
154 DRM_INFO_LOG("ProcessOfflineReleaseResponse enter.");
155 std::lock_guard<std::recursive_mutex> lock(mutex_);
156 int32_t retCode = DRM_INNER_ERR_OK;
157
158 if (keySessionServiceProxy_ == nullptr) {
159 DRM_ERR_LOG("ProcessOfflineReleaseResponse keySessionServiceProxy_ is null");
160 return DRM_INNER_ERR_INVALID_KEY_SESSION;
161 }
162 retCode = keySessionServiceProxy_->ProcessOfflineReleaseResponse(licenseId, releaseResponse);
163 if (retCode != DRM_INNER_ERR_OK) {
164 DRM_ERR_LOG("ProcessOfflineReleaseResponse failed, retCode: %{public}d", retCode);
165 return DRM_INNER_ERR_BASE;
166 }
167 return DRM_INNER_ERR_OK;
168 }
169
GetContentProtectionLevel(ContentProtectionLevel * securityLevel)170 int32_t MediaKeySessionImpl::GetContentProtectionLevel(ContentProtectionLevel *securityLevel)
171 {
172 DRM_INFO_LOG("GetContentProtectionLevel enter.");
173 std::lock_guard<std::recursive_mutex> lock(mutex_);
174 int32_t retCode = DRM_INNER_ERR_OK;
175 ContentProtectionLevel protectionLevel;
176
177 if (keySessionServiceProxy_ == nullptr) {
178 DRM_ERR_LOG("GetContentProtectionLevel serviceProxy_ is null");
179 return DRM_INNER_ERR_INVALID_KEY_SESSION;
180 }
181 retCode = keySessionServiceProxy_->GetContentProtectionLevel(protectionLevel);
182 *securityLevel = protectionLevel;
183 if (retCode != DRM_INNER_ERR_OK) {
184 DRM_ERR_LOG("GetContentProtectionLevel failed, retCode: %{public}d", retCode);
185 return DRM_INNER_ERR_BASE;
186 }
187 return DRM_INNER_ERR_OK;
188 }
189
CheckMediaKeyStatus(std::map<std::string,std::string> & licenseStatus)190 int32_t MediaKeySessionImpl::CheckMediaKeyStatus(std::map<std::string, std::string> &licenseStatus)
191 {
192 DRM_INFO_LOG("CheckMediaKeyStatus enter.");
193 std::lock_guard<std::recursive_mutex> lock(mutex_);
194 int32_t retCode = DRM_INNER_ERR_OK;
195
196 if (keySessionServiceProxy_ == nullptr) {
197 DRM_ERR_LOG("CheckMediaKeyStatus keySessionServiceProxy_ is null");
198 return DRM_INNER_ERR_INVALID_KEY_SESSION;
199 }
200 retCode = keySessionServiceProxy_->CheckMediaKeyStatus(licenseStatus);
201 if (retCode != DRM_INNER_ERR_OK) {
202 DRM_ERR_LOG("CheckMediaKeyStatus failed, retCode: %{public}d", retCode);
203 return DRM_INNER_ERR_BASE;
204 }
205 return DRM_INNER_ERR_OK;
206 }
207
RestoreOfflineMediaKeys(std::vector<uint8_t> & licenseId)208 int32_t MediaKeySessionImpl::RestoreOfflineMediaKeys(std::vector<uint8_t> &licenseId)
209 {
210 DRM_INFO_LOG("RestoreOfflineMediaKeys enter.");
211 std::lock_guard<std::recursive_mutex> lock(mutex_);
212 int32_t retCode = DRM_INNER_ERR_OK;
213
214 if (keySessionServiceProxy_ == nullptr) {
215 DRM_ERR_LOG("RestoreOfflineMediaKeys keySessionServiceProxy_ is null");
216 return DRM_INNER_ERR_INVALID_KEY_SESSION;
217 }
218 retCode = keySessionServiceProxy_->RestoreOfflineMediaKeys(licenseId);
219 if (retCode != DRM_INNER_ERR_OK) {
220 DRM_ERR_LOG("RestoreOfflineMediaKeys failed, retCode: %{public}d", retCode);
221 return DRM_INNER_ERR_BASE;
222 }
223 return DRM_INNER_ERR_OK;
224 }
225
ClearMediaKeys()226 int32_t MediaKeySessionImpl::ClearMediaKeys()
227 {
228 DRM_INFO_LOG("ClearMediaKeys enter.");
229 std::lock_guard<std::recursive_mutex> lock(mutex_);
230 int32_t retCode = DRM_INNER_ERR_OK;
231
232 if (keySessionServiceProxy_ == nullptr) {
233 DRM_ERR_LOG("ClearMediaKeys keySessionServiceProxy_ is null");
234 return DRM_INNER_ERR_INVALID_KEY_SESSION;
235 }
236 retCode = keySessionServiceProxy_->ClearMediaKeys();
237 if (retCode != DRM_INNER_ERR_OK) {
238 DRM_ERR_LOG("ClearMediaKeys failed, retCode: %{public}d", retCode);
239 return DRM_INNER_ERR_BASE;
240 }
241 return DRM_INNER_ERR_OK;
242 }
243
RequireSecureDecoderModule(std::string & mimeType,bool * status)244 int32_t MediaKeySessionImpl::RequireSecureDecoderModule(std::string &mimeType, bool *status)
245 {
246 DRM_INFO_LOG("RequireSecureDecoderModule enter.");
247 std::lock_guard<std::recursive_mutex> lock(mutex_);
248 int32_t retCode = DRM_INNER_ERR_OK;
249 bool decoderModuleStatus;
250
251 if (keySessionServiceProxy_ == nullptr) {
252 DRM_ERR_LOG("RequireSecureDecoderModule keySessionServiceProxy_ is null");
253 return DRM_INNER_ERR_INVALID_KEY_SESSION;
254 }
255 retCode = keySessionServiceProxy_->RequireSecureDecoderModule(mimeType, decoderModuleStatus);
256 *status = decoderModuleStatus;
257 if (retCode != DRM_INNER_ERR_OK) {
258 DRM_ERR_LOG("status: %{public}d", *status);
259 return retCode;
260 }
261 return DRM_INNER_ERR_OK;
262 }
263
GetMediaKeySessionServiceProxy()264 sptr<IMediaKeySessionService> MediaKeySessionImpl::GetMediaKeySessionServiceProxy()
265 {
266 DRM_INFO_LOG("GetMediaKeySessionServiceProxy enter.");
267 std::lock_guard<std::recursive_mutex> lock(mutex_);
268 if (keySessionServiceProxy_ != nullptr) {
269 DRM_DEBUG_LOG("MediaKeySessionImpl MediaKeySessionServiceProxy is not nullptr");
270 }
271 return keySessionServiceProxy_;
272 }
273
GetApplicationCallback()274 sptr<MediaKeySessionImplCallback> MediaKeySessionImpl::GetApplicationCallback()
275 {
276 DRM_INFO_LOG("GetApplicationCallback enter.");
277 return keySessionApplicationCallback_;
278 }
279
SetCallback(const sptr<MediaKeySessionImplCallback> & callback)280 int32_t MediaKeySessionImpl::SetCallback(const sptr<MediaKeySessionImplCallback> &callback)
281 {
282 DRM_DEBUG_LOG("0x%{public}06" PRIXPTR " SetCallback in", FAKE_POINTER(this));
283 std::lock_guard<std::recursive_mutex> lock(mutex_);
284 DRM_CHECK_AND_RETURN_RET_LOG(callback != nullptr, DRM_INNER_ERR_INVALID_VAL, "callback is nullptr");
285 keySessionApplicationCallback_ = callback;
286
287 int32_t ret = DRM_INNER_ERR_BASE;
288 keySessionServiceCallback_ = new (std::nothrow) MediaKeySessionServiceCallback(this);
289 if (keySessionServiceCallback_ == nullptr) {
290 DRM_ERR_LOG("MediaKeySessionServiceCallback alloc failed.");
291 return ret;
292 }
293 keySessionServiceCallback_->Init();
294 if (keySessionServiceProxy_ == nullptr) {
295 DRM_ERR_LOG("SetCallback keySessionServiceProxy_ is null");
296 return DRM_INNER_ERR_INVALID_KEY_SESSION;
297 }
298 ret = keySessionServiceProxy_->SetCallback(keySessionServiceCallback_);
299 if (ret != DRM_INNER_ERR_OK) {
300 DRM_ERR_LOG("SetCallback failed, retCode: %{public}d", ret);
301 return DRM_INNER_ERR_BASE;
302 }
303 return ret;
304 }
305
306
Init()307 void MediaKeySessionServiceCallback::Init()
308 {
309 DRM_INFO_LOG("MediaKeySessionServiceCallback::Init");
310 serviceThreadRunning = true;
311 eventQueueThread = std::thread([this] { this->ProcessEventMessage();});
312 }
313
Release()314 void MediaKeySessionServiceCallback::Release()
315 {
316 DRM_INFO_LOG("Release enter");
317 {
318 serviceThreadRunning = false;
319 {
320 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
321 cv.notify_all();
322 }
323 if (eventQueueThread.joinable()) {
324 eventQueueThread.join();
325 }
326 }
327 std::lock_guard<std::recursive_mutex> lock(mutex_);
328 keySessionImpl_ = nullptr;
329 }
330
InitEventMap()331 void MediaKeySessionServiceCallback::InitEventMap()
332 {
333 DRM_INFO_LOG("InitEventMap enter");
334 std::lock_guard<std::recursive_mutex> lock(mutex_);
335 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_KEY_NEEDED)] =
336 MediaKeySessionEvent::EVENT_STR_KEY_NEEDED;
337 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_KEY_EXPIRED)] =
338 MediaKeySessionEvent::EVENT_STR_KEY_EXPIRED;
339 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_EXPIRATION_UPDATED)] =
340 MediaKeySessionEvent::EVENT_STR_EXPIRATION_UPDATED;
341 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_KEY_CHANGED)] =
342 MediaKeySessionEvent::EVENT_STR_KEY_CHANGED;
343 eventMap_[static_cast<int32_t>(DrmEventType::DRM_EVENT_VENDOR_DEFINED)] =
344 MediaKeySessionEvent::EVENT_STR_VENDOR_DEFINED;
345 }
346
GetEventName(DrmEventType event)347 std::string MediaKeySessionServiceCallback::GetEventName(DrmEventType event)
348 {
349 DRM_INFO_LOG("GetEventName enter");
350 std::string eventName = "";
351 std::lock_guard<std::recursive_mutex> lock(mutex_);
352 int32_t eventType = static_cast<int32_t>(event);
353 if (eventMap_.find(eventType) == eventMap_.end()) {
354 return eventName;
355 }
356 return eventMap_[eventType];
357 }
358
SendEvent(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)359 int32_t MediaKeySessionServiceCallback::SendEvent(DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
360 {
361 DRM_INFO_LOG("SendEvent enter");
362 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
363 KeySessionEventMessage message;
364 message.messageType = KeySessionEventMessage::EventKey;
365 message.event = event;
366 message.extra = extra;
367 message.data = data;
368 eventQueue.push(message);
369 cv.notify_all();
370 return DRM_INNER_ERR_OK;
371 }
372
SendEventHandler(DrmEventType event,int32_t extra,const std::vector<uint8_t> & data)373 int32_t MediaKeySessionServiceCallback::SendEventHandler(
374 DrmEventType event, int32_t extra, const std::vector<uint8_t> &data)
375 {
376 DRM_INFO_LOG("SendEventHandler enter");
377 std::string eventName = GetEventName(event);
378 std::lock_guard<std::recursive_mutex> lock(mutex_);
379 if (keySessionImpl_ != nullptr && eventName.length() != 0) {
380 sptr<MediaKeySessionImplCallback> applicationCallback = keySessionImpl_->GetApplicationCallback();
381 if (applicationCallback != nullptr) {
382 applicationCallback->SendEvent(eventName, extra, data);
383 return DRM_INNER_ERR_OK;
384 }
385 }
386 DRM_DEBUG_LOG("SendEventHandler failed.");
387 return DRM_INNER_ERR_BASE;
388 }
389
SendEventKeyChanged(const std::map<std::vector<uint8_t>,MediaKeySessionKeyStatus> & statusTable,bool hasNewGoodLicense)390 int32_t MediaKeySessionServiceCallback::SendEventKeyChanged(
391 const std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> &statusTable, bool hasNewGoodLicense)
392 {
393 DRM_INFO_LOG("SendEventKeyChanged enter");
394 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
395 KeySessionEventMessage message;
396 message.messageType = KeySessionEventMessage::EventKeyChanged;
397 message.statusTable = statusTable;
398 message.hasNewGoodLicense = hasNewGoodLicense;
399 eventQueue.push(message);
400 cv.notify_all();
401 return DRM_INNER_ERR_OK;
402 }
403
SendEventKeyChangedHandler(const std::map<std::vector<uint8_t>,MediaKeySessionKeyStatus> & statusTable,bool hasNewGoodLicense)404 int32_t MediaKeySessionServiceCallback::SendEventKeyChangedHandler(
405 const std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> &statusTable, bool hasNewGoodLicense)
406 {
407 DRM_INFO_LOG("SendEventKeyChangedHandler enter.");
408 std::lock_guard<std::recursive_mutex> lock(mutex_);
409 if (keySessionImpl_ != nullptr) {
410 sptr<MediaKeySessionImplCallback> callback = keySessionImpl_->GetApplicationCallback();
411 if (callback != nullptr) {
412 callback->SendEventKeyChanged(statusTable, hasNewGoodLicense);
413 return DRM_INNER_ERR_OK;
414 }
415 }
416 DRM_ERR_LOG("SendEventKeyChangedHandler failed.");
417 return DRM_INNER_ERR_BASE;
418 }
419
ProcessEventMessage()420 void MediaKeySessionServiceCallback::ProcessEventMessage()
421 {
422 DRM_INFO_LOG("ProcessEventMessage msg enter");
423 while (serviceThreadRunning) {
424 std::unique_lock<std::mutex> queueMutexLock(queueMutex);
425 cv.wait_for(queueMutexLock, std::chrono::milliseconds(100L)); // 100ms
426 std::queue<KeySessionEventMessage> localQueue;
427 localQueue.swap(eventQueue);
428 queueMutexLock.unlock();
429 while (!localQueue.empty()) {
430 auto e = localQueue.front();
431 localQueue.pop();
432 if (e.messageType == KeySessionEventMessage::EventKeyChanged) {
433 SendEventKeyChangedHandler(e.statusTable, e.hasNewGoodLicense);
434 } else if (e.messageType == KeySessionEventMessage::EventKey) {
435 SendEventHandler(e.event, e.extra, e.data);
436 }
437 }
438 }
439 DRM_INFO_LOG("ProcessEventMessage msg exit");
440 }
441 } // DrmStandard
442 } // OHOS
443