1 /*
2  * Copyright (c) 2021-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 #include "shortcut_info.h"
16 
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <string.h>
20 #include <unistd.h>
21 
22 #include "bundle_constants.h"
23 #include "json_util.h"
24 #include "nlohmann/json.hpp"
25 #include "parcel_macro.h"
26 #include "string_ex.h"
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 namespace {
31 const char* JSON_KEY_BUNDLE_ID = "id";
32 const char* JSON_KEY_BUNDLE_HOST_ABILITY = "hostAbility";
33 const char* JSON_KEY_BUNDLE_ICON = "icon";
34 const char* JSON_KEY_BUNDLE_LABEL = "label";
35 const char* JSON_KEY_BUNDLE_DISABLE_MESSAGE = "disableMessage";
36 const char* JSON_KEY_BUNDLE_IS_STATIC = "isStatic";
37 const char* JSON_KEY_BUNDLE_IS_HOME_SHORTCUT = "isHomeShortcut";
38 const char* JSON_KEY_BUNDLE_IS_ENABLES = "isEnables";
39 const char* JSON_KEY_BUNDLE_INTENTS = "intents";
40 const char* JSON_KEY_BUNDLE_TARGET_BUNDLE = "targetBundle";
41 const char* JSON_KEY_BUNDLE_TARGET_MODULE = "targetModule";
42 const char* JSON_KEY_BUNDLE_TARGET_CLASS = "targetClass";
43 const char* JSON_KEY_BUNDLE_PARAMETERS = "parameters";
44 const char* JSON_KEY_ICON_ID = "iconId";
45 const char* JSON_KEY_LABEL_ID = "labelId";
46 const char* JSON_KEY_APP_INDEX = "appIndex";
47 const char* JSON_KEY_SOURCE_TYPE = "sourceType";
48 const char* SHORTCUTS = "shortcuts";
49 const char* SHORTCUT_ID = "shortcutId";
50 const char* SHORTCUT_WANTS = "wants";
51 const char* ICON = "icon";
52 const char* ICON_ID = "iconId";
53 const char* LABEL = "label";
54 const char* LABEL_ID = "labelId";
55 }  // namespace
56 
ReadFromParcel(Parcel & parcel)57 bool ShortcutInfo::ReadFromParcel(Parcel &parcel)
58 {
59     id = Str16ToStr8(parcel.ReadString16());
60     bundleName = Str16ToStr8(parcel.ReadString16());
61     moduleName = Str16ToStr8(parcel.ReadString16());
62     hostAbility = Str16ToStr8(parcel.ReadString16());
63     icon = Str16ToStr8(parcel.ReadString16());
64     label = Str16ToStr8(parcel.ReadString16());
65     iconId = parcel.ReadUint32();
66     labelId = parcel.ReadUint32();
67     disableMessage = Str16ToStr8(parcel.ReadString16());
68     isStatic = parcel.ReadBool();
69     isHomeShortcut = parcel.ReadBool();
70     isEnables = parcel.ReadBool();
71     int32_t intentsSize;
72     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, intentsSize);
73     CONTAINER_SECURITY_VERIFY(parcel, intentsSize, &intents);
74     for (auto i = 0; i < intentsSize; i++) {
75         ShortcutIntent shortcutIntent;
76         shortcutIntent.targetBundle = Str16ToStr8(parcel.ReadString16()); // target bundle name
77         shortcutIntent.targetModule = Str16ToStr8(parcel.ReadString16()); // target module name
78         shortcutIntent.targetClass = Str16ToStr8(parcel.ReadString16()); // target class name
79         int32_t parametersSize;
80         READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, parametersSize);
81         CONTAINER_SECURITY_VERIFY(parcel, parametersSize, &shortcutIntent.parameters);
82         for (int32_t i = 0; i < parametersSize; ++i) {
83             std::string key = Str16ToStr8(parcel.ReadString16());
84             std::string value = Str16ToStr8(parcel.ReadString16());
85             shortcutIntent.parameters.emplace(key, value);
86         }
87         intents.emplace_back(shortcutIntent);
88     }
89     appIndex = parcel.ReadInt32();
90     sourceType = parcel.ReadInt32();
91     return true;
92 }
93 
Unmarshalling(Parcel & parcel)94 ShortcutInfo *ShortcutInfo::Unmarshalling(Parcel &parcel)
95 {
96     ShortcutInfo *info = new (std::nothrow) ShortcutInfo();
97     if (info && !info->ReadFromParcel(parcel)) {
98         APP_LOGW("read from parcel failed");
99         delete info;
100         info = nullptr;
101     }
102     return info;
103 }
104 
Marshalling(Parcel & parcel) const105 bool ShortcutInfo::Marshalling(Parcel &parcel) const
106 {
107     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(id));
108     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName));
109     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(moduleName));
110     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(hostAbility));
111     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(icon));
112     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(label));
113     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, iconId);
114     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, labelId);
115     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(disableMessage));
116     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isStatic);
117     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isHomeShortcut);
118     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isEnables);
119 
120     const auto intentsSize = static_cast<int32_t>(intents.size());
121     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, intentsSize);
122     for (auto i = 0; i < intentsSize; i++) {
123         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(intents[i].targetBundle));
124         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(intents[i].targetModule));
125         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(intents[i].targetClass));
126         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(intents[i].parameters.size()));
127         for (const auto &dataItem : intents[i].parameters) {
128             WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(dataItem.first));
129             WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(dataItem.second));
130         }
131     }
132     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, appIndex);
133     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, sourceType);
134     return true;
135 }
136 
to_json(nlohmann::json & jsonObject,const ShortcutIntent & shortcutIntent)137 void to_json(nlohmann::json &jsonObject, const ShortcutIntent &shortcutIntent)
138 {
139     jsonObject = nlohmann::json {
140         {JSON_KEY_BUNDLE_TARGET_BUNDLE, shortcutIntent.targetBundle},
141         {JSON_KEY_BUNDLE_TARGET_MODULE, shortcutIntent.targetModule},
142         {JSON_KEY_BUNDLE_TARGET_CLASS, shortcutIntent.targetClass},
143         {JSON_KEY_BUNDLE_PARAMETERS, shortcutIntent.parameters},
144     };
145 }
146 
to_json(nlohmann::json & jsonObject,const ShortcutInfo & shortcutInfo)147 void to_json(nlohmann::json &jsonObject, const ShortcutInfo &shortcutInfo)
148 {
149     jsonObject = nlohmann::json {
150         {JSON_KEY_BUNDLE_ID, shortcutInfo.id},
151         {Constants::BUNDLE_NAME, shortcutInfo.bundleName},
152         {Constants::MODULE_NAME, shortcutInfo.moduleName},
153         {JSON_KEY_BUNDLE_HOST_ABILITY, shortcutInfo.hostAbility},
154         {JSON_KEY_BUNDLE_ICON, shortcutInfo.icon},
155         {JSON_KEY_BUNDLE_LABEL, shortcutInfo.label},
156         {JSON_KEY_BUNDLE_DISABLE_MESSAGE, shortcutInfo.disableMessage},
157         {JSON_KEY_BUNDLE_IS_STATIC, shortcutInfo.isStatic},
158         {JSON_KEY_BUNDLE_IS_HOME_SHORTCUT, shortcutInfo.isHomeShortcut},
159         {JSON_KEY_BUNDLE_IS_ENABLES, shortcutInfo.isEnables},
160         {JSON_KEY_BUNDLE_INTENTS, shortcutInfo.intents},
161         {JSON_KEY_ICON_ID, shortcutInfo.iconId},
162         {JSON_KEY_LABEL_ID, shortcutInfo.labelId},
163         {JSON_KEY_APP_INDEX, shortcutInfo.appIndex},
164         {JSON_KEY_SOURCE_TYPE, shortcutInfo.sourceType},
165   };
166 }
167 
from_json(const nlohmann::json & jsonObject,ShortcutIntent & shortcutIntent)168 void from_json(const nlohmann::json &jsonObject, ShortcutIntent &shortcutIntent)
169 {
170     const auto &jsonObjectEnd = jsonObject.end();
171     int32_t parseResult = ERR_OK;
172     GetValueIfFindKey<std::string>(jsonObject,
173         jsonObjectEnd,
174         JSON_KEY_BUNDLE_TARGET_BUNDLE,
175         shortcutIntent.targetBundle,
176         JsonType::STRING,
177         false,
178         parseResult,
179         ArrayType::NOT_ARRAY);
180     GetValueIfFindKey<std::string>(jsonObject,
181         jsonObjectEnd,
182         JSON_KEY_BUNDLE_TARGET_MODULE,
183         shortcutIntent.targetModule,
184         JsonType::STRING,
185         false,
186         parseResult,
187         ArrayType::NOT_ARRAY);
188     GetValueIfFindKey<std::string>(jsonObject,
189         jsonObjectEnd,
190         JSON_KEY_BUNDLE_TARGET_CLASS,
191         shortcutIntent.targetClass,
192         JsonType::STRING,
193         false,
194         parseResult,
195         ArrayType::NOT_ARRAY);
196     GetValueIfFindKey<std::map<std::string, std::string>>(jsonObject,
197         jsonObjectEnd,
198         JSON_KEY_BUNDLE_PARAMETERS,
199         shortcutIntent.parameters,
200         JsonType::OBJECT,
201         false,
202         parseResult,
203         ArrayType::NOT_ARRAY);
204     if (parseResult != ERR_OK) {
205         APP_LOGE("read shortcutIntent jsonObject error : %{public}d", parseResult);
206     }
207 }
208 
from_json(const nlohmann::json & jsonObject,ShortcutInfo & shortcutInfo)209 void from_json(const nlohmann::json &jsonObject, ShortcutInfo &shortcutInfo)
210 {
211     const auto &jsonObjectEnd = jsonObject.end();
212     int32_t parseResult = ERR_OK;
213     GetValueIfFindKey<std::string>(jsonObject,
214         jsonObjectEnd,
215         JSON_KEY_BUNDLE_ID,
216         shortcutInfo.id,
217         JsonType::STRING,
218         false,
219         parseResult,
220         ArrayType::NOT_ARRAY);
221     GetValueIfFindKey<std::string>(jsonObject,
222         jsonObjectEnd,
223         Constants::BUNDLE_NAME,
224         shortcutInfo.bundleName,
225         JsonType::STRING,
226         false,
227         parseResult,
228         ArrayType::NOT_ARRAY);
229     GetValueIfFindKey<std::string>(jsonObject,
230         jsonObjectEnd,
231         Constants::MODULE_NAME,
232         shortcutInfo.moduleName,
233         JsonType::STRING,
234         false,
235         parseResult,
236         ArrayType::NOT_ARRAY);
237     GetValueIfFindKey<std::string>(jsonObject,
238         jsonObjectEnd,
239         JSON_KEY_BUNDLE_HOST_ABILITY,
240         shortcutInfo.hostAbility,
241         JsonType::STRING,
242         false,
243         parseResult,
244         ArrayType::NOT_ARRAY);
245     GetBigStringIfFindKey<std::string>(jsonObject,
246         jsonObjectEnd,
247         JSON_KEY_BUNDLE_ICON,
248         shortcutInfo.icon,
249         JsonType::STRING,
250         false,
251         parseResult,
252         ArrayType::NOT_ARRAY);
253     GetValueIfFindKey<std::string>(jsonObject,
254         jsonObjectEnd,
255         JSON_KEY_BUNDLE_LABEL,
256         shortcutInfo.label,
257         JsonType::STRING,
258         false,
259         parseResult,
260         ArrayType::NOT_ARRAY);
261     GetValueIfFindKey<std::string>(jsonObject,
262         jsonObjectEnd,
263         JSON_KEY_BUNDLE_DISABLE_MESSAGE,
264         shortcutInfo.disableMessage,
265         JsonType::STRING,
266         false,
267         parseResult,
268         ArrayType::NOT_ARRAY);
269     GetValueIfFindKey<bool>(jsonObject,
270         jsonObjectEnd,
271         JSON_KEY_BUNDLE_IS_STATIC,
272         shortcutInfo.isStatic,
273         JsonType::BOOLEAN,
274         false,
275         parseResult,
276         ArrayType::NOT_ARRAY);
277     GetValueIfFindKey<bool>(jsonObject,
278         jsonObjectEnd,
279         JSON_KEY_BUNDLE_IS_HOME_SHORTCUT,
280         shortcutInfo.isHomeShortcut,
281         JsonType::BOOLEAN,
282         false,
283         parseResult,
284         ArrayType::NOT_ARRAY);
285     GetValueIfFindKey<bool>(jsonObject,
286         jsonObjectEnd,
287         JSON_KEY_BUNDLE_IS_ENABLES,
288         shortcutInfo.isEnables,
289         JsonType::BOOLEAN,
290         false,
291         parseResult,
292         ArrayType::NOT_ARRAY);
293     GetValueIfFindKey<std::vector<ShortcutIntent>>(jsonObject,
294         jsonObjectEnd,
295         JSON_KEY_BUNDLE_INTENTS,
296         shortcutInfo.intents,
297         JsonType::ARRAY,
298         false,
299         parseResult,
300         ArrayType::OBJECT);
301     GetValueIfFindKey<uint32_t>(jsonObject,
302         jsonObjectEnd,
303         JSON_KEY_ICON_ID,
304         shortcutInfo.iconId,
305         JsonType::NUMBER,
306         false,
307         parseResult,
308         ArrayType::NOT_ARRAY);
309     GetValueIfFindKey<uint32_t>(jsonObject,
310         jsonObjectEnd,
311         JSON_KEY_LABEL_ID,
312         shortcutInfo.labelId,
313         JsonType::NUMBER,
314         false,
315         parseResult,
316         ArrayType::NOT_ARRAY);
317     GetValueIfFindKey<int32_t>(jsonObject,
318         jsonObjectEnd,
319         JSON_KEY_APP_INDEX,
320         shortcutInfo.appIndex,
321         JsonType::NUMBER,
322         false,
323         parseResult,
324         ArrayType::NOT_ARRAY);
325     GetValueIfFindKey<int32_t>(jsonObject,
326         jsonObjectEnd,
327         JSON_KEY_SOURCE_TYPE,
328         shortcutInfo.sourceType,
329         JsonType::NUMBER,
330         false,
331         parseResult,
332         ArrayType::NOT_ARRAY);
333     if (parseResult != ERR_OK) {
334         APP_LOGE("read shortcutInfo jsonObject error : %{public}d", parseResult);
335     }
336 }
337 
from_json(const nlohmann::json & jsonObject,ShortcutWant & shortcutWant)338 void from_json(const nlohmann::json &jsonObject, ShortcutWant &shortcutWant)
339 {
340     const auto &jsonObjectEnd = jsonObject.end();
341     int32_t parseResult = ERR_OK;
342     GetValueIfFindKey<std::string>(jsonObject,
343         jsonObjectEnd,
344         Constants::BUNDLE_NAME,
345         shortcutWant.bundleName,
346         JsonType::STRING,
347         false,
348         parseResult,
349         ArrayType::NOT_ARRAY);
350     GetValueIfFindKey<std::string>(jsonObject,
351         jsonObjectEnd,
352         Constants::MODULE_NAME,
353         shortcutWant.moduleName,
354         JsonType::STRING,
355         false,
356         parseResult,
357         ArrayType::NOT_ARRAY);
358     GetValueIfFindKey<std::string>(jsonObject,
359         jsonObjectEnd,
360         Constants::ABILITY_NAME,
361         shortcutWant.abilityName,
362         JsonType::STRING,
363         false,
364         parseResult,
365         ArrayType::NOT_ARRAY);
366     GetValueIfFindKey<std::map<std::string, std::string>>(jsonObject,
367         jsonObjectEnd,
368         JSON_KEY_BUNDLE_PARAMETERS,
369         shortcutWant.parameters,
370         JsonType::OBJECT,
371         false,
372         parseResult,
373         ArrayType::NOT_ARRAY);
374     if (parseResult != ERR_OK) {
375         APP_LOGE("read shortcutWant module.json error : %{public}d", parseResult);
376     }
377 }
378 
from_json(const nlohmann::json & jsonObject,Shortcut & shortcut)379 void from_json(const nlohmann::json &jsonObject, Shortcut &shortcut)
380 {
381     const auto &jsonObjectEnd = jsonObject.end();
382     int32_t parseResult = ERR_OK;
383     GetValueIfFindKey<std::string>(jsonObject,
384         jsonObjectEnd,
385         SHORTCUT_ID,
386         shortcut.shortcutId,
387         JsonType::STRING,
388         false,
389         parseResult,
390         ArrayType::NOT_ARRAY);
391     GetValueIfFindKey<std::string>(jsonObject,
392         jsonObjectEnd,
393         ICON,
394         shortcut.icon,
395         JsonType::STRING,
396         false,
397         parseResult,
398         ArrayType::NOT_ARRAY);
399     GetValueIfFindKey<uint32_t>(jsonObject,
400         jsonObjectEnd,
401         ICON_ID,
402         shortcut.iconId,
403         JsonType::NUMBER,
404         false,
405         parseResult,
406         ArrayType::NOT_ARRAY);
407     GetValueIfFindKey<std::string>(jsonObject,
408         jsonObjectEnd,
409         LABEL,
410         shortcut.label,
411         JsonType::STRING,
412         false,
413         parseResult,
414         ArrayType::NOT_ARRAY);
415     GetValueIfFindKey<uint32_t>(jsonObject,
416         jsonObjectEnd,
417         LABEL_ID,
418         shortcut.labelId,
419         JsonType::NUMBER,
420         false,
421         parseResult,
422         ArrayType::NOT_ARRAY);
423     GetValueIfFindKey<std::vector<ShortcutWant>>(jsonObject,
424         jsonObjectEnd,
425         SHORTCUT_WANTS,
426         shortcut.wants,
427         JsonType::ARRAY,
428         false,
429         parseResult,
430         ArrayType::OBJECT);
431     if (parseResult != ERR_OK) {
432         APP_LOGE("read Shortcut module.json error : %{public}d", parseResult);
433     }
434 }
435 
from_json(const nlohmann::json & jsonObject,ShortcutJson & shortcutJson)436 void from_json(const nlohmann::json &jsonObject, ShortcutJson &shortcutJson)
437 {
438     APP_LOGD("read shortcuts tag from module.json");
439     const auto &jsonObjectEnd = jsonObject.end();
440     int32_t parseResult = ERR_OK;
441     GetValueIfFindKey<std::vector<Shortcut>>(jsonObject,
442         jsonObjectEnd,
443         SHORTCUTS,
444         shortcutJson.shortcuts,
445         JsonType::ARRAY,
446         false,
447         parseResult,
448         ArrayType::OBJECT);
449     if (parseResult != ERR_OK) {
450         APP_LOGE("read ShortcutJson module.json error : %{public}d", parseResult);
451     }
452 }
453 }  // namespace AppExecFwk
454 }  // namespace OHOS
455