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