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