1/*
2 * Copyright (c) 2024 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 <stdio.h>
17#include <stdlib.h>
18
19#include "cJSON.h"
20#include "securec.h"
21
22#include "hnp_base.h"
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28static int ParseLinksJsonToCfgInfo(cJSON *linksItem, HnpCfgInfo *hnpCfg)
29{
30    NativeBinLink *linkArray = NULL;
31
32    int linkArrayNum = cJSON_GetArraySize(linksItem);
33    if (linkArrayNum > 0) {
34        hnpCfg->linkNum = (size_t)linkArrayNum;
35        linkArray = (NativeBinLink*)malloc(sizeof(NativeBinLink) * linkArrayNum);
36        if (linkArray == NULL) {
37            HNP_LOGE("malloc unsuccess.");
38            return HNP_ERRNO_NOMEM;
39        }
40        for (int i = 0; i < linkArrayNum; i++) {
41            cJSON *link = cJSON_GetArrayItem(linksItem, i);
42            if (link == NULL) {
43                free(linkArray);
44                return HNP_ERRNO_BASE_GET_ARRAY_ITRM_FAILED;
45            }
46            cJSON *sourceItem = cJSON_GetObjectItem(link, "source");
47            if ((sourceItem == NULL) || (sourceItem->valuestring == NULL)) {
48                HNP_LOGE("get source info in cfg unsuccess.");
49                free(linkArray);
50                return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
51            }
52            if (strcpy_s(linkArray[i].source, MAX_FILE_PATH_LEN, sourceItem->valuestring) != EOK) {
53                HNP_LOGE("strcpy unsuccess.");
54                free(linkArray);
55                return HNP_ERRNO_BASE_COPY_FAILED;
56            }
57            linkArray[i].target[0] = '\0';  //允许target不填,软链接默认使用原二进制名称
58            cJSON *targetItem = cJSON_GetObjectItem(link, "target");
59            if ((targetItem != NULL) && (targetItem->valuestring != NULL) &&
60                (strcpy_s(linkArray[i].target, MAX_FILE_PATH_LEN, targetItem->valuestring) != EOK)) {
61                HNP_LOGE("strcpy unsuccess.");
62                free(linkArray);
63                return HNP_ERRNO_BASE_COPY_FAILED;
64            }
65        }
66        hnpCfg->links = linkArray;
67    } else {
68        hnpCfg->linkNum = 0;
69    }
70    return 0;
71}
72
73static int ParseJsonStreamToHnpCfgInfo(cJSON *json, HnpCfgInfo *hnpCfg)
74{
75    int ret;
76
77    cJSON *typeItem = cJSON_GetObjectItem(json, "type");
78    if ((typeItem == NULL) || (typeItem->valuestring == NULL)) {
79        HNP_LOGE("get type info in cfg unsuccess.");
80        return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
81    }
82    if (strcmp(typeItem->valuestring, "hnp-config") != 0) {
83        HNP_LOGE("type info not match.type=%{public}s", typeItem->valuestring);
84        return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
85    }
86    cJSON *nameItem = cJSON_GetObjectItem(json, "name");
87    if ((nameItem == NULL) || (nameItem->valuestring == NULL)) {
88        HNP_LOGE("get name info in cfg unsuccess.");
89        return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
90    }
91    ret = strcpy_s(hnpCfg->name, MAX_FILE_PATH_LEN, nameItem->valuestring);
92    if (ret != EOK) {
93        HNP_LOGE("strcpy unsuccess.");
94        return HNP_ERRNO_BASE_COPY_FAILED;
95    }
96    cJSON *versionItem = cJSON_GetObjectItem(json, "version");
97    if ((versionItem == NULL) || (versionItem->valuestring == NULL)) {
98        HNP_LOGE("get version info in cfg unsuccess.");
99        return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
100    }
101    ret = strcpy_s(hnpCfg->version, HNP_VERSION_LEN, versionItem->valuestring);
102    if (ret != EOK) {
103        HNP_LOGE("strcpy unsuccess.");
104        return HNP_ERRNO_BASE_COPY_FAILED;
105    }
106    cJSON *installItem = cJSON_GetObjectItem(json, "install");
107    if (installItem == NULL) {
108        HNP_LOGE("get install info in cfg unsuccess.");
109        return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
110    }
111    cJSON *linksItem = cJSON_GetObjectItem(installItem, "links");
112    if (linksItem != NULL) {
113        ret = ParseLinksJsonToCfgInfo(linksItem, hnpCfg);
114        if (ret != 0) {
115            return ret;
116        }
117    } else {
118        hnpCfg->linkNum = 0;
119    }
120    return 0;
121}
122
123int ParseHnpCfgFile(const char *hnpCfgPath, HnpCfgInfo *hnpCfg)
124{
125    int ret;
126    char *cfgStream = NULL;
127    cJSON *json;
128    int size;
129
130    ret = ReadFileToStream(hnpCfgPath, &cfgStream, &size);
131    if (ret != 0) {
132        HNP_LOGE("read cfg file[%{public}s] unsuccess.", hnpCfgPath);
133        return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
134    }
135    json = cJSON_Parse(cfgStream);
136    free(cfgStream);
137    if (json == NULL) {
138        HNP_LOGE("parse json file[%{public}s] unsuccess.", hnpCfgPath);
139        return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
140    }
141    ret = ParseJsonStreamToHnpCfgInfo(json, hnpCfg);
142    cJSON_Delete(json);
143
144    return ret;
145}
146
147int HnpCfgGetFromSteam(char *cfgStream, HnpCfgInfo *hnpCfg)
148{
149    cJSON *json;
150    int ret;
151
152    if (cfgStream == NULL) {
153        HNP_LOGE("hnp cfg file not found.");
154        return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
155    }
156
157    json = cJSON_Parse(cfgStream);
158    if (json == NULL) {
159        HNP_LOGE("parse json file unsuccess.");
160        return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
161    }
162    ret = ParseJsonStreamToHnpCfgInfo(json, hnpCfg);
163    cJSON_Delete(json);
164
165    return ret;
166}
167int GetHnpJsonBuff(HnpCfgInfo *hnpCfg, char **buff)
168{
169    cJSON *root = cJSON_CreateObject();
170
171    cJSON_AddStringToObject(root, "type", "hnp-config");
172    cJSON_AddStringToObject(root, "name", hnpCfg->name);
173    cJSON_AddStringToObject(root, "version", hnpCfg->version);
174    cJSON_AddObjectToObject(root, "install");
175    char *str = cJSON_Print(root);
176    cJSON_Delete(root);
177
178    *buff = str;
179    return 0;
180}
181
182static bool HnpInstallHapExistCheck(const char *hnpPackageName, cJSON *json, cJSON **hapItemOut, int *hapIndex)
183{
184    cJSON *hapItem = NULL;
185    bool hapExist = false;
186    cJSON *hapJson = NULL;
187
188    for (int i = 0; i < cJSON_GetArraySize(json); i++) {
189        hapItem = cJSON_GetArrayItem(json, i);
190        hapJson = cJSON_GetObjectItem(hapItem, "hap");
191        if ((hapJson != NULL) && (cJSON_IsString(hapJson)) && (strcmp(hapJson->valuestring, hnpPackageName) == 0)) {
192            hapExist = true;
193            *hapItemOut = hapItem;
194            *hapIndex = i;
195            break;
196        }
197    }
198
199    return hapExist;
200}
201
202static bool HnpInstallHnpExistCheck(cJSON *hnpItemArr, const char *name, cJSON **hnpItemOut, int *hnpIndex,
203    const char *version)
204{
205    if (hnpItemArr == NULL) {
206        return false;
207    }
208
209    for (int i = 0; i < cJSON_GetArraySize(hnpItemArr); i++) {
210        cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, i);
211        cJSON *nameJson = cJSON_GetObjectItem(hnpItem, "name");
212        cJSON *versionJson = cJSON_GetObjectItem(hnpItem, "current_version");
213        if ((nameJson != NULL) && (strcmp(nameJson->valuestring, name) == 0)) {
214            *hnpItemOut = hnpItem;
215            *hnpIndex = i;
216            if (version == NULL) {
217                return true;
218            }
219            if ((versionJson != NULL) && (strcmp(versionJson->valuestring, version) == 0)) {
220                return true;
221            }
222        }
223    }
224
225    return false;
226}
227
228static void HnpPackageVersionUpdateAll(cJSON *json, const HnpCfgInfo *hnpCfg)
229{
230    for (int i = 0; i < cJSON_GetArraySize(json); i++) {
231        cJSON *hapItem = cJSON_GetArrayItem(json, i);
232        cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
233        for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
234            cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
235            cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
236            if ((nameItem == NULL) ||
237                ((cJSON_IsString(nameItem)) && (strcmp(nameItem->valuestring, hnpCfg->name) != 0))) {
238                continue;
239            }
240            cJSON *version = cJSON_GetObjectItem(hnpItem, "current_version");
241            if (version == NULL) {
242                break;
243            }
244            cJSON_SetValuestring(version, hnpCfg->version);
245            break;
246        }
247    }
248
249    return;
250}
251
252static int HnpHapJsonWrite(cJSON *json)
253{
254    FILE *fp = fopen(HNP_PACKAGE_INFO_JSON_FILE_PATH, "wb");
255    if (fp == NULL) {
256        HNP_LOGE("open file:%{public}s unsuccess!", HNP_PACKAGE_INFO_JSON_FILE_PATH);
257        return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
258    }
259    char *jsonStr = cJSON_Print(json);
260    size_t jsonStrSize = strlen(jsonStr);
261    size_t writeLen = fwrite(jsonStr, sizeof(char), jsonStrSize, fp);
262    (void)fclose(fp);
263    free(jsonStr);
264    if (writeLen != jsonStrSize) {
265        HNP_LOGE("package info write file:%{public}s unsuccess!", HNP_PACKAGE_INFO_JSON_FILE_PATH);
266        return HNP_ERRNO_BASE_FILE_WRITE_FAILED;
267    }
268
269    return 0;
270}
271
272static int HnpHapJsonHnpAdd(bool hapExist, cJSON *json, cJSON *hapItem, const char *hnpPackageName,
273    const HnpCfgInfo *hnpCfg)
274{
275    cJSON *hnpItemArr = NULL;
276    int ret;
277
278    if (hapExist) {
279        hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
280        if (hnpItemArr == NULL) {
281            HNP_LOGE("hnp item array get unsuccess");
282            return HNP_ERRNO_BASE_PARSE_ITEM_NO_FOUND;
283        }
284    } else {
285        hapItem = cJSON_CreateObject();
286        if (hapItem == NULL) {
287            HNP_LOGE("hnp json write create hap object unsuccess");
288            return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
289        }
290        cJSON_AddStringToObject(hapItem, "hap", hnpPackageName);
291        hnpItemArr = cJSON_CreateArray();
292        if (hnpItemArr == NULL) {
293            HNP_LOGE("hnp json write array create unsuccess");
294            cJSON_Delete(hapItem);
295            return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
296        }
297        cJSON_AddItemToObject(hapItem, "hnp", hnpItemArr);
298        cJSON_AddItemToArray(json, hapItem);
299    }
300
301    cJSON *hnpItem = cJSON_CreateObject();
302    if (hnpItem == NULL) {
303        HNP_LOGE("hnp json write create hnp object unsuccess");
304        return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
305    }
306    cJSON_AddItemToObject(hnpItem, "name", cJSON_CreateString(hnpCfg->name));
307    cJSON_AddItemToObject(hnpItem, "current_version", cJSON_CreateString(hnpCfg->version));
308    if (hnpCfg->isInstall) {
309        cJSON_AddItemToObject(hnpItem, "install_version", cJSON_CreateString(hnpCfg->version));
310    } else {
311        cJSON_AddItemToObject(hnpItem, "install_version", cJSON_CreateString("none"));
312    }
313    cJSON_AddItemToArray(hnpItemArr, hnpItem);
314
315    HnpPackageVersionUpdateAll(json, hnpCfg);
316
317    ret = HnpHapJsonWrite(json);
318    return ret;
319}
320
321int HnpInstallInfoJsonWrite(const char *hapPackageName, const HnpCfgInfo *hnpCfg)
322{
323    bool hapExist = false;
324    int hapIndex = 0;
325    int hnpIndex = 0;
326    char *infoStream;
327    int size;
328    cJSON *hapItem = NULL;
329    cJSON *hnpItem = NULL;
330    cJSON *json = NULL;
331
332    if ((hapPackageName == NULL) || (hnpCfg == NULL)) {
333        return HNP_ERRNO_BASE_PARAMS_INVALID;
334    }
335
336    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
337    if (ret != 0) {
338        if ((ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED) || (ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL)) {
339            if ((json = cJSON_CreateArray()) == NULL) {
340                HNP_LOGE("hnp json write array create unsuccess");
341                return HNP_ERRNO_BASE_JSON_ARRAY_CREATE_FAILED;
342            }
343        } else {
344            HNP_LOGE("hnp json write read hnp info file unsuccess");
345            return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
346        }
347    } else {
348        json = cJSON_Parse(infoStream);
349        free(infoStream);
350        if (json == NULL) {
351            HNP_LOGE("hnp json write parse json file unsuccess.");
352            return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
353        }
354        hapExist = HnpInstallHapExistCheck(hapPackageName, json, &hapItem, &hapIndex);
355    }
356
357    if (hapExist) {
358        cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
359        bool hnpExist = HnpInstallHnpExistCheck(hnpItemArr, hnpCfg->name, &hnpItem, &hnpIndex, NULL);
360        if (hnpExist) {
361            cJSON *versionJson = cJSON_GetObjectItem(hnpItem, "current_version");
362            if (versionJson != NULL) { // 当前版本存在,即非新增版本,仅更新current_version即可,无需更新install_version
363                cJSON_SetValuestring(versionJson, hnpCfg->version);
364                HnpPackageVersionUpdateAll(json, hnpCfg);
365                ret = HnpHapJsonWrite(json);
366                cJSON_Delete(json);
367                return ret;
368            }
369        }
370    }
371
372    ret = HnpHapJsonHnpAdd(hapExist, json, hapItem, hapPackageName, hnpCfg);
373    cJSON_Delete(json);
374    return ret;
375}
376
377static bool HnpOtherPackageInstallCheck(const char *name, const char *version, int packageIndex, cJSON *json)
378{
379    bool hnpExist = false;
380    int hnpIndex = 0;
381
382    for (int i = 0; i < cJSON_GetArraySize(json); i++) {
383        if (i == packageIndex) {
384            continue;
385        }
386        cJSON *hapItem = cJSON_GetArrayItem(json, i);
387        cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
388        cJSON *hnpItem = NULL;
389        hnpExist = HnpInstallHnpExistCheck(hnpItemArr, name, &hnpItem, &hnpIndex, version);
390        if (hnpExist) {
391            return true;
392        }
393    }
394
395    return false;
396}
397
398static int HnpPackageInfoGetOut(HnpPackageInfo *packageInfos, int sum, HnpPackageInfo **packageInfoOut, int *count)
399{
400    HnpPackageInfo *ptr;
401
402    if (sum == 0) {
403        return 0;
404    }
405
406    ptr = malloc(sizeof(HnpPackageInfo) * sum);
407    if (ptr == NULL) {
408        HNP_LOGE("malloc hnp info unsuccess.");
409        return HNP_ERRNO_NOMEM;
410    }
411
412    if (memcpy_s(ptr, sizeof(HnpPackageInfo) * sum, packageInfos, sizeof(HnpPackageInfo) * sum) != 0) {
413        free(ptr);
414        HNP_LOGE("memcpy hnp info unsuccess.");
415        return HNP_ERRNO_BASE_MEMCPY_FAILED;
416    }
417
418    *packageInfoOut = ptr;
419    *count = sum;
420    return 0;
421}
422
423static int HnpPackageJsonGet(cJSON **pJson)
424{
425    char *infoStream;
426    int size;
427
428    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
429    if (ret != 0) {
430        if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
431            return 0;
432        }
433        HNP_LOGE("package info get read hnp info file unsuccess");
434        return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
435    }
436
437    cJSON *json = cJSON_Parse(infoStream);
438    free(infoStream);
439    if (json == NULL) {
440        HNP_LOGE("package info get parse json file unsuccess.");
441        return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
442    }
443
444    *pJson = json;
445
446    return 0;
447}
448
449int HnpPackageInfoGet(const char *packageName, HnpPackageInfo **packageInfoOut, int *count)
450{
451    bool hnpExist = false;
452    int hapIndex = 0;
453    HnpPackageInfo packageInfos[MAX_PACKAGE_HNP_NUM] = {0};
454    int sum = 0;
455    cJSON *json = NULL;
456
457    int ret = HnpPackageJsonGet(&json);
458    if (ret != 0 || json == NULL) {
459        return ret;
460    }
461
462    cJSON *hapItem = NULL;
463    if (HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex) == false) {
464        cJSON_Delete(json);
465        return 0;
466    }
467
468    cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
469    for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
470        cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
471        cJSON *name = cJSON_GetObjectItem(hnpItem, "name");
472        cJSON *version = cJSON_GetObjectItem(hnpItem, "current_version");
473        cJSON *installVersion = cJSON_GetObjectItem(hnpItem, "install_version");
474        if (name == NULL || version == NULL || installVersion == NULL || !cJSON_IsString(name) ||
475            !cJSON_IsString(version) || !cJSON_IsString(installVersion)) {
476            continue;
477        }
478        hnpExist = HnpOtherPackageInstallCheck(name->valuestring, version->valuestring, hapIndex, json);
479        // 当卸载当前版本未被其他hap使用或者存在安装版本的时候,需要卸载对应的当前版本或者安装版本
480        if (!hnpExist || strcmp(installVersion->valuestring, "none") != 0) {
481            if ((strcpy_s(packageInfos[sum].name, MAX_FILE_PATH_LEN, name->valuestring) != EOK) ||
482                (strcpy_s(packageInfos[sum].currentVersion, HNP_VERSION_LEN, version->valuestring) != EOK) ||
483                (strcpy_s(packageInfos[sum].installVersion, HNP_VERSION_LEN, installVersion->valuestring) != EOK)) {
484                HNP_LOGE("strcpy hnp info name[%{public}s],version[%{public}s],install version[%{public}s] unsuccess.",
485                    name->valuestring, version->valuestring, installVersion->valuestring);
486                cJSON_Delete(json);
487                return HNP_ERRNO_BASE_COPY_FAILED;
488            }
489            packageInfos[sum].hnpExist = hnpExist;
490            sum++;
491        }
492    }
493    cJSON_Delete(json);
494
495    return HnpPackageInfoGetOut(packageInfos, sum, packageInfoOut, count);
496}
497
498int HnpPackageInfoHnpDelete(const char *packageName, const char *name, const char *version)
499{
500    char *infoStream;
501    int size;
502    cJSON *hapItem = NULL;
503    cJSON *hnpItem = NULL;
504    int hapIndex = 0;
505    bool hapExist = false;
506    int hnpIndex = 0;
507    bool hnpExist = false;
508
509    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
510    if (ret != 0) {
511        if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
512            return 0;
513        } else {
514            HNP_LOGE("hnp delete read hnp info file unsuccess");
515            return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
516        }
517    }
518
519    cJSON *json = cJSON_Parse(infoStream);
520    free(infoStream);
521    if (json == NULL) {
522        HNP_LOGE("hnp delete parse json file unsuccess.");
523        return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
524    }
525
526    hapExist = HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex);
527    if (!hapExist) {
528        cJSON_Delete(json);
529        return 0;
530    }
531
532    cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
533    hnpExist = HnpInstallHnpExistCheck(hnpItemArr, name, &hnpItem, &hnpIndex, version);
534    if (hnpExist) {
535        cJSON_DeleteItemFromArray(hnpItemArr, hnpIndex);
536    }
537
538    ret = HnpHapJsonWrite(json);
539    cJSON_Delete(json);
540    return ret;
541}
542
543int HnpPackageInfoDelete(const char *packageName)
544{
545    char *infoStream;
546    int size;
547    cJSON *hapItem = NULL;
548    int hapIndex = 0;
549    bool hapExist = false;
550
551    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
552    if (ret != 0) {
553        if (ret == HNP_ERRNO_BASE_FILE_OPEN_FAILED || ret == HNP_ERRNO_BASE_GET_FILE_LEN_NULL) {
554            return 0;
555        }
556        HNP_LOGE("package info delete read hnp info file unsuccess");
557        return HNP_ERRNO_BASE_READ_FILE_STREAM_FAILED;
558    }
559
560    cJSON *json = cJSON_Parse(infoStream);
561    free(infoStream);
562    if (json == NULL) {
563        HNP_LOGE("package info delete parse json file unsuccess.");
564        return HNP_ERRNO_BASE_PARSE_JSON_FAILED;
565    }
566
567    hapExist = HnpInstallHapExistCheck(packageName, json, &hapItem, &hapIndex);
568    if (hapExist) {
569        cJSON_DeleteItemFromArray(json, hapIndex);
570    }
571
572    ret = HnpHapJsonWrite(json);
573    cJSON_Delete(json);
574    return ret;
575}
576
577static char *HnpNeedUnInstallHnpVersionGet(cJSON *hnpItemArr, const char *name)
578{
579    char *version = NULL;
580    if (hnpItemArr == NULL) {
581        return NULL;
582    }
583
584    for (int i = 0; i < cJSON_GetArraySize(hnpItemArr); i++) {
585        cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, i);
586        cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
587        cJSON *currentItem = cJSON_GetObjectItem(hnpItem, "current_version");
588        cJSON *installItem = cJSON_GetObjectItem(hnpItem, "install_version");
589        if ((nameItem != NULL) && (currentItem != NULL) && (installItem != NULL) && (cJSON_IsString(nameItem)) &&
590            (cJSON_IsString(currentItem)) && (cJSON_IsString(installItem)) &&
591            (strcmp(nameItem->valuestring, name) == 0) &&
592            (strcmp(currentItem->valuestring, installItem->valuestring) == 0)) {
593            version = strdup(currentItem->valuestring);
594            return version;
595        }
596    }
597
598    return NULL;
599}
600
601char *HnpCurrentVersionGet(const char *name)
602{
603    char *infoStream;
604    int size;
605    cJSON *hapItem = NULL;
606    char *version = NULL;
607
608    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
609    if (ret != 0) {
610        return NULL;
611    }
612
613    cJSON *json = cJSON_Parse(infoStream);
614    free(infoStream);
615    if (json == NULL) {
616        HNP_LOGE("hnp delete parse json file unsuccess.");
617        return NULL;
618    }
619
620    for (int i = 0; i < cJSON_GetArraySize(json); i++) {
621        hapItem = cJSON_GetArrayItem(json, i);
622        cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
623        if (hnpItemArr == NULL) {
624            cJSON_Delete(json);
625            return NULL;
626        }
627
628        for (int j = 0; j < cJSON_GetArraySize(hnpItemArr); j++) {
629            cJSON *hnpItem = cJSON_GetArrayItem(hnpItemArr, j);
630            cJSON *nameItem = cJSON_GetObjectItem(hnpItem, "name");
631            cJSON *versionItem = cJSON_GetObjectItem(hnpItem, "current_version");
632            if ((nameItem != NULL) && (versionItem != NULL) && (cJSON_IsString(nameItem)) &&
633                (cJSON_IsString(versionItem)) && (strcmp(nameItem->valuestring, name) == 0)) {
634                version = strdup(versionItem->valuestring);
635                cJSON_Delete(json);
636                return version;
637            }
638        }
639    }
640
641    cJSON_Delete(json);
642    return NULL;
643}
644
645char *HnpCurrentVersionUninstallCheck(const char *name)
646{
647    char *infoStream;
648    int size;
649    cJSON *hapItem = NULL;
650    char *version = NULL;
651
652    int ret = ReadFileToStream(HNP_PACKAGE_INFO_JSON_FILE_PATH, &infoStream, &size);
653    if (ret != 0) {
654        return NULL;
655    }
656
657    cJSON *json = cJSON_Parse(infoStream);
658    free(infoStream);
659    if (json == NULL) {
660        HNP_LOGE("hnp delete parse json file unsuccess.");
661        return NULL;
662    }
663
664    for (int i = 0; i < cJSON_GetArraySize(json); i++) {
665        hapItem = cJSON_GetArrayItem(json, i);
666        cJSON *hnpItemArr = cJSON_GetObjectItem(hapItem, "hnp");
667        version = HnpNeedUnInstallHnpVersionGet(hnpItemArr, name);
668        if (version != NULL) {
669            break;
670        }
671    }
672
673    cJSON_Delete(json);
674    return version;
675}
676
677#ifdef __cplusplus
678}
679#endif