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 #ifndef NATIVE_DRM_OBJECT_H
17 #define NATIVE_DRM_OBJECT_H
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include "native_drm_err.h"
22 #include "native_drm_base.h"
23 #include "native_drm_common.h"
24 
25 #include "key_session_impl.h"
26 #include "media_key_system_impl.h"
27 #include "native_mediakeysystem.h"
28 #include "native_mediakeysession.h"
29 
30 namespace OHOS {
31 namespace DrmStandard {
32 class MediaKeySystemCallbackCapi;
33 class MediaKeySessionCallbackCapi;
34 
35 struct MediaKeySystemObject : public MediaKeySystem {
MediaKeySystemObjectMediaKeySystemObject36     explicit MediaKeySystemObject(const OHOS::sptr<OHOS::DrmStandard::MediaKeySystemImpl> &impl) : systemImpl_(impl) {}
37     ~MediaKeySystemObject() = default;
38 
39     const OHOS::sptr<OHOS::DrmStandard::MediaKeySystemImpl> systemImpl_ = nullptr;
40     OHOS::sptr<OHOS::DrmStandard::MediaKeySystemCallbackCapi> systemCallback_ = nullptr;
41 };
42 
43 struct MediaKeySessionObject : public MediaKeySession {
MediaKeySessionObjectMediaKeySessionObject44     explicit MediaKeySessionObject(const OHOS::sptr<OHOS::DrmStandard::MediaKeySessionImpl> &impl) : sessionImpl_(impl)
45     {}
46     ~MediaKeySessionObject() = default;
47 
48     const OHOS::sptr<OHOS::DrmStandard::MediaKeySessionImpl> sessionImpl_ = nullptr;
49     OHOS::sptr<MediaKeySessionCallbackCapi> sessionCallback_ = nullptr;
50 };
51 
52 class MediaKeySystemCallbackCapi : public MediaKeySystemImplCallback {
53 public:
MediaKeySystemCallbackCapi()54     MediaKeySystemCallbackCapi() : system_(nullptr), callback_(nullptr), systemCallback_(nullptr)
55     {
56         DRM_INFO_LOG("MediaKeySystemCallbackCapi.");
57         InitEventMap();
58     }
59 
InitEventMap()60     void InitEventMap()
61     {
62         DRM_INFO_LOG("InitEventMap enter.");
63         eventMap_.insert({ MediaKeySystemEvent::EVENT_STR_PROVISION_REQUIRED,
64             EVENT_PROVISION_REQUIRED });
65         DRM_INFO_LOG("InitEventMap exit.");
66     }
67 
~MediaKeySystemCallbackCapi()68     virtual ~MediaKeySystemCallbackCapi()
69     {
70         DRM_INFO_LOG("~MediaKeySystemCallbackCapi.");
71     }
72 
SetCallbackReference(MediaKeySystem_Callback callback)73     void SetCallbackReference(MediaKeySystem_Callback callback)
74     {
75         DRM_INFO_LOG("MediaKeySystemCallbackCapi SetCallbackReference.");
76         std::lock_guard<std::mutex> lock(mutex_);
77         callback_ = callback;
78     }
79 
SetCallbackReference(MediaKeySystem * system,OH_MediaKeySystem_Callback systemCallback)80     void SetCallbackReference(MediaKeySystem *system, OH_MediaKeySystem_Callback systemCallback)
81     {
82         DRM_INFO_LOG("MediaKeySystemCallbackCapi SetCallbackReference.");
83         std::lock_guard<std::mutex> lock(mutex_);
84         system_ = system;
85         systemCallback_ = systemCallback;
86     }
87 
ClearCallbackReference()88     void ClearCallbackReference()
89     {
90         DRM_INFO_LOG("MediaKeySystemCallbackCapi ClearCallbackReference.");
91         std::lock_guard<std::mutex> lock(mutex_);
92         system_ = nullptr;
93         callback_ = nullptr;
94         systemCallback_ = nullptr;
95     }
96 
SendEvent(const std::string & event,int32_t extra,const std::vector<uint8_t> & data)97     void SendEvent(const std::string &event, int32_t extra, const std::vector<uint8_t> &data) override
98     {
99         DRM_INFO_LOG("MediaKeySystemCallbackCapi SendEvent.");
100         std::lock_guard<std::mutex> lock(mutex_);
101         DRM_CHECK_AND_RETURN_LOG((callback_ != nullptr) || (systemCallback_ != nullptr),
102             "hasn't register any callback of %{public}s event", event.c_str());
103 
104         if (eventMap_.find(event) == eventMap_.end()) {
105             DRM_ERR_LOG("MediaKeySystemCallbackCapi SendEvent failed, not find this event type.");
106             return;
107         }
108 
109         unsigned char *dataInfo = nullptr;
110         if (data.size() != 0) {
111             dataInfo = (unsigned char *)malloc(data.size());
112             DRM_CHECK_AND_RETURN_LOG(dataInfo != nullptr, "malloc faild!");
113             errno_t ret = memcpy_s(dataInfo, data.size(), data.data(), data.size());
114             if (ret != EOK) {
115                 DRM_ERR_LOG("memcpy_s faild!");
116                 free(dataInfo);
117                 dataInfo = nullptr;
118                 return;
119             }
120         }
121 
122         if (callback_ != nullptr) {
123             callback_(eventMap_[event], dataInfo, data.size(), std::to_string(extra).data());
124         }
125         if (systemCallback_ != nullptr) {
126             systemCallback_(system_, eventMap_[event], dataInfo, data.size(), std::to_string(extra).data());
127         }
128 
129         if (dataInfo != nullptr) {
130             free(dataInfo);
131             dataInfo = nullptr;
132         }
133     }
134 
135 private:
136     MediaKeySystem *system_ = nullptr;
137     MediaKeySystem_Callback callback_ = nullptr;
138     OH_MediaKeySystem_Callback systemCallback_ = nullptr;
139     std::mutex mutex_;
140     std::unordered_map<std::string, DRM_EventType> eventMap_;
141 };
142 
143 class MediaKeySessionCallbackCapi : public MediaKeySessionImplCallback {
144 public:
MediaKeySessionCallbackCapi()145     MediaKeySessionCallbackCapi() : session_(nullptr), callback_({}), sessionCallback_({})
146     {
147         DRM_INFO_LOG("MediaKeySessionCallbackCapi.");
148         InitEventMap();
149     }
150 
InitEventMap()151     void InitEventMap()
152     {
153         eventMap_.insert({ static_cast<std::string>(MediaKeySessionEvent::EVENT_STR_EXPIRATION_UPDATED),
154             EVENT_EXPIRATION_UPDATE });
155         eventMap_.insert(
156             { static_cast<std::string>(MediaKeySessionEvent::EVENT_STR_KEY_EXPIRED), EVENT_KEY_EXPIRED });
157         eventMap_.insert(
158             { static_cast<std::string>(MediaKeySessionEvent::EVENT_STR_KEY_NEEDED), EVENT_KEY_REQUIRED });
159         eventMap_.insert(
160             { static_cast<std::string>(MediaKeySessionEvent::EVENT_STR_VENDOR_DEFINED), EVENT_VENDOR_DEFINED });
161     }
162 
~MediaKeySessionCallbackCapi()163     virtual ~MediaKeySessionCallbackCapi()
164     {
165         DRM_INFO_LOG("~MediaKeySessionCallbackCapi.");
166     }
167 
SetCallbackReference(MediaKeySession_Callback callback)168     void SetCallbackReference(MediaKeySession_Callback callback)
169     {
170         DRM_INFO_LOG("MediaKeySessionCallbackCapi SetCallbackReference.");
171         std::lock_guard<std::mutex> lock(mutex_);
172         callback_ = callback;
173     }
174 
SetCallbackReference(MediaKeySession * session,OH_MediaKeySession_Callback sessionCallback)175     void SetCallbackReference(MediaKeySession *session, OH_MediaKeySession_Callback sessionCallback)
176     {
177         DRM_INFO_LOG("MediaKeySessionCallbackCapi SetCallbackReference.");
178         std::lock_guard<std::mutex> lock(mutex_);
179         session_ = session;
180         sessionCallback_ = sessionCallback;
181     }
182 
ClearCallbackReference()183     void ClearCallbackReference()
184     {
185         DRM_INFO_LOG("MediaKeySessionCallbackCapi ClearCallbackReference.");
186         std::lock_guard<std::mutex> lock(mutex_);
187         session_ = nullptr;
188         callback_ = {};
189         sessionCallback_ = {};
190     }
191 
SendEvent(const std::string & event,int32_t extra,const std::vector<uint8_t> & data)192     void SendEvent(const std::string &event, int32_t extra, const std::vector<uint8_t> &data) override
193     {
194         DRM_INFO_LOG("MediaKeySessionCallbackCapi SendEvent.");
195         std::lock_guard<std::mutex> lock(mutex_);
196         DRM_CHECK_AND_RETURN_LOG((callback_.eventCallback != nullptr) || (sessionCallback_.eventCallback != nullptr),
197             "hasn't register any callback of %{public}s event", event.c_str());
198         if (eventMap_.find(event) == eventMap_.end()) {
199             DRM_ERR_LOG("MediaKeySystemCallbackCapi SendEvent failed, not find this event type.");
200             return;
201         }
202 
203         unsigned char *dataInfo = nullptr;
204         if (data.size() != 0) {
205             dataInfo = (unsigned char *)malloc(data.size());
206             DRM_CHECK_AND_RETURN_LOG(dataInfo != nullptr, "malloc faild!");
207             errno_t ret = memcpy_s(dataInfo, data.size(), data.data(), data.size());
208             if (ret != EOK) {
209                 DRM_ERR_LOG("memcpy_s faild!");
210                 free(dataInfo);
211                 dataInfo = nullptr;
212                 return;
213             }
214         }
215 
216         if (callback_.eventCallback != nullptr) {
217             callback_.eventCallback(eventMap_[event], dataInfo, data.size(), std::to_string(extra).data());
218         }
219         if (sessionCallback_.eventCallback != nullptr) {
220             sessionCallback_.eventCallback(
221                 session_, eventMap_[event], dataInfo, data.size(), std::to_string(extra).data());
222         }
223 
224         if (dataInfo != nullptr) {
225             free(dataInfo);
226             dataInfo = nullptr;
227         }
228     }
229 
SendEventKeyChanged(std::map<std::vector<uint8_t>,MediaKeySessionKeyStatus> statusTable,bool hasNewGoodLicense)230     void SendEventKeyChanged(std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> statusTable,
231         bool hasNewGoodLicense) override
232     {
233         DRM_INFO_LOG("MediaKeySessionCallbackCapi SendEventKeyChanged.");
234         std::lock_guard<std::mutex> lock(mutex_);
235         DRM_CHECK_AND_RETURN_LOG((callback_.keyChangeCallback != nullptr) ||
236             (sessionCallback_.keyChangeCallback != nullptr), "hasn't register any callback of KeyChanged event!");
237 
238         static std::unordered_map<MediaKeySessionKeyStatus, std::string> KeyStatusStringMap {
239             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_USABLE, "USABLE"},
240             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_EXPIRED, "EXPIRED"},
241             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_OUTPUT_NOT_ALLOWED, "OUTPUT_NOT_ALLOWED"},
242             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_PENDING, "PENDING"},
243             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_INTERNAL_ERROR, "INTERNAL_ERROR"},
244             {MediaKeySessionKeyStatus::MEDIA_KEY_SESSION_KEY_STATUS_USABLE_IN_FUTURE, "USABLE_IN_FUTURE"},
245         };
246 
247         uint32_t tableCount = statusTable.size();
248         DRM_CHECK_AND_RETURN_LOG(tableCount <= MAX_KEY_INFO_COUNT, "DRM_KeysInfo has not enough space!");
249 
250         DRM_KeysInfo info;
251         info.keysInfoCount = tableCount;
252         uint32_t index = 0;
253         for (auto &item : statusTable) {
254             uint32_t keyIdSize = item.first.size();
255             DRM_CHECK_AND_RETURN_LOG(keyIdSize <= MAX_KEY_ID_LEN, "DRM_KeysInfo keyId has not enough space!");
256             errno_t ret = memset_s(info.keyId[index], MAX_KEY_ID_LEN, 0x00, MAX_KEY_ID_LEN);
257             DRM_CHECK_AND_RETURN_LOG(ret == EOK, "memset_s keyId failed!");
258             ret = memcpy_s(info.keyId[index], keyIdSize, item.first.data(), keyIdSize);
259             DRM_CHECK_AND_RETURN_LOG(ret == EOK, "memcpy_s keyId failed!");
260 
261             std::string keyStatus = KeyStatusStringMap[item.second];
262             uint32_t statusSize = keyStatus.size();
263             DRM_CHECK_AND_RETURN_LOG(statusSize <= MAX_KEY_STATUS_VALUE_LEN,
264                 "DRM_KeysInfo statusValue has not enough space!");
265             ret = memset_s(info.statusValue[index], MAX_KEY_STATUS_VALUE_LEN, 0x00, MAX_KEY_STATUS_VALUE_LEN);
266             DRM_CHECK_AND_RETURN_LOG(ret == EOK, "memset_s statusValue failed!");
267             ret = memcpy_s(info.statusValue[index], statusSize, keyStatus.data(), statusSize);
268             DRM_CHECK_AND_RETURN_LOG(ret == EOK, "memcpy_s statusValue failed!");
269 
270             index++;
271         }
272         if (callback_.keyChangeCallback != nullptr) {
273             callback_.keyChangeCallback(&info, hasNewGoodLicense);
274         }
275         if (sessionCallback_.keyChangeCallback != nullptr) {
276             sessionCallback_.keyChangeCallback(session_, &info, hasNewGoodLicense);
277         }
278     }
279 
280 private:
281     struct MediaKeySession *session_ = nullptr;
282     struct MediaKeySession_Callback callback_ = {};
283     struct OH_MediaKeySession_Callback sessionCallback_ = {};
284     std::mutex mutex_;
285     std::unordered_map<std::string, DRM_EventType> eventMap_;
286 };
287 } // DrmStandard
288 } // OHOS
289 
290 #endif // NATIVE_DRM_OBJECT_H
291