• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "client_helper.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #include "napi_util.h"
22 #include "node_api.h"
23 
24 #include "update_define.h"
25 #include "update_helper.h"
26 
27 namespace OHOS {
28 namespace UpdateEngine {
TrimString(std::string & str)29 void ClientHelper::TrimString(std::string &str)
30 {
31     str.erase(0, str.find_first_not_of(" "));
32     str.erase(str.find_last_not_of(" ") + 1);
33 }
34 
IsValidUpgradeFile(const std::string & upgradeFile)35 bool ClientHelper::IsValidUpgradeFile(const std::string &upgradeFile)
36 {
37     if (upgradeFile.empty()) {
38         return false;
39     }
40 
41     std::string::size_type pos = upgradeFile.find_first_of('/');
42     if (pos != 0) {
43         return false;
44     }
45 
46     pos = upgradeFile.find_last_of('.');
47     if (pos == std::string::npos) {
48         return false;
49     }
50 
51     std::string postfix = upgradeFile.substr(pos + 1);
52     std::transform(postfix.begin(), postfix.end(), postfix.begin(), ::tolower);
53     if (postfix.compare("bin") == 0) {
54         return true;
55     } else if (postfix.compare("zip") == 0) {
56         return true;
57     } else if (postfix.compare("lz4") == 0) {
58         return true;
59     } else if (postfix.compare("gz") == 0) {
60         return true;
61     }
62     return false;
63 }
64 
BuildDescInfo(napi_env env,napi_value & obj,const DescriptionInfo & descriptInfo)65 void BuildDescInfo(napi_env env, napi_value &obj, const DescriptionInfo &descriptInfo)
66 {
67     napi_value napiDescriptInfo;
68     napi_create_object(env, &napiDescriptInfo);
69     NapiUtil::SetInt32(env, napiDescriptInfo, "descriptionType", static_cast<int32_t>(descriptInfo.descriptionType));
70     NapiUtil::SetString(env, napiDescriptInfo, "content", descriptInfo.content.c_str());
71     napi_set_named_property(env, obj, "descriptionInfo", napiDescriptInfo);
72 }
73 
IsValidData(const ErrorMessage & errorMessage)74 bool IsValidData(const ErrorMessage &errorMessage)
75 {
76     return errorMessage.errorCode != 0;
77 }
78 
IsValidData(const ComponentDescription & componentDescription)79 bool IsValidData(const ComponentDescription &componentDescription)
80 {
81     return componentDescription.componentId != "";
82 }
83 
IsValidData(const VersionComponent & versionComponent)84 bool IsValidData(const VersionComponent &versionComponent)
85 {
86     return versionComponent.componentType != CAST_INT(ComponentType::INVALID);
87 }
88 
89 template <typename T>
GetValidDataCount(const std::vector<T> & list)90 size_t GetValidDataCount(const std::vector<T> &list)
91 {
92     size_t validDataCount = 0;
93     for (size_t i = 0; i < list.size(); i++) {
94         if (IsValidData(list[i])) {
95             validDataCount++;
96         }
97     }
98     return validDataCount;
99 }
100 
BuildComponentDescriptions(napi_env env,napi_value & obj,const std::vector<ComponentDescription> & componentDescriptions)101 void BuildComponentDescriptions(napi_env env, napi_value &obj, const std::vector<ComponentDescription>
102     &componentDescriptions)
103 {
104     size_t validComponentCount = GetValidDataCount(componentDescriptions);
105     if (validComponentCount == 0) {
106         return;
107     }
108     napi_create_array_with_length(env, validComponentCount, &obj);
109     napi_status status;
110     size_t index = 0;
111     for (size_t i = 0; (i < componentDescriptions.size()) && (index < validComponentCount); i++) {
112         if (IsValidData(componentDescriptions[i])) {
113             napi_value napiComponentDescription;
114             status = napi_create_object(env, &napiComponentDescription);
115             PARAM_CHECK(status == napi_ok, continue, "Failed to napi_create_object %d", static_cast<int32_t>(status));
116             NapiUtil::SetString(env, napiComponentDescription, "componentId",
117                 componentDescriptions[i].componentId.c_str());
118             BuildDescInfo(env, napiComponentDescription, componentDescriptions[i].descriptionInfo);
119             napi_set_element(env, obj, index, napiComponentDescription);
120             index++;
121         }
122     }
123 }
124 
BuildVersionComponents(napi_env env,napi_value & obj,const std::vector<VersionComponent> & versionComponents)125 void BuildVersionComponents(napi_env env, napi_value &obj, const std::vector<VersionComponent> &versionComponents)
126 {
127     size_t validComponentCount = GetValidDataCount(versionComponents);
128     if (validComponentCount == 0) {
129         return;
130     }
131     napi_value napiVersionComponents;
132     napi_create_array_with_length(env, validComponentCount, &napiVersionComponents);
133     napi_status status;
134     size_t index = 0;
135     for (size_t i = 0; (i < versionComponents.size()) && (index < validComponentCount); i++) {
136         if (IsValidData(versionComponents[i])) {
137             napi_value napiVersionComponent;
138             status = napi_create_object(env, &napiVersionComponent);
139             PARAM_CHECK(status == napi_ok, continue, "Failed to napi_create_object %d", static_cast<int32_t>(status));
140             NapiUtil::SetString(env, napiVersionComponent, "componentId", versionComponents[i].componentId.c_str());
141             NapiUtil::SetInt32(env, napiVersionComponent, "componentType", versionComponents[i].componentType);
142             NapiUtil::SetString(env, napiVersionComponent, "upgradeAction", versionComponents[i].upgradeAction.c_str());
143             NapiUtil::SetString(
144                 env, napiVersionComponent, "displayVersion", versionComponents[i].displayVersion.c_str());
145             NapiUtil::SetString(env, napiVersionComponent, "innerVersion", versionComponents[i].innerVersion.c_str());
146             NapiUtil::SetInt32(env, napiVersionComponent, "size", versionComponents[i].size);
147             NapiUtil::SetInt32(env, napiVersionComponent, "effectiveMode", versionComponents[i].effectiveMode);
148             BuildDescInfo(env, napiVersionComponent, versionComponents[i].descriptionInfo);
149             NapiUtil::SetString(
150                 env, napiVersionComponent, "componentExtra", versionComponents[i].componentExtra.c_str());
151             napi_set_element(env, napiVersionComponents, index, napiVersionComponent);
152             index++;
153         }
154     }
155     napi_set_named_property(env, obj, "versionComponents", napiVersionComponents);
156 }
157 
BuildCurrentVersionInfo(napi_env env,napi_value & obj,const UpdateResult & result)158 int32_t ClientHelper::BuildCurrentVersionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
159 {
160     PARAM_CHECK(result.result.currentVersionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
161         "ClientHelper::BuildCurrentVersionInfo null");
162     CLIENT_LOGI("BuildCurrentVersionInfo");
163     PARAM_CHECK(result.type == SessionType::SESSION_GET_CUR_VERSION,
164         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %{public}d", result.type);
165     napi_status status = napi_create_object(env, &obj);
166     PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
167         "Failed to create napi_create_object %d", static_cast<int32_t>(status));
168 
169     CurrentVersionInfo *info = result.result.currentVersionInfo;
170     PARAM_CHECK(info != nullptr, return CAST_INT(ClientStatus::CLIENT_FAIL), "info is null");
171 
172     NapiUtil::SetString(env, obj, "osVersion", info->osVersion);
173     NapiUtil::SetString(env, obj, "deviceName", info->deviceName);
174     BuildVersionComponents(env, obj, info->versionComponents);
175     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
176 }
177 
BuildVersionDigestInfo(napi_env env,napi_value & obj,const VersionDigestInfo & versionDigestInfo)178 void BuildVersionDigestInfo(napi_env env, napi_value &obj, const VersionDigestInfo &versionDigestInfo)
179 {
180     napi_value napiVersionDigestInfo;
181     napi_create_object(env, &napiVersionDigestInfo);
182     NapiUtil::SetString(env, napiVersionDigestInfo, "versionDigest", versionDigestInfo.versionDigest);
183     napi_set_named_property(env, obj, "versionDigestInfo", napiVersionDigestInfo);
184 }
185 
BuildErrorMessages(napi_env env,napi_value & obj,const std::string & name,const std::vector<ErrorMessage> & errorMessages)186 void BuildErrorMessages(
187     napi_env env, napi_value &obj, const std::string &name, const std::vector<ErrorMessage> &errorMessages)
188 {
189     size_t validErrorMsgCount = GetValidDataCount(errorMessages);
190     if (validErrorMsgCount == 0) {
191         return;
192     }
193 
194     napi_value napiErrorMessages;
195     napi_create_array_with_length(env, validErrorMsgCount, &napiErrorMessages);
196     size_t index = 0;
197     for (size_t i = 0; (i < errorMessages.size()) && (index < validErrorMsgCount); i++) {
198         if (IsValidData(errorMessages[i])) {
199             napi_value napiErrorMessage;
200             napi_create_object(env, &napiErrorMessage);
201             NapiUtil::SetInt32(env, napiErrorMessage, "errorCode", errorMessages[i].errorCode);
202             NapiUtil::SetString(env, napiErrorMessage, "errorMessage", errorMessages[i].errorMessage);
203             napi_set_element(env, napiErrorMessages, index, napiErrorMessage);
204             index++;
205         }
206     }
207     napi_set_named_property(env, obj, name.c_str(), napiErrorMessages);
208 }
209 
BuildTaskBody(napi_env env,napi_value & obj,const TaskBody & taskBody)210 void BuildTaskBody(napi_env env, napi_value &obj, const TaskBody &taskBody)
211 {
212     napi_value napiTaskBody;
213     napi_create_object(env, &napiTaskBody);
214     BuildVersionDigestInfo(env, napiTaskBody, taskBody.versionDigestInfo);
215     NapiUtil::SetInt32(env, napiTaskBody, "status", CAST_INT(taskBody.status));
216     NapiUtil::SetInt32(env, napiTaskBody, "subStatus", taskBody.subStatus);
217     NapiUtil::SetInt32(env, napiTaskBody, "progress", taskBody.progress);
218     NapiUtil::SetInt32(env, napiTaskBody, "installMode", taskBody.installMode);
219     BuildErrorMessages(env, napiTaskBody, "errorMessages", taskBody.errorMessages);
220     BuildVersionComponents(env, napiTaskBody, taskBody.versionComponents);
221     napi_set_named_property(env, obj, "taskBody", napiTaskBody);
222 }
223 
BuildTaskInfo(napi_env env,napi_value & obj,const UpdateResult & result)224 int32_t ClientHelper::BuildTaskInfo(napi_env env, napi_value &obj, const UpdateResult &result)
225 {
226     PARAM_CHECK(result.result.taskInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
227         "ClientHelper::BuildTaskInfo null");
228     CLIENT_LOGI("ClientHelper::BuildTaskInfo");
229     napi_status status = napi_create_object(env, &obj);
230     PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
231         "Failed to create napi_create_object %d", static_cast<int32_t>(status));
232     NapiUtil::SetBool(env, obj, "existTask", result.result.taskInfo->existTask);
233     if (result.result.taskInfo->existTask) {
234         BuildTaskBody(env, obj, result.result.taskInfo->taskBody);
235     }
236     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
237 }
238 
BuildNewVersionInfo(napi_env env,napi_value & obj,const UpdateResult & result)239 int32_t ClientHelper::BuildNewVersionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
240 {
241     PARAM_CHECK(result.result.newVersionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
242         "ClientHelper::BuildNewVersionInfo null");
243     PARAM_CHECK(result.type == SessionType::SESSION_GET_NEW_VERSION,
244         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
245         "invalid type %d",
246         result.type);
247     napi_status status = napi_create_object(env, &obj);
248     PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
249         "Failed to create napi_create_object %d", static_cast<int32_t>(status));
250 
251     BuildVersionDigestInfo(env, obj, result.result.newVersionInfo->versionDigestInfo);
252     BuildVersionComponents(env, obj, result.result.newVersionInfo->versionComponents);
253     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
254 }
255 
BuildVersionDescriptionInfo(napi_env env,napi_value & obj,const UpdateResult & result)256 int32_t ClientHelper::BuildVersionDescriptionInfo(napi_env env, napi_value &obj, const UpdateResult &result)
257 {
258     PARAM_CHECK(result.result.versionDescriptionInfo != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
259         "ClientHelper::BuildVersionDescriptionInfo null");
260     CLIENT_LOGI("BuildVersionDescriptionInfo");
261     PARAM_CHECK(result.type == SessionType::SESSION_GET_NEW_VERSION_DESCRIPTION ||
262         result.type == SessionType::SESSION_GET_CUR_VERSION_DESCRIPTION,
263         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %{public}d", result.type);
264 
265     VersionDescriptionInfo *info = result.result.versionDescriptionInfo;
266     PARAM_CHECK(info != nullptr, return CAST_INT(ClientStatus::CLIENT_FAIL), "info is null");
267 
268     BuildComponentDescriptions(env, obj, info->componentDescriptions);
269     PARAM_CHECK(obj != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS), "BuildComponentDescriptions null");
270     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
271 }
272 
BuildCheckResult(napi_env env,napi_value & obj,const UpdateResult & result)273 int32_t ClientHelper::BuildCheckResult(napi_env env, napi_value &obj, const UpdateResult &result)
274 {
275     PARAM_CHECK(result.result.checkResult != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
276         "ClientHelper::BuildCheckResult null");
277     PARAM_CHECK(result.type == SessionType::SESSION_CHECK_VERSION,
278         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %d", result.type);
279     napi_status status = napi_create_object(env, &obj);
280     PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
281         "Failed to create napi_create_object %d", static_cast<int32_t>(status));
282     CheckResult *checkResult = result.result.checkResult;
283     NapiUtil::SetBool(env, obj, "isExistNewVersion", checkResult->isExistNewVersion);
284 
285     if (checkResult->isExistNewVersion) {
286         napi_value newVersionInfo;
287         napi_create_object(env, &newVersionInfo);
288         BuildVersionDigestInfo(env, newVersionInfo, checkResult->newVersionInfo.versionDigestInfo);
289         BuildVersionComponents(env, newVersionInfo, checkResult->newVersionInfo.versionComponents);
290         napi_set_named_property(env, obj, "newVersionInfo", newVersionInfo);
291     }
292     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
293 }
294 
BuildUpgradePolicy(napi_env env,napi_value & obj,const UpdateResult & result)295 int32_t ClientHelper::BuildUpgradePolicy(napi_env env, napi_value &obj, const UpdateResult &result)
296 {
297     PARAM_CHECK(result.result.upgradePolicy != nullptr, return CAST_INT(ClientStatus::CLIENT_SUCCESS),
298         "ClientHelper::BuildUpgradePolicy null");
299     PARAM_CHECK(result.type == SessionType::SESSION_GET_POLICY,
300         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE), "invalid type %d", result.type);
301     napi_status status = napi_create_object(env, &obj);
302     PARAM_CHECK(status == napi_ok, return status, "Failed to create napi_create_object %d", status);
303     UpgradePolicy &upgradePolicy = *result.result.upgradePolicy;
304 
305     // Add the result.
306     NapiUtil::SetBool(env, obj, "downloadStrategy", upgradePolicy.downloadStrategy);
307     NapiUtil::SetBool(env, obj, "autoUpgradeStrategy", upgradePolicy.autoUpgradeStrategy);
308 
309     napi_value autoUpgradePeriods;
310     size_t count = COUNT_OF(upgradePolicy.autoUpgradePeriods);
311     status = napi_create_array_with_length(env, count, &autoUpgradePeriods);
312     PARAM_CHECK(status == napi_ok, return status, "Failed to create array for interval %d", status);
313     for (size_t i = 0; i < count; i++) {
314         napi_value result;
315         status = napi_create_object(env, &result);
316         PARAM_CHECK(status == napi_ok, continue, "Failed to napi_create_object %d", static_cast<int32_t>(status));
317         NapiUtil::SetInt32(env, result, "start", upgradePolicy.autoUpgradePeriods[i].start);
318         NapiUtil::SetInt32(env, result, "end", upgradePolicy.autoUpgradePeriods[i].end);
319         napi_set_element(env, autoUpgradePeriods, i, result);
320     }
321     status = napi_set_named_property(env, obj, "autoUpgradePeriods", autoUpgradePeriods);
322     PARAM_CHECK(status == napi_ok, return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
323             "Failed to napi_set_named_property %d", static_cast<int32_t>(status));
324     return napi_ok;
325 }
326 
BuildUndefinedStatus(napi_env env,napi_value & obj,const UpdateResult & result)327 int32_t ClientHelper::BuildUndefinedStatus(napi_env env, napi_value &obj, const UpdateResult &result)
328 {
329     return napi_get_undefined(env, &obj);
330 }
331 
CheckNapiObjectType(napi_env env,const napi_value arg)332 ClientStatus CheckNapiObjectType(napi_env env, const napi_value arg)
333 {
334     napi_valuetype type = napi_undefined;
335     napi_status status = napi_typeof(env, arg, &type);
336     PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_INVALID_TYPE,
337         "Invalid argc %d", static_cast<int32_t>(status));
338     PARAM_CHECK(type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
339         "Invalid argc %d", static_cast<int32_t>(type))
340     return ClientStatus::CLIENT_SUCCESS;
341 }
342 
ParseBusinessType(napi_env env,const napi_value arg,UpgradeInfo & upgradeInfo)343 void ParseBusinessType(napi_env env, const napi_value arg, UpgradeInfo &upgradeInfo)
344 {
345     bool result = false;
346     napi_status status = napi_has_named_property(env, arg, "businessType", &result);
347     if (result && (status == napi_ok)) {
348         napi_value businessTypeValue;
349         status = napi_get_named_property(env, arg, "businessType", &businessTypeValue);
350         PARAM_CHECK(status == napi_ok, return, "Failed to napi_set_named_property %d", static_cast<int32_t>(status));
351         NapiUtil::GetString(env, businessTypeValue, "vendor", upgradeInfo.businessType.vendor);
352 
353         int32_t subType;
354         NapiUtil::GetInt32(env, businessTypeValue, "subType", subType);
355         upgradeInfo.businessType.subType = static_cast<BusinessSubType>(subType);
356     }
357     if (upgradeInfo.businessType.subType != BusinessSubType::PARAM) {
358         upgradeInfo.businessType.subType = BusinessSubType::FIRMWARE;
359     }
360 }
361 
GetUpgradeInfoFromArg(napi_env env,const napi_value arg,UpgradeInfo & upgradeInfo)362 ClientStatus ClientHelper::GetUpgradeInfoFromArg(napi_env env, const napi_value arg, UpgradeInfo &upgradeInfo)
363 {
364     PARAM_CHECK(CheckNapiObjectType(env, arg) == ClientStatus::CLIENT_SUCCESS,
365         return ClientStatus::CLIENT_INVALID_TYPE, "GetUpgradeInfoFromArg type invalid");
366     NapiUtil::GetString(env, arg, "upgradeApp", upgradeInfo.upgradeApp);
367     ParseBusinessType(env, arg, upgradeInfo);
368     NapiUtil::GetString(env, arg, "upgradeDevId", upgradeInfo.upgradeDevId);
369     NapiUtil::GetString(env, arg, "controlDevId", upgradeInfo.controlDevId);
370     return ClientStatus::CLIENT_SUCCESS;
371 }
372 
GetUpgradePolicyFromArg(napi_env env,const napi_value arg,UpgradePolicy & upgradePolicy)373 ClientStatus ClientHelper::GetUpgradePolicyFromArg(napi_env env, const napi_value arg, UpgradePolicy &upgradePolicy)
374 {
375     PARAM_CHECK(CheckNapiObjectType(env, arg) == ClientStatus::CLIENT_SUCCESS,
376         return ClientStatus::CLIENT_INVALID_TYPE, "GetUpgradePolicyFromArg type invalid");
377 
378     // upgradePolicy
379     NapiUtil::GetBool(env, arg, "downloadStrategy", upgradePolicy.downloadStrategy);
380     NapiUtil::GetBool(env, arg, "autoUpgradeStrategy", upgradePolicy.autoUpgradeStrategy);
381 
382     // Get the array.
383     bool result = false;
384     napi_status status = napi_has_named_property(env, arg, "autoUpgradePeriods", &result);
385     if (result && (status == napi_ok)) {
386         napi_value value;
387         status = napi_get_named_property(env, arg, "autoUpgradePeriods", &value);
388         PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL, "Failed to get attr autoUpgradePeriods");
389         status = napi_is_array(env, value, &result);
390         PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL, "napi_is_array failed");
391         uint32_t count = 0;
392         status = napi_get_array_length(env, value, &count);
393         PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL,
394             "napi_get_array_length failed");
395         uint32_t i = 0;
396         do {
397             if (i >= COUNT_OF(upgradePolicy.autoUpgradePeriods)) {
398                 break;
399             }
400             napi_value element;
401             napi_get_element(env, value, i, &element);
402             napi_get_value_uint32(env, element, &upgradePolicy.autoUpgradePeriods[i].start);
403             napi_get_value_uint32(env, element, &upgradePolicy.autoUpgradePeriods[i].end);
404             CLIENT_LOGI("upgradePolicy autoUpgradeInterval");
405             i++;
406         } while (i < count);
407     }
408     CLIENT_LOGI("upgradePolicy autoDownload:%d autoDownloadNet:%d",
409         static_cast<int32_t>(upgradePolicy.downloadStrategy),
410         static_cast<int32_t>(upgradePolicy.autoUpgradeStrategy));
411     return ClientStatus::CLIENT_SUCCESS;
412 }
413 
GetDescriptionFormat(napi_env env,const napi_value arg,DescriptionFormat & format)414 ClientStatus ClientHelper::GetDescriptionFormat(napi_env env, const napi_value arg, DescriptionFormat &format)
415 {
416     int tmpFormat = 0;
417     NapiUtil::GetInt32(env, arg, "format", tmpFormat);
418     static const std::list formatList = {DescriptionFormat::STANDARD, DescriptionFormat::SIMPLIFIED};
419     PARAM_CHECK(IsValidEnum(formatList, tmpFormat), return ClientStatus::CLIENT_INVALID_TYPE,
420         "GetDescriptionFormat error, invalid format:%{public}d", tmpFormat);
421     format = static_cast<DescriptionFormat>(tmpFormat);
422     return ClientStatus::CLIENT_SUCCESS;
423 }
424 
GetNetType(napi_env env,const napi_value arg,NetType & netType)425 ClientStatus ClientHelper::GetNetType(napi_env env, const napi_value arg, NetType &netType)
426 {
427     int allowNetwork = 0;
428     NapiUtil::GetInt32(env, arg, "allowNetwork", allowNetwork);
429     static const std::list netTypeList = {NetType::CELLULAR, NetType::METERED_WIFI, NetType::NOT_METERED_WIFI,
430         NetType::WIFI, NetType::CELLULAR_AND_WIFI};
431     PARAM_CHECK(IsValidEnum(netTypeList, allowNetwork), return ClientStatus::CLIENT_INVALID_TYPE,
432         "GetNetType error, invalid NetType:%{public}d", allowNetwork);
433     netType = static_cast<NetType>(allowNetwork);
434     return ClientStatus::CLIENT_SUCCESS;
435 }
436 
GetOrder(napi_env env,const napi_value arg,Order & order)437 ClientStatus ClientHelper::GetOrder(napi_env env, const napi_value arg, Order &order)
438 {
439     int tmpOrder = 0;
440     NapiUtil::GetInt32(env, arg, "order", tmpOrder);
441     static const std::list orderList = {Order::DOWNLOAD, Order::INSTALL, Order::APPLY, Order::DOWNLOAD_AND_INSTALL,
442         Order::INSTALL_AND_APPLY};
443     PARAM_CHECK(IsValidEnum(orderList, tmpOrder), return ClientStatus::CLIENT_INVALID_TYPE,
444         "GetOrder error, invalid order:%{public}d", tmpOrder);
445     order = static_cast<Order>(tmpOrder);
446     return ClientStatus::CLIENT_SUCCESS;
447 }
448 
GetOptionsFromArg(napi_env env,const napi_value arg,DescriptionOptions & descriptionOptions)449 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, DescriptionOptions &descriptionOptions)
450 {
451     ClientStatus ret = GetDescriptionFormat(env, arg, descriptionOptions.format);
452     PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
453         "GetDescriptionOptionsFromArg GetDescriptionFormat error");
454     NapiUtil::GetString(env, arg, "language", descriptionOptions.language);
455     return ClientStatus::CLIENT_SUCCESS;
456 }
457 
GetOptionsFromArg(napi_env env,const napi_value arg,DownloadOptions & downloadOptions)458 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, DownloadOptions &downloadOptions)
459 {
460     ClientStatus ret = GetNetType(env, arg, downloadOptions.allowNetwork);
461     PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
462         "GetDownloadOptionsFromArg GetNetType error");
463 
464     ret = GetOrder(env, arg, downloadOptions.order);
465     PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_INVALID_TYPE,
466         "GetDownloadOptionsFromArg GetOrder error");
467     return ClientStatus::CLIENT_SUCCESS;
468 }
469 
GetOptionsFromArg(napi_env env,const napi_value arg,PauseDownloadOptions & pauseDownloadOptions)470 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg,
471     PauseDownloadOptions &pauseDownloadOptions)
472 {
473     NapiUtil::GetBool(env, arg, "isAllowAutoResume", pauseDownloadOptions.isAllowAutoResume);
474     return ClientStatus::CLIENT_SUCCESS;
475 }
476 
GetOptionsFromArg(napi_env env,const napi_value arg,ResumeDownloadOptions & resumeDownloadOptions)477 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg,
478     ResumeDownloadOptions &resumeDownloadOptions)
479 {
480     return GetNetType(env, arg, resumeDownloadOptions.allowNetwork);
481 }
482 
GetVersionDigestInfoFromArg(napi_env env,const napi_value arg,VersionDigestInfo & versionDigestInfo)483 ClientStatus ClientHelper::GetVersionDigestInfoFromArg(napi_env env, const napi_value arg,
484     VersionDigestInfo &versionDigestInfo)
485 {
486     NapiUtil::GetString(env, arg, "versionDigest", versionDigestInfo.versionDigest);
487     CLIENT_LOGI("GetVersionDigestInfoFromArg versionDigest:%{public}s", versionDigestInfo.versionDigest.c_str());
488     return ClientStatus::CLIENT_SUCCESS;
489 }
490 
GetOptionsFromArg(napi_env env,const napi_value arg,UpgradeOptions & upgradeOptions)491 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, UpgradeOptions &upgradeOptions)
492 {
493     return GetOrder(env, arg, upgradeOptions.order);
494 }
495 
GetOptionsFromArg(napi_env env,const napi_value arg,ClearOptions & clearOptions)496 ClientStatus ClientHelper::GetOptionsFromArg(napi_env env, const napi_value arg, ClearOptions &clearOptions)
497 {
498     int32_t status = 0;
499     NapiUtil::GetInt32(env, arg, "status", status);
500     static const std::list statusList = {
501         UpgradeStatus::INIT,                  UpgradeStatus::CHECKING_VERSION,
502         UpgradeStatus::CHECK_VERSION_FAIL,    UpgradeStatus::CHECK_VERSION_SUCCESS,
503         UpgradeStatus::DOWNLOADING,           UpgradeStatus::DOWNLOAD_PAUSE,
504         UpgradeStatus::DOWNLOAD_CANCEL,       UpgradeStatus::DOWNLOAD_FAIL,
505         UpgradeStatus::DOWNLOAD_SUCCESS,      UpgradeStatus::VERIFYING,
506         UpgradeStatus::VERIFY_FAIL,           UpgradeStatus::VERIFY_SUCCESS,
507         UpgradeStatus::PACKAGE_TRANSING,      UpgradeStatus::PACKAGE_TRANS_FAIL,
508         UpgradeStatus::PACKAGE_TRANS_SUCCESS, UpgradeStatus::INSTALLING,
509         UpgradeStatus::INSTALL_FAIL,          UpgradeStatus::INSTALL_SUCCESS,
510         UpgradeStatus::UPDATING,              UpgradeStatus::UPDATE_FAIL,
511         UpgradeStatus::UPDATE_SUCCESS };
512     PARAM_CHECK(IsValidEnum(statusList, status), return ClientStatus::CLIENT_INVALID_TYPE,
513         "GetClearOptionsFromArg error, invalid status:%{public}d", status);
514     clearOptions.status = static_cast<UpgradeStatus>(status);
515     CLIENT_LOGI("GetClearOptionsFromArg status:%{public}d", clearOptions.status);
516     return ClientStatus::CLIENT_SUCCESS;
517 }
518 
ParseUpgradeFile(napi_env env,const napi_value arg,UpgradeFile & upgradeFile)519 ClientStatus ParseUpgradeFile(napi_env env, const napi_value arg, UpgradeFile &upgradeFile)
520 {
521     napi_valuetype type = napi_undefined;
522     napi_status status = napi_typeof(env, arg, &type);
523     PARAM_CHECK(status == napi_ok && type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
524         "ParseUpgradeFile error, error type");
525 
526     int32_t fileType = 0;
527     NapiUtil::GetInt32(env, arg, "fileType", fileType);
528     static const std::list enumList = { ComponentType::OTA };
529     PARAM_CHECK(IsValidEnum(enumList, fileType), return ClientStatus::CLIENT_INVALID_PARAM,
530         "ParseUpgradeFile error, invalid fileType:%{public}d", fileType);
531     upgradeFile.fileType = static_cast<ComponentType>(fileType);
532 
533     NapiUtil::GetString(env, arg, "filePath", upgradeFile.filePath);
534     ClientHelper::TrimString(upgradeFile.filePath);
535     if (!ClientHelper::IsValidUpgradeFile(upgradeFile.filePath)) {
536         CLIENT_LOGE("ParseUpgradeFile, invalid filePath:%s", upgradeFile.filePath.c_str());
537         return ClientStatus::CLIENT_INVALID_PARAM;
538     }
539     CLIENT_LOGI("ParseUpgradeFile fileType:%{public}d, filePath:%s", fileType, upgradeFile.filePath.c_str());
540     return ClientStatus::CLIENT_SUCCESS;
541 }
542 
GetUpgradeFileFromArg(napi_env env,const napi_value arg,UpgradeFile & upgradeFile)543 ClientStatus ClientHelper::GetUpgradeFileFromArg(napi_env env, const napi_value arg, UpgradeFile &upgradeFile)
544 {
545     return ParseUpgradeFile(env, arg, upgradeFile);
546 }
547 
GetUpgradeFilesFromArg(napi_env env,const napi_value arg,std::vector<UpgradeFile> & upgradeFiles)548 ClientStatus ClientHelper::GetUpgradeFilesFromArg(napi_env env, const napi_value arg,
549     std::vector<UpgradeFile> &upgradeFiles)
550 {
551     bool result = false;
552     napi_status status = napi_is_array(env, arg, &result);
553     PARAM_CHECK(status == napi_ok && result, return ClientStatus::CLIENT_FAIL,
554         "GetUpgradeFilesFromArg error, napi_is_array failed");
555 
556     uint32_t count = 0;
557     status = napi_get_array_length(env, arg, &count);
558     PARAM_CHECK((status == napi_ok) && (count > 0), return ClientStatus::CLIENT_FAIL,
559         "GetUpgradeFilesFromArg error, napi_get_array_length failed");
560     for (uint32_t idx = 0; idx < count; idx++) {
561         napi_value element;
562         napi_get_element(env, arg, idx, &element);
563         UpgradeFile upgradeFile;
564         ClientStatus ret = ParseUpgradeFile(env, element, upgradeFile);
565         if (ret != ClientStatus::CLIENT_SUCCESS) {
566             return ret;
567         }
568         upgradeFiles.emplace_back(upgradeFile);
569     }
570     CLIENT_LOGI("GetUpgradeFilesFromArg success, size:%{public}zu", upgradeFiles.size());
571     return ClientStatus::CLIENT_SUCCESS;
572 }
573 
GetEventClassifyInfoFromArg(napi_env env,const napi_value arg,EventClassifyInfo & eventClassifyInfo)574 ClientStatus ClientHelper::GetEventClassifyInfoFromArg(napi_env env, const napi_value arg,
575     EventClassifyInfo &eventClassifyInfo)
576 {
577     napi_valuetype type = napi_undefined;
578     napi_status status = napi_typeof(env, arg, &type);
579     PARAM_CHECK(status == napi_ok && type == napi_object, return ClientStatus::CLIENT_INVALID_TYPE,
580         "GetEventClassifyInfoFromArg error, error type");
581 
582     int32_t eventClassify = 0;
583     NapiUtil::GetInt32(env, arg, "eventClassify", eventClassify);
584     static const std::list enumList = { EventClassify::TASK };
585     PARAM_CHECK(IsValidEnum(enumList, eventClassify), return ClientStatus::CLIENT_INVALID_TYPE,
586         "GetEventClassifyInfoFromArg error, invalid eventClassify:0x%{public}x", eventClassify);
587     eventClassifyInfo.eventClassify = static_cast<EventClassify>(eventClassify);
588 
589     NapiUtil::GetString(env, arg, "extraInfo", eventClassifyInfo.extraInfo);
590     CLIENT_LOGI("GetEventClassifyInfoFromArg eventClassify:0x%{public}x, extraInfo:%s",
591         eventClassify, eventClassifyInfo.extraInfo.c_str());
592     return ClientStatus::CLIENT_SUCCESS;
593 }
594 
IsCommonError(CallResult callResult)595 bool ClientHelper::IsCommonError(CallResult callResult)
596 {
597     return callResult == CallResult::UN_SUPPORT || callResult == CallResult::NOT_SYSTEM_APP ||
598         callResult == CallResult::APP_NOT_GRANTED || callResult == CallResult::PARAM_ERR;
599 }
600 
ConvertToErrorCode(CallResult callResult)601 int32_t ClientHelper::ConvertToErrorCode(CallResult callResult)
602 {
603     if (IsCommonError(callResult) || callResult == CallResult::SUCCESS) {
604         return CAST_INT(callResult);
605     } else {
606         return COMPONENT_ERR + CAST_INT(callResult);
607     }
608 }
609 
BuildBusinessError(napi_env env,napi_value & obj,const BusinessError & businessError)610 int32_t ClientHelper::BuildBusinessError(napi_env env, napi_value &obj, const BusinessError &businessError)
611 {
612     if (!IsErrorExist(businessError)) {
613         // success, no need to set businessError
614         return CAST_INT(ClientStatus::CLIENT_SUCCESS);
615     }
616     napi_status status = napi_create_object(env, &obj);
617     PARAM_CHECK(status == napi_ok,
618         return CAST_INT(ClientStatus::CLIENT_INVALID_TYPE),
619         "Failed to create napi_create_object %d",
620         static_cast<int32_t>(status));
621 
622     // 转码处理
623     NapiUtil::SetString(env, obj, "message", businessError.message);
624     NapiUtil::SetInt32(env, obj, "code", ConvertToErrorCode(businessError.errorNum));
625     BuildErrorMessages(env, obj, "data", businessError.data);
626     return CAST_INT(ClientStatus::CLIENT_SUCCESS);
627 }
628 
BuildThrowError(napi_env env,const BusinessError & businessError)629 napi_value ClientHelper::BuildThrowError(napi_env env, const BusinessError &businessError)
630 {
631     napi_value message = nullptr;
632     napi_create_string_utf8(env, businessError.message.c_str(), NAPI_AUTO_LENGTH, &message);
633     napi_value error = nullptr;
634     napi_status status = napi_create_error(env, nullptr, message, &error);
635     PARAM_CHECK(status == napi_ok, return nullptr, "Failed to create napi_create_object %d",
636         static_cast<int32_t>(status));
637 
638     // 转码处理
639     NapiUtil::SetInt32(env, error, "code", ConvertToErrorCode(businessError.errorNum));
640     NapiUtil::SetString(env, error, "message", businessError.message);
641     BuildErrorMessages(env, error, "data", businessError.data);
642     return error;
643 }
644 
ConvertVectorToStr(std::vector<std::pair<std::string,std::string>> & strVector,bool isFirst)645 std::string ClientHelper::ConvertVectorToStr(std::vector<std::pair<std::string, std::string>> &strVector,
646     bool isFirst)
647 {
648     std::string strValue;
649     for (auto &str : strVector) {
650         if (!strValue.empty()) {
651             strValue.append(", ");
652         }
653         if (isFirst) {
654             strValue.append(str.first);
655         } else {
656             strValue.append(str.second);
657         }
658     }
659     return strValue;
660 }
661 
GetParamNames(std::vector<std::pair<std::string,std::string>> & strVector)662 std::string ClientHelper::GetParamNames(std::vector<std::pair<std::string, std::string>> &strVector)
663 {
664     return ConvertVectorToStr(strVector, true);
665 }
666 
GetParamTypes(std::vector<std::pair<std::string,std::string>> & strVector)667 std::string ClientHelper::GetParamTypes(std::vector<std::pair<std::string, std::string>> &strVector)
668 {
669     return ConvertVectorToStr(strVector, false);
670 }
671 
NapiThrowParamError(napi_env env,std::vector<std::pair<std::string,std::string>> & paramInfos)672 void ClientHelper::NapiThrowParamError(
673     napi_env env, std::vector<std::pair<std::string, std::string>> &paramInfos)
674 {
675     BusinessError businessError;
676     CallResult errCode = CallResult::PARAM_ERR;
677     std::string errMsg = "BusinessError " + std::to_string(CAST_INT(errCode))
678         .append(": Parameter error. The type of { ").append(GetParamNames(paramInfos)).append(" }")
679         .append("must be { ").append(GetParamTypes(paramInfos)).append(" }.");
680     businessError.Build(errCode, errMsg);
681     napi_value msg = BuildThrowError(env, businessError);
682     napi_status status = napi_throw(env, msg);
683     PARAM_CHECK(status == napi_ok, return, "Failed to napi_throw %d", static_cast<int32_t>(status));
684 }
685 
BuildTaskBody(napi_env env,napi_value & obj,EventId eventId,const TaskBody & taskBody)686 ClientStatus BuildTaskBody(napi_env env, napi_value &obj, EventId eventId, const TaskBody &taskBody)
687 {
688     auto iter = g_taskBodyTemplateMap.find(eventId);
689     PARAM_CHECK(iter != g_taskBodyTemplateMap.end(), return ClientStatus::CLIENT_INVALID_PARAM,
690         "BuildTaskBody error, eventId %{public}d", CAST_INT(eventId));
691     uint32_t taskBodyTemplate = iter->second;
692     napi_value napiTaskBody = nullptr;
693     napi_create_object(env, &napiTaskBody);
694     if (taskBodyTemplate & VERSION_DIGEST_INFO) {
695         BuildVersionDigestInfo(env, napiTaskBody, taskBody.versionDigestInfo);
696     }
697     if (taskBodyTemplate & UPGRADE_STATUS) {
698         NapiUtil::SetInt32(env, napiTaskBody, "status",  CAST_INT(taskBody.status));
699     }
700     if (taskBodyTemplate & SUB_STATUS) {
701         NapiUtil::SetInt32(env, napiTaskBody, "subStatus", taskBody.subStatus);
702     }
703     if (taskBodyTemplate & PROGRESS) {
704         NapiUtil::SetInt32(env, napiTaskBody, "progress", taskBody.progress);
705     }
706     if (taskBodyTemplate & INSTALL_MODE) {
707         NapiUtil::SetInt32(env, napiTaskBody, "installMode", taskBody.installMode);
708     }
709     if (taskBodyTemplate & ERROR_MESSAGE) {
710         BuildErrorMessages(env, napiTaskBody, "errorMessages", taskBody.errorMessages);
711     }
712     if (taskBodyTemplate & VERSION_COMPONENT) {
713         BuildVersionComponents(env, napiTaskBody, taskBody.versionComponents);
714     }
715     napi_set_named_property(env, obj, "taskBody", napiTaskBody);
716     return ClientStatus::CLIENT_SUCCESS;
717 }
718 
BuildEventInfo(napi_env env,napi_value & obj,const EventInfo & eventInfo)719 ClientStatus ClientHelper::BuildEventInfo(napi_env env, napi_value &obj, const EventInfo &eventInfo)
720 {
721     napi_status status = napi_create_object(env, &obj);
722     PARAM_CHECK(status == napi_ok, return ClientStatus::CLIENT_FAIL,
723         "BuildEventInfo error, failed to create napi_create_object %{public}d", CAST_INT(status));
724 
725     NapiUtil::SetInt32(env, obj, "eventId", CAST_INT(eventInfo.eventId));
726     ClientStatus ret = BuildTaskBody(env, obj, eventInfo.eventId, eventInfo.taskBody);
727     PARAM_CHECK(ret == ClientStatus::CLIENT_SUCCESS, return ClientStatus::CLIENT_FAIL,
728         "BuildEventInfo error, build task info fail");
729     return ClientStatus::CLIENT_SUCCESS;
730 }
731 
IsErrorExist(const BusinessError & businessError)732 bool ClientHelper::IsErrorExist(const BusinessError &businessError)
733 {
734     return businessError.errorNum != CallResult::SUCCESS;
735 }
736 } // namespace UpdateEngine
737 } // namespace OHOS
738