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 #ifndef NAPI_PARAM_UTILS_H
16 #define NAPI_PARAM_UTILS_H
17
18 #include <cstdint>
19 #include <map>
20 #include <list>
21 #include <string>
22 #include <mutex>
23 #include <vector>
24 #include "napi/native_api.h"
25 #include "napi/native_common.h"
26 #include "napi/native_node_api.h"
27 #include "napi_base_context.h"
28 #include "drm_log.h"
29 #include "drm_error_code.h"
30 #include "i_keysession_service.h"
31
32 namespace OHOS {
33 namespace DrmStandard {
34 /* Constants for array index */
35 const int32_t PARAM0 = 0;
36 const int32_t PARAM1 = 1;
37 const int32_t PARAM2 = 2;
38 const int32_t PARAM3 = 3;
39
40 /* Constants for array size */
41 const int32_t ARGS_ZERO = 0;
42 const int32_t ARGS_ONE = 1;
43 const int32_t ARGS_TWO = 2;
44 const int32_t ARGS_THREE = 3;
45 const int32_t ARGS_FOUR = 4;
46
47 const int32_t KEY_SYSTEM_MAX_NUMBER = 64;
48 const int32_t KEY_SESSION_MAX_NUMBER = 64;
49
50 enum NapiMediaKeyRequestType {
51 MEDIA_KEY_REQUEST_TYPE_UNKNOWN = 0,
52 MEDIA_KEY_REQUEST_TYPE_INITIAL,
53 MEDIA_KEY_REQUEST_TYPE_RENEWAL,
54 MEDIA_KEY_REQUEST_TYPE_RELEASE,
55 MEDIA_KEY_REQUEST_TYPE_NONE,
56 MEDIA_KEY_REQUEST_TYPE_UPDATE,
57 };
58
59 struct NapiProvisionRequest {
60 std::vector<uint8_t> data;
61 std::string defaultURL;
62 };
63
64 struct DrmEventParame {
65 int32_t extra;
66 std::vector<uint8_t> data;
67 };
68
69 struct DrmKeysChangeEventParame {
70 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> statusTable;
71 bool hasNewGoodLicense;
72 };
73
74 template<typename T>
75 class ObjectRefMap {
76 public:
77 static std::mutex allObjLock;
78 static std::map<T*, uint32_t> refMap;
79 static void Insert(T *obj);
80 static void Erase(T *obj);
81 static T *IncreaseRef(T *obj);
82 static void DecreaseRef(T *obj);
83
84 ObjectRefMap(T *obj);
85 ~ObjectRefMap();
86 T *GetPtr();
87
88 private:
89 T *obj_ = nullptr;
90 };
91
92 template <typename T>
93 std::mutex ObjectRefMap<T>::allObjLock;
94
95 template <typename T>
96 std::map<T *, uint32_t> ObjectRefMap<T>::refMap;
97
98 template <typename T>
Insert(T * obj)99 void ObjectRefMap<T>::Insert(T *obj)
100 {
101 std::lock_guard<std::mutex> lock(allObjLock);
102 refMap[obj] = 1;
103 }
104
105 template <typename T>
Erase(T * obj)106 void ObjectRefMap<T>::Erase(T *obj)
107 {
108 std::lock_guard<std::mutex> lock(allObjLock);
109 auto it = refMap.find(obj);
110 if (it != refMap.end()) {
111 refMap.erase(it);
112 }
113 }
114
115 template <typename T>
IncreaseRef(T * obj)116 T *ObjectRefMap<T>::IncreaseRef(T *obj)
117 {
118 std::lock_guard<std::mutex> lock(allObjLock);
119 if (refMap.count(obj)) {
120 refMap[obj]++;
121 return obj;
122 } else {
123 return nullptr;
124 }
125 }
126
127 template <typename T>
DecreaseRef(T * obj)128 void ObjectRefMap<T>::DecreaseRef(T *obj)
129 {
130 std::lock_guard<std::mutex> lock(allObjLock);
131 if (refMap.count(obj) && --refMap[obj] == 0) {
132 refMap.erase(obj);
133 delete obj;
134 obj = nullptr;
135 }
136 }
137
138 template <typename T>
ObjectRefMap(T * obj)139 ObjectRefMap<T>::ObjectRefMap(T *obj)
140 {
141 if (obj != nullptr) {
142 obj_ = ObjectRefMap::IncreaseRef(obj);
143 }
144 }
145
146 template <typename T>
~ObjectRefMap()147 ObjectRefMap<T>::~ObjectRefMap()
148 {
149 if (obj_ != nullptr) {
150 ObjectRefMap::DecreaseRef(obj_);
151 }
152 }
153
154 template <typename T>
GetPtr()155 T *ObjectRefMap<T>::GetPtr()
156 {
157 return obj_;
158 }
159
160 #define DRM_NAPI_GET_JS_ARGS(env, info, argc, argv, thisVar) \
161 do { \
162 void *data; \
163 napi_get_cb_info(env, info, &(argc), argv, &(thisVar), &data); \
164 } while (0)
165
166 #define DRM_NAPI_GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar) \
167 do { \
168 void *data; \
169 status = napi_get_cb_info(env, info, nullptr, nullptr, &(thisVar), &data); \
170 } while (0)
171
172 #define DRM_NAPI_CHECK_AND_RETURN_VOID_LOG(cond, fmt, ...) \
173 do { \
174 if (!(cond)) { \
175 DRM_ERR_LOG(fmt, ##__VA_ARGS__); \
176 return; \
177 } \
178 } while (0)
179
180 #define DRM_NAPI_CHECK_AND_RETURN_LOG(cond, status, fmt, ...) \
181 do { \
182 if (!(cond)) { \
183 DRM_ERR_LOG(fmt, ##__VA_ARGS__); \
184 return status; \
185 } \
186 } while (0)
187
188
189 /* check condition related to argc/argv, return and logging. */
190 #define NAPI_CHECK_ARGS_RETURN_VOID(context, condition, message, code) \
191 do { \
192 if (!(condition)) { \
193 (context)->status = napi_invalid_arg; \
194 (context)->errMessage = std::string(message); \
195 (context)->errCode = code; \
196 DRM_ERR_LOG("test (" #condition ") failed: " message); \
197 return; \
198 } \
199 } while (0)
200
201 #define NAPI_CHECK_STATUS_RETURN_VOID(context, message, code) \
202 do { \
203 if ((context)->status != napi_ok) { \
204 (context)->errMessage = std::string(message); \
205 (context)->errCode = code; \
206 DRM_ERR_LOG("test (context->status == napi_ok) failed: " message); \
207 return; \
208 } \
209 } while (0)
210
211 class NapiParamUtils {
212 public:
213 static napi_status GetValueInt32(const napi_env &env, int32_t &value, napi_value in);
214 static napi_status SetValueInt32(const napi_env &env, const int32_t &value, napi_value &result);
215 static napi_status GetValueInt32(const napi_env &env, const std::string &fieldStr, int32_t &value, napi_value in);
216 static napi_status SetValueInt32(const napi_env &env, const std::string &fieldStr,
217 const int32_t value, napi_value &result);
218
219 static std::string GetStringArgument(napi_env env, napi_value value);
220 static napi_status SetValueString(const napi_env &env, const std::string &stringValue, napi_value &result);
221 static napi_status SetValueString(const napi_env &env, const std::string &fieldStr, const std::string &stringValue,
222 napi_value &result);
223
224 static napi_value GetUndefinedValue(napi_env env);
225
226 static napi_status SetValueUint8Array(const napi_env &env, const std::vector<uint8_t> &value,
227 napi_value &result);
228 static napi_status SetValueUint8Array(const napi_env &env, const std::string &fieldStr,
229 const std::vector<uint8_t> &value, napi_value &result);
230 static napi_status GetValueUint8Array(const napi_env &env, std::vector<uint8_t> &value,
231 napi_value in);
232 static napi_status SetValueBoolean(const napi_env &env, const bool boolValue, napi_value &result);
233 static napi_status SetValueMap(const napi_env &env,
234 std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> statusTable, napi_value &result);
235
236 static napi_status GetValueOptionsData(const napi_env &env, std::map<std::string, std::string> &valueMap,
237 napi_value in);
238 static napi_status SetProvisionRequest(const napi_env &env, const NapiProvisionRequest &provisionRequest,
239 napi_value &result);
240 static napi_status SetMediaKeyRequest(const napi_env &env,
241 const IMediaKeySessionService::MediaKeyRequest &mediaKeyRequest, napi_value &result);
242 static napi_status SetDrmEventInfo(const napi_env &env, DrmEventParame &eventParame,
243 napi_value &result);
244 static napi_status SetDrmKeysChangeEventInfo(const napi_env &env, DrmKeysChangeEventParame &eventParame,
245 napi_value &statusTable, napi_value &hasNewGoodLicense);
246 };
247 } // namespace DrmStandard
248 } // namespace OHOS
249 #endif // NAPI_PARAM_UTILS_H
250