1 /* 2 * Copyright (c) 2025 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 DRM_ADAPTER_IMPL_H 17 #define DRM_ADAPTER_IMPL_H 18 19 #include <mutex> 20 #include <pthread.h> 21 #include <securec.h> 22 23 #include "drm_adapter.h" 24 #include "native_drm_common.h" 25 #include "native_drm_err.h" 26 #include "nweb_log.h" 27 28 namespace OHOS::NWeb { 29 30 const std::string SECURITY_LEVEL = "securityLevel"; 31 const std::string SERVER_CERTIFICATE = "serviceCertificate"; 32 const std::string ORIGIN = "origin"; 33 const std::string PRIVACY_MODE = "privacyMode"; 34 const std::string SESSION_SHARING = "sessionSharing"; 35 const std::string ENABLE = "enable"; 36 const std::string WIDEVINE_NAME = "com.widevine.alpha"; 37 const std::string WISEPLAY_NAME = "com.wiseplay.drm"; 38 39 constexpr int32_t SECURITY_LEVEL_1 = 1; 40 constexpr int32_t SECURITY_LEVEL_3 = 3; 41 constexpr int32_t SECURITY_LEVEL_UNKNOWN = 0; 42 constexpr int32_t INFO_SIZE = 8; 43 constexpr int32_t MAX_URL_LENGTH = 2048; 44 constexpr int32_t MAX_REQUEST_LENGTH = 12288; 45 constexpr int32_t HEX_OFFSET = 4; 46 constexpr int32_t MAX_KEY_SET_ID_LEN = 128; 47 constexpr uint64_t MILLISECOND_IN_SECOND = 1000; 48 constexpr int32_t MILLISECOND_DIGITS = 3; 49 constexpr int32_t EXPIRATION_INFO_MAX_LEN = 16; 50 constexpr int32_t EXPIRATION_INFO_BASE = 10; 51 52 enum class MediaKeyType : int32_t { 53 MEDIA_KEY_TYPE_OFFLINE = 0, 54 MEDIA_KEY_TYPE_ONLINE, 55 MEDIA_KEY_TYPE_RELEASE, 56 }; 57 58 enum class ClearInfoType : int32_t { 59 KEY_RELEASE = 0, 60 LOAD_FAIL, 61 }; 62 63 enum class KeyStatus : uint32_t { 64 KEY_STATUS_USABLE = 0, 65 KEY_STATUS_EXPIRED = 1, 66 KEY_STATUS_OUTPUT_NOT_ALLOWED = 2, 67 KEY_STATUS_PENDING = 3, 68 KEY_STATUS_INTERNAL_ERROR = 4, 69 KEY_STATUS_USABLE_IN_FUTURE = 5, 70 }; 71 72 enum class DrmResult : int32_t { 73 DRM_RESULT_ERROR = -1, 74 DRM_RESULT_OK = 0, 75 }; 76 77 class SessionId { 78 public: CreateSessionId(const std::string & emeId)79 static std::shared_ptr<SessionId> CreateSessionId(const std::string& emeId) 80 { 81 return std::make_shared<SessionId>(emeId, nullptr, 0); 82 } 83 SessionId(std::string emeId,const uint8_t * keySetId,int32_t keySetIdLen)84 SessionId(std::string emeId, const uint8_t* keySetId, int32_t keySetIdLen) 85 : emeId_(emeId), keySetIdLen_(keySetIdLen) 86 { 87 (void)memset_s(keySetId_, sizeof(keySetId_), 0, sizeof(keySetId_)); 88 if (keySetId != nullptr && keySetIdLen > 0 && keySetIdLen <= MAX_KEY_SET_ID_LEN) { 89 if (memcpy_s(keySetId_, sizeof(keySetId_), keySetId, keySetIdLen) != 0) { 90 WVLOG_E("memcpy_s failed!"); 91 } 92 } 93 } 94 EmeId()95 std::string EmeId() 96 { 97 return emeId_; 98 } 99 KeySetId()100 uint8_t* KeySetId() 101 { 102 return keySetId_; 103 } 104 KeySetIdLen()105 int32_t KeySetIdLen() 106 { 107 return keySetIdLen_; 108 } 109 SetKeySetId(uint8_t * keySetId,int32_t keySetIdLen)110 void SetKeySetId(uint8_t* keySetId, int32_t keySetIdLen) 111 { 112 if (keySetIdLen > MAX_KEY_SET_ID_LEN) { 113 WVLOG_E("keySetIdLen error!"); 114 return; 115 } 116 if (keySetId == nullptr || keySetIdLen <= 0) { 117 (void)memset_s(keySetId_, sizeof(keySetId_), 0, sizeof(keySetId_)); 118 } else { 119 if (memcpy_s(keySetId_, sizeof(keySetId_), keySetId, keySetIdLen) != 0) { 120 WVLOG_E("memcpy_s failed!"); 121 } 122 } 123 keySetIdLen_ = keySetIdLen; 124 } 125 126 private: 127 std::string emeId_; 128 uint8_t keySetId_[MAX_KEY_SET_ID_LEN]; 129 int32_t keySetIdLen_; 130 }; 131 132 class SessionInfo { 133 public: SessionInfo(std::shared_ptr<SessionId> sessionId,std::string mimeType,int32_t keyType)134 SessionInfo(std::shared_ptr<SessionId> sessionId, std::string mimeType, int32_t keyType) 135 : sessionId_(sessionId), mimeType_(mimeType), keyType_(keyType) 136 {} 137 MimeType()138 std::string MimeType() 139 { 140 return mimeType_; 141 } 142 KeyType()143 int32_t KeyType() 144 { 145 return keyType_; 146 } 147 SetKeyType(int32_t keyType)148 void SetKeyType(int32_t keyType) 149 { 150 keyType_ = keyType; 151 } 152 GetSessionId()153 std::shared_ptr<SessionId> GetSessionId() 154 { 155 return sessionId_; 156 } 157 158 private: 159 std::shared_ptr<SessionId> sessionId_; 160 std::string mimeType_; 161 int32_t keyType_; 162 }; 163 164 class DrmCallbackImpl { 165 public: 166 DrmCallbackImpl(std::shared_ptr<DrmCallbackAdapter> callbackAdapter); 167 ~DrmCallbackImpl() = default; 168 169 void OnSessionMessage(const std::string& sessionId, int32_t& type, const std::vector<uint8_t>& message); 170 void OnProvisionRequest(const std::string& defaultUrl, const std::string& requestData); 171 void OnProvisioningComplete(bool success); 172 void OnMediaKeySessionReady(void* session); 173 void OnPromiseRejected(uint32_t promiseId, const std::string& errorMessage); 174 void OnPromiseResolved(uint32_t promiseId); 175 void OnPromiseResolvedWithSession(uint32_t promiseId, const std::string& sessionId); 176 void OnSessionClosed(const std::string& sessionId); 177 void OnSessionKeysChange(const std::string& sessionId, const std::vector<std::string>& keyIdArray, 178 const std::vector<uint32_t>& statusArray, bool hasAdditionalUsableKey, bool isKeyRelease); 179 void OnSessionExpirationUpdate(const std::string& sessionId, uint64_t expirationTime); 180 void OnStorageProvisioned(); 181 void OnStorageSaveInfo(const std::vector<uint8_t>& ketSetId, const std::string& mimeType, 182 const std::string& sessionId, int32_t keyType); 183 void OnStorageLoadInfo(const std::string& sessionId); 184 void OnStorageClearInfoForKeyRelease(const std::string& sessionId); 185 void OnStorageClearInfoForLoadFail(const std::string& sessionId); 186 void OnMediaLicenseReady(bool success); 187 188 void UpdateEmeId(const std::string& emeId, bool isRelease); 189 void UpdateMimeType(const std::string& mimeType, int32_t type); 190 191 std::string EmeId(); 192 std::string MimeType(); 193 bool IsRelease(); 194 int32_t Type(); 195 196 private: 197 std::shared_ptr<DrmCallbackAdapter> callbackAdapter_; 198 std::string emeId_ = ""; 199 std::string mimeType_ = ""; 200 bool isRelease_ = false; 201 int32_t type_ = -1; 202 }; 203 204 class DrmAdapterImpl : public DrmAdapter { 205 public: 206 DrmAdapterImpl() = default; 207 ~DrmAdapterImpl() override; 208 209 static Drm_ErrCode SystemCallBackWithObj( 210 MediaKeySystem* mediaKeySystem, DRM_EventType eventType, uint8_t* info, int32_t infoLen, char* extra); 211 static Drm_ErrCode SessoinEventCallBackWithObj( 212 MediaKeySession* mediaKeySessoin, DRM_EventType eventType, uint8_t* info, int32_t infoLen, char* extra); 213 static Drm_ErrCode SessoinKeyChangeCallBackWithObj( 214 MediaKeySession* mediaKeySessoin, DRM_KeysInfo* keysInfo, bool newKeysAvailable); 215 216 bool IsSupported(const std::string& name) override; 217 bool IsSupported2(const std::string& name, const std::string& mimeType) override; 218 bool IsSupported3(const std::string& name, const std::string& mimeType, int32_t level) override; 219 std::vector<uint8_t> GetUUID(const std::string& name) override; 220 void StorageProvisionedResult(bool result) override; 221 void StorageSaveInfoResult(bool result, int32_t type) override; 222 void StorageLoadInfoResult(const std::string& sessionId, const std::vector<uint8_t>& keySetId, 223 const std::string& mimeType, uint32_t keyType) override; 224 void StorageClearInfoResult(bool result, int32_t type) override; 225 226 int32_t CreateKeySystem(const std::string& name, const std::string& origin, int32_t securityLevel) override; 227 int32_t ProcessKeySystemResponse(const std::string& response, bool isResponseReceived) override; 228 int32_t GenerateMediaKeyRequest(const std::string& sessionId, int32_t type, int32_t initDataLen, 229 const std::vector<uint8_t>& initData, const std::string& mimeType, uint32_t promiseId) override; 230 int32_t UpdateSession(uint32_t promiseId, const std::string& sessionId, std::vector<uint8_t> response) override; 231 int32_t CloseSession(uint32_t promiseId, const std::string& sessionId) override; 232 int32_t RemoveSession(uint32_t promiseId, const std::string& sessionId) override; 233 int32_t LoadSession(uint32_t promiseId, const std::string& sessionId) override; 234 int32_t ReleaseMediaKeySystem() override; 235 int32_t ReleaseMediaKeySession() override; 236 237 int32_t SetConfigurationString(const std::string& configName, const std::string& value) override; 238 int32_t GetConfigurationString(const std::string& configName, char* value, int32_t valueLen) override; 239 int32_t SetConfigurationByteArray(const std::string& configName, const uint8_t* value, int32_t valueLen) override; 240 int32_t GetConfigurationByteArray(const std::string& configName, uint8_t* value, int32_t* valueLen) override; 241 int32_t GetMaxContentProtectionLevel(int32_t& level) override; 242 int32_t GetCertificateStatus(int32_t& certStatus) override; 243 int32_t RegistDrmCallback(std::shared_ptr<DrmCallbackAdapter> callbackAdapter) override; 244 int32_t ClearMediaKeys() override; 245 int32_t GetSecurityLevel() override; 246 int32_t RequireSecureDecoderModule(const std::string& mimeType, bool& status) override; 247 248 private: 249 int32_t CreateMediaKeySession(); 250 void PutSessionInfo(std::shared_ptr<SessionId> sessionId, const std::string& mimeType, int32_t type); 251 std::shared_ptr<SessionInfo> GetSessionInfo(std::shared_ptr<SessionId> sessionId); 252 void RemoveSessionInfo(std::shared_ptr<SessionId> sessionId); 253 void LoadSessionInfo(const std::string& emeId); 254 void LoadSessionWithLoadedStorage(std::shared_ptr<SessionId> sessionId, uint32_t promiseId); 255 void UpdateSessionResult( 256 bool isKeyRelease, std::shared_ptr<SessionId> sessionId, uint8_t* mediaKeyId, int32_t mediaKeyIdLen); 257 258 void SetKeyType(std::shared_ptr<SessionId> sessionId, int32_t keyType); 259 void SetKeySetId(std::shared_ptr<SessionId> sessionId, uint8_t* mediaKeyId, int32_t mediaKeyIdLen); 260 261 std::shared_ptr<SessionId> GetSessionIdByEmeId(const std::string& emeId); 262 263 void ClearPersistentSessionInfoFroKeyRelease(std::shared_ptr<SessionId> sessionId); 264 void ClearPersistentSessionInfoForLoadFail(std::shared_ptr<SessionId> sessionId); 265 266 void HandleKeyUpdatedCallback(uint32_t promiseId, bool result); 267 268 static void OnSessionExpirationUpdate(MediaKeySession* drmKeySessoin, uint8_t* info, int32_t infoLen); 269 static void GetKeyRequest(MediaKeySession* drmKeySessoin, uint8_t* info, int32_t infoLen); 270 271 private: 272 static std::unordered_map<MediaKeySystem*, std::shared_ptr<DrmCallbackImpl>> mediaKeySystemCallbackMap_; 273 static std::unordered_map<MediaKeySession*, std::shared_ptr<DrmCallbackImpl>> mediaKeySessionCallbackMap_; 274 static std::mutex mediaKeySystemCallbackMapMutex_; 275 static std::mutex mediaKeySessionCallbackMutex_; 276 277 MediaKeySystem* drmKeySystem_ = nullptr; 278 MediaKeySession* drmKeySessoin_ = nullptr; 279 DRM_ContentProtectionLevel contentProtectionLevel_ = CONTENT_PROTECTION_LEVEL_UNKNOWN; 280 std::shared_ptr<DrmCallbackImpl> callback_ = nullptr; 281 282 std::unordered_map<std::string, std::shared_ptr<SessionInfo>> emeSessionInfoMap_; 283 uint32_t removeSessionPromiseId_ = 0; 284 uint32_t updateSessionPromiseId_ = 0; 285 uint32_t loadSessionPromiseId_ = 0; 286 std::string releaseEmeId_ = ""; 287 bool isWiseplay_ = false; 288 }; 289 } // namespace OHOS::NWeb 290 #endif // DRM_ADAPTER_IMPL_H