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