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 #include "napi_param_utils.h"
17 
18 namespace OHOS {
19 namespace DrmStandard {
GetUndefinedValue(napi_env env)20 napi_value NapiParamUtils::GetUndefinedValue(napi_env env)
21 {
22     napi_value result {};
23     napi_get_undefined(env, &result);
24     return result;
25 }
26 
GetValueInt32(const napi_env & env,int32_t & value,napi_value in)27 napi_status NapiParamUtils::GetValueInt32(const napi_env &env, int32_t &value, napi_value in)
28 {
29     napi_status status = napi_get_value_int32(env, in, &value);
30     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_value_int32 failed.");
31     return status;
32 }
33 
SetValueInt32(const napi_env & env,const int32_t & value,napi_value & result)34 napi_status NapiParamUtils::SetValueInt32(const napi_env &env, const int32_t &value, napi_value &result)
35 {
36     napi_status status = napi_create_int32(env, value, &result);
37     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed.");
38     return status;
39 }
40 
GetValueInt32(const napi_env & env,const std::string & fieldStr,int32_t & value,napi_value in)41 napi_status NapiParamUtils::GetValueInt32(const napi_env &env, const std::string &fieldStr, int32_t &value,
42     napi_value in)
43 {
44     napi_value jsValue = nullptr;
45     napi_status status = napi_get_named_property(env, in, fieldStr.c_str(), &jsValue);
46     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_named_property failed.");
47     status = GetValueInt32(env, value, jsValue);
48     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "GetValueInt32 napi_get_value_int32 failed.");
49     return status;
50 }
51 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int32_t value,napi_value & result)52 napi_status NapiParamUtils::SetValueInt32(const napi_env &env, const std::string &fieldStr, const int32_t value,
53     napi_value &result)
54 {
55     napi_value jsValue = nullptr;
56     napi_status status = SetValueInt32(env, value, jsValue);
57     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed.");
58     status = napi_set_named_property(env, result, fieldStr.c_str(), jsValue);
59     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueInt32 napi_create_int32 failed.");
60     return status;
61 }
62 
GetStringArgument(napi_env env,napi_value value)63 std::string NapiParamUtils::GetStringArgument(napi_env env, napi_value value)
64 {
65     std::string strValue = "";
66     size_t bufLength = 0;
67     napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &bufLength);
68     if (status == napi_ok && bufLength > 0 && bufLength < PATH_MAX) {
69         strValue.reserve(bufLength + 1);
70         strValue.resize(bufLength);
71         status = napi_get_value_string_utf8(env, value, strValue.data(), bufLength + 1, &bufLength);
72         if (status == napi_ok) {
73             DRM_DEBUG_LOG("argument = %{public}s", strValue.c_str());
74         }
75     }
76     return strValue;
77 }
78 
SetValueString(const napi_env & env,const std::string & stringValue,napi_value & result)79 napi_status NapiParamUtils::SetValueString(const napi_env &env, const std::string &stringValue, napi_value &result)
80 {
81     napi_status status = napi_create_string_utf8(env, stringValue.c_str(), NAPI_AUTO_LENGTH, &result);
82     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString napi_create_string_utf8 failed.");
83     return status;
84 }
85 
SetValueString(const napi_env & env,const std::string & fieldStr,const std::string & stringValue,napi_value & result)86 napi_status NapiParamUtils::SetValueString(const napi_env &env, const std::string &fieldStr,
87     const std::string &stringValue, napi_value &result)
88 {
89     napi_value value = nullptr;
90     napi_status status = SetValueString(env, stringValue.c_str(), value);
91     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString failed.");
92     status = napi_set_named_property(env, result, fieldStr.c_str(), value);
93     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueString napi_set_named_property failed.");
94     return status;
95 }
96 
SetValueUint8Array(const napi_env & env,const std::vector<uint8_t> & value,napi_value & result)97 napi_status NapiParamUtils::SetValueUint8Array(const napi_env &env, const std::vector<uint8_t> &value,
98     napi_value &result)
99 {
100     napi_status status = napi_create_array(env, &result);
101     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueUint8Array napi_create_array failed.");
102     for (size_t i = 0; i < value.size(); i++) {
103         napi_value item;
104         status = napi_create_int32(env, value[i], &item);
105         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_create_int32 failed.");
106         status = napi_set_element(env, result, i, item);
107         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_set_element failed.");
108     }
109     return status;
110 }
111 
SetValueUint8Array(const napi_env & env,const std::string & fieldStr,const std::vector<uint8_t> & value,napi_value & result)112 napi_status NapiParamUtils::SetValueUint8Array(const napi_env &env, const std::string &fieldStr,
113     const std::vector<uint8_t> &value, napi_value &result)
114 {
115     napi_value jsValue = nullptr;
116     napi_status status = SetValueUint8Array(env, value, jsValue);
117     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueUint8Array failed.");
118     status = napi_set_named_property(env, result, fieldStr.c_str(), jsValue);
119     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_set_named_property failed.");
120     return status;
121 }
122 
GetValueUint8Array(const napi_env & env,std::vector<uint8_t> & value,napi_value in)123 napi_status NapiParamUtils::GetValueUint8Array(const napi_env &env, std::vector<uint8_t> &value, napi_value in)
124 {
125     void *reponseData = nullptr;
126     size_t reponseDataLen;
127     size_t offset;
128     napi_value arraybuffer = nullptr;
129     napi_typedarray_type type;
130     napi_status status = napi_get_typedarray_info(env, in, &type, &reponseDataLen, &reponseData, &arraybuffer, &offset);
131     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "napi_get_typedarray_info failed.");
132     uint8_t *reponseDataPtr = reinterpret_cast<uint8_t *>(reponseData);
133     std::vector<uint8_t> initDataStr(reponseDataPtr, reponseDataPtr + reponseDataLen);
134     value.assign(initDataStr.begin(), initDataStr.end());
135     return status;
136 }
137 
SetValueBoolean(const napi_env & env,const bool boolValue,napi_value & result)138 napi_status NapiParamUtils::SetValueBoolean(const napi_env &env, const bool boolValue, napi_value &result)
139 {
140     napi_status status = napi_get_boolean(env, boolValue, &result);
141     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetValueBoolean napi_get_boolean failed.");
142     return status;
143 }
144 
SetValueMap(const napi_env & env,std::map<std::vector<uint8_t>,MediaKeySessionKeyStatus> statusTable,napi_value & statusTableMap)145 napi_status NapiParamUtils::SetValueMap(const napi_env &env,
146     std::map<std::vector<uint8_t>, MediaKeySessionKeyStatus> statusTable, napi_value &statusTableMap)
147 {
148     uint32_t index = 0;
149     napi_status status;
150     napi_create_array_with_length(env, statusTable.size(), &statusTableMap);
151     for (auto itemTmp : statusTable) {
152         napi_value jsObject;
153         napi_value jsKeyId;
154         napi_value jsKeyStatus;
155         napi_create_object(env, &jsObject);
156         status = napi_create_array_with_length(env, itemTmp.first.size(), &jsKeyId);
157         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_create_array_with_length");
158         for (uint32_t i = 0; i < itemTmp.first.size(); i++) {
159             napi_value number = nullptr;
160             (void)napi_create_uint32(env, itemTmp.first[i], &number);
161             (void)napi_set_element(env, jsKeyId, i, number);
162         }
163         status = napi_set_named_property(env, jsObject, "keyId", jsKeyId);
164         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_named_property");
165         std::string value;
166         switch (itemTmp.second) {
167             case MEDIA_KEY_SESSION_KEY_STATUS_USABLE:
168                 value = "USABLE";
169                 break;
170             case MEDIA_KEY_SESSION_KEY_STATUS_EXPIRED:
171                 value = "EXPIRED";
172                 break;
173             case MEDIA_KEY_SESSION_KEY_STATUS_OUTPUT_NOT_ALLOWED:
174                 value = "OUTPUT_NOT_ALLOWED";
175                 break;
176             case MEDIA_KEY_SESSION_KEY_STATUS_PENDING:
177                 value = "PENDING";
178                 break;
179             case MEDIA_KEY_SESSION_KEY_STATUS_INTERNAL_ERROR:
180                 value = "INTERNAL_ERROR";
181                 break;
182             case MEDIA_KEY_SESSION_KEY_STATUS_USABLE_IN_FUTURE:
183                 value = "USABLE_IN_FUTURE";
184                 break;
185             default:
186                 value = "Fault Status";
187                 break;
188         }
189         status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &jsKeyStatus);
190         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_create_string_utf8");
191         status = napi_set_named_property(env, jsObject, "value", jsKeyStatus);
192         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_named_property");
193         status = napi_set_element(env, statusTableMap, index, jsObject);
194         DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "failed to call napi_set_element");
195         index++;
196     }
197     return status;
198 }
199 
GetValueOptionsData(const napi_env & env,std::map<std::string,std::string> & valueMap,napi_value in)200 napi_status NapiParamUtils::GetValueOptionsData(const napi_env &env, std::map<std::string, std::string> &valueMap,
201     napi_value in)
202 {
203     uint32_t optionalDataCount = 0;
204     napi_status status = napi_get_array_length(env, in, &optionalDataCount);
205     if (optionalDataCount > 0) {
206         for (size_t i = 0; i < optionalDataCount; i++) {
207             napi_value tmpData;
208             napi_value tmpName;
209             napi_value tmpValue;
210             size_t nameLength = 0;
211             size_t valueLength = 0;
212             status = napi_get_element(env, in, i, &tmpData);
213             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData element!");
214             status = napi_get_named_property(env, tmpData, "name", &tmpName);
215             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData property!");
216             status = napi_get_named_property(env, tmpData, "value", &tmpValue);
217             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "Could not able to read optionalData property!");
218             status = napi_get_value_string_utf8(env, tmpName, nullptr, 0, &nameLength);
219             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status,
220                 "Could not able to transfer optionalData buffer info!");
221             status = napi_get_value_string_utf8(env, tmpValue, nullptr, 0, &valueLength);
222             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status,
223                 "Could not able to transfer optionalData buffer info!");
224             std::string name(nameLength, 0);
225             status = napi_get_value_string_utf8(env, tmpName, &name[0], nameLength + 1, &nameLength);
226             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status,
227                 "Could not able to transfer optionalData buffer info!");
228             std::string value(valueLength, 0);
229             status = napi_get_value_string_utf8(env, tmpValue, &value[0], valueLength + 1, &valueLength);
230             DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status,
231                 "Could not able to transfer optionalData buffer info!");
232             valueMap.insert(std::make_pair(name, value));
233         }
234     }
235     return status;
236 }
237 
SetProvisionRequest(const napi_env & env,const NapiProvisionRequest & provisionRequest,napi_value & result)238 napi_status NapiParamUtils::SetProvisionRequest(const napi_env &env, const NapiProvisionRequest &provisionRequest,
239     napi_value &result)
240 {
241     napi_status status = napi_create_object(env, &result);
242     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetProvisionRequest napi_create_object failed.");
243     status = SetValueString(env, "defaultURL", provisionRequest.defaultURL, result);
244     status = SetValueUint8Array(env, "data", provisionRequest.data, result);
245     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetProvisionRequest SetValueUint8Array failed.");
246     return status;
247 }
248 
SetMediaKeyRequest(const napi_env & env,const IMediaKeySessionService::MediaKeyRequest & mediaKeyRequest,napi_value & result)249 napi_status NapiParamUtils::SetMediaKeyRequest(const napi_env &env,
250     const IMediaKeySessionService::MediaKeyRequest &mediaKeyRequest, napi_value &result)
251 {
252     napi_status status = napi_create_object(env, &result);
253     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest napi_create_object failed.");
254     status = SetValueInt32(env, "mediaKeyRequestType", mediaKeyRequest.requestType, result);
255     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueInt32 failed.");
256     status = SetValueUint8Array(env, "data", mediaKeyRequest.mData, result);
257     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueUint8Array failed.");
258     status = SetValueString(env, "defaultURL", mediaKeyRequest.mDefaultURL, result);
259     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetMediaKeyRequest SetValueString failed.");
260     return status;
261 }
262 
SetDrmEventInfo(const napi_env & env,DrmEventParame & eventParame,napi_value & result)263 napi_status NapiParamUtils::SetDrmEventInfo(const napi_env &env, DrmEventParame &eventParame, napi_value &result)
264 {
265     napi_status status = napi_create_object(env, &result);
266     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo napi_create_object failed.");
267     status = SetValueUint8Array(env, "info", eventParame.data, result);
268     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo SetValueUint8Array failed.");
269     status = SetValueString(env, "extraInfo", std::to_string(eventParame.extra), result);
270     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmEventInfo SetValueString failed.");
271     return status;
272 }
273 
SetDrmKeysChangeEventInfo(const napi_env & env,DrmKeysChangeEventParame & eventParame,napi_value & statusTable,napi_value & hasNewGoodLicense)274 napi_status NapiParamUtils::SetDrmKeysChangeEventInfo(const napi_env &env, DrmKeysChangeEventParame &eventParame,
275     napi_value &statusTable, napi_value &hasNewGoodLicense)
276 {
277     napi_status status = SetValueMap(env, eventParame.statusTable, statusTable);
278     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmKeysChangeEventInfo SetValueMap failed.");
279     status = SetValueBoolean(env, eventParame.hasNewGoodLicense, hasNewGoodLicense);
280     DRM_NAPI_CHECK_AND_RETURN_LOG(status == napi_ok, status, "SetDrmKeysChangeEventInfo SetValueBoolean failed.");
281     return napi_ok;
282 }
283 } // namespace DrmStandard
284 } // namespace OHOS