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