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