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