• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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