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 "app_log_wrapper.h"
17 #include "skill.h"
18 #include <regex>
19 #include <unistd.h>
20 #include "mime_type_mgr.h"
21 #include "parcel_macro.h"
22 #include "json_util.h"
23 #include <fcntl.h>
24 #include "nlohmann/json.hpp"
25 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
26 #include "type_descriptor.h"
27 #include "utd_client.h"
28 #endif
29 
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 constexpr const char* JSON_KEY_TYPE = "type";
34 constexpr const char* JSON_KEY_PERMISSIONS = "permissions";
35 constexpr const char* JSON_KEY_ACTIONS = "actions";
36 constexpr const char* JSON_KEY_ENTITIES = "entities";
37 constexpr const char* JSON_KEY_URIS = "uris";
38 constexpr const char* JSON_KEY_SCHEME = "scheme";
39 constexpr const char* JSON_KEY_HOST = "host";
40 constexpr const char* JSON_KEY_PORT = "port";
41 constexpr const char* JSON_KEY_PATH = "path";
42 constexpr const char* JSON_KEY_PATHSTARTWITH = "pathStartWith";
43 constexpr const char* JSON_KEY_PATHREGEX = "pathRegex";
44 constexpr const char* JSON_KEY_UTD = "utd";
45 constexpr const char* JSON_KEY_MAXFILESUPPORTED = "maxFileSupported";
46 constexpr const char* JSON_KEY_LINKFEATURE =  "linkFeature";
47 constexpr const char* JSON_KEY_DOMAINVERIFY = "domainVerify";
48 constexpr const char* BUNDLE_MODULE_PROFILE_KEY_PATHREGX = "pathRegx";
49 constexpr const char* PARAM_SEPARATOR = "?";
50 constexpr const char* PORT_SEPARATOR = ":";
51 constexpr const char* SCHEME_SEPARATOR = "://";
52 constexpr const char* PATH_SEPARATOR = "/";
53 constexpr const char* TYPE_WILDCARD = "*/*";
54 const char WILDCARD = '*';
55 constexpr const char* TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard";
56 const char* LINK_FEATURE = "linkFeature";
57 const char* GENERAL_OBJECT = "general.object";
58 }; // namespace
59 
Match(const OHOS::AAFwk::Want & want) const60 bool Skill::Match(const OHOS::AAFwk::Want &want) const
61 {
62     std::string linkFeature = want.GetStringParam(LINK_FEATURE);
63     if (!linkFeature.empty()) {
64         size_t matchUriIndex = 0;
65         return MatchLinkFeature(linkFeature, want, matchUriIndex);
66     }
67 
68     if (!MatchActionAndEntities(want)) {
69         APP_LOGD("Action or entities does not match");
70         return false;
71     }
72     std::vector<std::string> vecTypes = want.GetStringArrayParam(OHOS::AAFwk::Want::PARAM_ABILITY_URITYPES);
73     if (vecTypes.size() > 0) {
74         for (std::string strType : vecTypes) {
75             if (MatchUriAndType(want.GetUriString(), strType)) {
76                 APP_LOGD("type %{public}s, Is Matched", strType.c_str());
77                 return true;
78             }
79         }
80         return false;
81     }
82     bool matchUriAndType = MatchUriAndType(want.GetUriString(), want.GetType());
83     if (!matchUriAndType) {
84         APP_LOGD("Uri or Type does not match");
85         return false;
86     }
87     return true;
88 }
89 
Match(const OHOS::AAFwk::Want & want,size_t & matchUriIndex) const90 bool Skill::Match(const OHOS::AAFwk::Want &want, size_t &matchUriIndex) const
91 {
92     std::string linkFeature = want.GetStringParam(LINK_FEATURE);
93     if (!linkFeature.empty()) {
94         return MatchLinkFeature(linkFeature, want, matchUriIndex);
95     }
96 
97     if (!MatchActionAndEntities(want)) {
98         APP_LOGD("Action or entities does not match");
99         return false;
100     }
101 
102     std::vector<std::string> vecTypes = want.GetStringArrayParam(OHOS::AAFwk::Want::PARAM_ABILITY_URITYPES);
103     if (vecTypes.size() > 0) {
104         for (std::string strType : vecTypes) {
105             if (MatchUriAndType(want.GetUriString(), strType, matchUriIndex)) {
106                 APP_LOGD("type %{public}s, Is Matched", strType.c_str());
107                 return true;
108             }
109         }
110         return false;
111     }
112     bool matchUriAndType = MatchUriAndType(want.GetUriString(), want.GetType(), matchUriIndex);
113     if (!matchUriAndType) {
114         APP_LOGD("Uri or Type does not match");
115         return false;
116     }
117     return true;
118 }
119 
MatchLauncher(const OHOS::AAFwk::Want & want) const120 bool Skill::MatchLauncher(const OHOS::AAFwk::Want &want) const
121 {
122     bool matchAction = MatchAction(want.GetAction());
123     if (!matchAction) {
124         APP_LOGD("Action does not match");
125         return false;
126     }
127     bool matchEntities = MatchEntities(want.GetEntities());
128     if (!matchEntities) {
129         APP_LOGD("Entities does not match");
130         return false;
131     }
132     return true;
133 }
134 
MatchAction(const std::string & action) const135 bool Skill::MatchAction(const std::string &action) const
136 {
137     // config actions empty, no match
138     if (actions.empty()) {
139         return false;
140     }
141     // config actions not empty, param empty, match
142     if (action.empty()) {
143         return true;
144     }
145     auto actionMatcher = [action] (const std::string &configAction) {
146         if (action == configAction) {
147             return true;
148         }
149         if (action == Constants::ACTION_HOME && configAction == Constants::WANT_ACTION_HOME) {
150             return true;
151         }
152         if (action == Constants::WANT_ACTION_HOME && configAction == Constants::ACTION_HOME) {
153             return true;
154         }
155         return false;
156     };
157     // config actions not empty, param not empty, if config actions contains param action, match
158     return std::find_if(actions.cbegin(), actions.cend(), actionMatcher) != actions.cend();
159 }
160 
MatchEntities(const std::vector<std::string> & paramEntities) const161 bool Skill::MatchEntities(const std::vector<std::string> &paramEntities) const
162 {
163     // param entities empty, match
164     if (paramEntities.empty()) {
165         return true;
166     }
167     // config entities empty, param entities not empty, not match
168     if (entities.empty()) {
169         return false;
170     }
171     // config entities not empty, param entities not empty, if every param entity in config entities, match
172     std::vector<std::string>::size_type size = paramEntities.size();
173     for (std::vector<std::string>::size_type i = 0; i < size; i++) {
174         bool ret = std::find(entities.cbegin(), entities.cend(), paramEntities[i]) == entities.cend();
175         if (ret) {
176             return false;
177         }
178     }
179     return true;
180 }
181 
MatchActionAndEntities(const OHOS::AAFwk::Want & want) const182 bool Skill::MatchActionAndEntities(const OHOS::AAFwk::Want &want) const
183 {
184     bool matchAction = MatchAction(want.GetAction());
185     if (!matchAction) {
186         APP_LOGD("Action does not match");
187         return false;
188     }
189     bool matchEntities = MatchEntities(want.GetEntities());
190     if (!matchEntities) {
191         APP_LOGD("Entities does not match");
192         return false;
193     }
194     return true;
195 }
196 
MatchUriAndType(const std::string & rawUriString,const std::string & type) const197 bool Skill::MatchUriAndType(const std::string &rawUriString, const std::string &type) const
198 {
199     const std::string uriString = GetOptParamUri(rawUriString);
200     if (uriString.empty() && type.empty()) {
201         // case1 : param uri empty, param type empty
202         if (uris.empty()) {
203             return true;
204         }
205         for (const SkillUri &skillUri : uris) {
206             if (skillUri.scheme.empty() && skillUri.type.empty()) {
207                 return true;
208             }
209         }
210         return false;
211     }
212     if (uris.empty()) {
213         return false;
214     }
215     if (!uriString.empty() && type.empty()) {
216         // case2 : param uri not empty, param type empty
217         for (const SkillUri &skillUri : uris) {
218             if (MatchUri(uriString, skillUri) && skillUri.type.empty()) {
219                 return true;
220             }
221         }
222         // if uri is a file path, match type by the suffix
223         return MatchMimeType(uriString);
224     } else if (uriString.empty() && !type.empty()) {
225         // case3 : param uri empty, param type not empty
226         for (const SkillUri &skillUri : uris) {
227             if (skillUri.scheme.empty() && MatchType(type, skillUri.type)) {
228                 return true;
229             }
230         }
231         return false;
232     } else {
233         // case4 : param uri not empty, param type not empty
234         for (const SkillUri &skillUri : uris) {
235             if (MatchUri(uriString, skillUri) && MatchType(type, skillUri.type)) {
236                 return true;
237             }
238         }
239         return false;
240     }
241 }
242 
MatchLinkFeature(const std::string & linkFeature,const OHOS::AAFwk::Want & want,size_t & matchUriIndex) const243 bool Skill::MatchLinkFeature(const std::string &linkFeature, const OHOS::AAFwk::Want &want, size_t &matchUriIndex) const
244 {
245     std::string paramUriString = GetOptParamUri(want.GetUriString());
246     std::string paramType = want.GetType();
247     // only linkFeature
248     if (paramUriString.empty() && paramType.empty()) {
249         for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
250             const SkillUri &skillUri = uris[uriIndex];
251             if (linkFeature == skillUri.linkFeature) {
252                 matchUriIndex = uriIndex;
253                 return true;
254             }
255         }
256         return false;
257     }
258     // linkFeature + uri + type
259     bool onlyUri = !paramUriString.empty() && paramType.empty();
260     for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
261         const SkillUri &skillUri = uris[uriIndex];
262         if (linkFeature != skillUri.linkFeature) {
263             continue;
264         }
265         if (MatchUri(paramUriString, skillUri) && MatchType(paramType, skillUri.type)) {
266             matchUriIndex = uriIndex;
267             return true;
268         }
269         if (!onlyUri) {
270             continue;
271         }
272         std::vector<std::string> paramUtdVector;
273         if (!MimeTypeMgr::GetUtdVectorByUri(paramUriString, paramUtdVector)) {
274             continue;
275         }
276         for (const std::string &paramUtd : paramUtdVector) {
277             if ((MatchUri(paramUriString, skillUri) ||
278                 (skillUri.scheme.empty() && paramUriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
279                 MatchType(paramUtd, skillUri.type)) {
280                 matchUriIndex = uriIndex;
281                 return true;
282             }
283         }
284     }
285     return false;
286 }
287 
MatchUriAndType(const std::string & rawUriString,const std::string & type,size_t & matchUriIndex) const288 bool Skill::MatchUriAndType(const std::string &rawUriString, const std::string &type, size_t &matchUriIndex) const
289 {
290     const std::string uriString = GetOptParamUri(rawUriString);
291     if (uriString.empty() && type.empty()) {
292         // case1 : param uri empty, param type empty
293         if (uris.empty()) {
294             return true;
295         }
296         for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
297             const SkillUri &skillUri = uris[uriIndex];
298             if (skillUri.scheme.empty() && skillUri.type.empty()) {
299                 matchUriIndex = uriIndex;
300                 return true;
301             }
302         }
303         return false;
304     }
305     if (uris.empty()) {
306         return false;
307     }
308     if (!uriString.empty() && type.empty()) {
309         // case2 : param uri not empty, param type empty
310         for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
311             const SkillUri &skillUri = uris[uriIndex];
312             if (MatchUri(uriString, skillUri) && skillUri.type.empty()) {
313                 matchUriIndex = uriIndex;
314                 return true;
315             }
316         }
317         // if uri is a file path, match type by the suffix
318         return MatchMimeType(uriString, matchUriIndex);
319     } else if (uriString.empty() && !type.empty()) {
320         // case3 : param uri empty, param type not empty
321         for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
322             const SkillUri &skillUri = uris[uriIndex];
323             if (skillUri.scheme.empty() && MatchType(type, skillUri.type)) {
324                 matchUriIndex = uriIndex;
325                 return true;
326             }
327         }
328         return false;
329     } else {
330         // case4 : param uri not empty, param type not empty
331         for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
332             const SkillUri &skillUri = uris[uriIndex];
333             if (MatchUri(uriString, skillUri) && MatchType(type, skillUri.type)) {
334                 matchUriIndex = uriIndex;
335                 return true;
336             }
337         }
338         return false;
339     }
340 }
341 
StartsWith(const std::string & sourceString,const std::string & targetPrefix) const342 bool Skill::StartsWith(const std::string &sourceString, const std::string &targetPrefix) const
343 {
344     return sourceString.rfind(targetPrefix, 0) == 0;
345 }
346 
GetOptParamUri(const std::string & uriString)347 std::string Skill::GetOptParamUri(const std::string &uriString)
348 {
349     std::size_t pos = uriString.find(PARAM_SEPARATOR);
350     if (pos == std::string::npos) {
351         return uriString;
352     }
353     return uriString.substr(0, pos);
354 }
355 
MatchUri(const std::string & uriString,const SkillUri & skillUri) const356 bool Skill::MatchUri(const std::string &uriString, const SkillUri &skillUri) const
357 {
358     if (uriString.empty() && skillUri.scheme.empty()) {
359         return true;
360     }
361     if (uriString.empty() || skillUri.scheme.empty()) {
362         return false;
363     }
364     if (skillUri.host.empty()) {
365         // config uri is : scheme
366         // belows are param uri matched conditions:
367         // 1.scheme
368         // 2.scheme:
369         // 3.scheme:/
370         // 4.scheme://
371         return uriString == skillUri.scheme || StartsWith(uriString, skillUri.scheme + PORT_SEPARATOR);
372     }
373     std::string optParamUri = GetOptParamUri(uriString);
374     std::string skillUriString;
375     skillUriString.append(skillUri.scheme).append(SCHEME_SEPARATOR).append(skillUri.host);
376     if (!skillUri.port.empty()) {
377         skillUriString.append(PORT_SEPARATOR).append(skillUri.port);
378     }
379     if (skillUri.path.empty() && skillUri.pathStartWith.empty() && skillUri.pathRegex.empty()) {
380         // with port, config uri is : scheme://host:port
381         // belows are param uri matched conditions:
382         // 1.scheme://host:port
383         // 2.scheme://host:port/path
384 
385         // without port, config uri is : scheme://host
386         // belows are param uri matched conditions:
387         // 1.scheme://host
388         // 2.scheme://host/path
389         // 3.scheme://host:port     scheme://host:port/path
390         bool ret = (optParamUri == skillUriString || StartsWith(optParamUri, skillUriString + PATH_SEPARATOR));
391         if (skillUri.port.empty()) {
392             ret = ret || StartsWith(optParamUri, skillUriString + PORT_SEPARATOR);
393         }
394         return ret;
395     }
396     skillUriString.append(PATH_SEPARATOR);
397     // if one of path, pathStartWith, pathRegex match, then match
398     if (!skillUri.path.empty()) {
399         // path match
400         std::string pathUri(skillUriString);
401         pathUri.append(skillUri.path);
402         if (optParamUri == pathUri) {
403             return true;
404         }
405     }
406     if (!skillUri.pathStartWith.empty()) {
407         // pathStartWith match
408         std::string pathStartWithUri(skillUriString);
409         pathStartWithUri.append(skillUri.pathStartWith);
410         if (StartsWith(optParamUri, pathStartWithUri)) {
411             return true;
412         }
413     }
414     if (!skillUri.pathRegex.empty()) {
415         // pathRegex match
416         std::string pathRegexUri(skillUriString);
417         pathRegexUri.append(skillUri.pathRegex);
418         try {
419             std::regex regex(pathRegexUri);
420             if (regex_match(optParamUri, regex)) {
421                 return true;
422             }
423         } catch (const std::regex_error& e) {
424             APP_LOGE("regex error");
425         }
426     }
427     return false;
428 }
429 
MatchType(const std::string & type,const std::string & skillUriType) const430 bool Skill::MatchType(const std::string &type, const std::string &skillUriType) const
431 {
432     if (type.empty() && skillUriType.empty()) {
433         return true;
434     }
435     if (type.empty() || skillUriType.empty()) {
436         return false;
437     }
438 
439     // only match */* or general.object
440     if (type == TYPE_ONLY_MATCH_WILDCARD) {
441         return skillUriType == TYPE_WILDCARD || skillUriType == GENERAL_OBJECT;
442     }
443 
444     bool containsUtd = false;
445     bool matchUtdRet = MatchUtd(type, skillUriType, containsUtd);
446     if (containsUtd) {
447         return matchUtdRet;
448     }
449 
450     if (type == TYPE_WILDCARD || skillUriType == TYPE_WILDCARD) {
451         // param is */* or config is */*
452         return true;
453     }
454     bool paramTypeRegex = type.back() == WILDCARD;
455     if (paramTypeRegex) {
456         // param is string/*
457         std::string prefix = type.substr(0, type.length() - 1);
458         return skillUriType.find(prefix) == 0;
459     }
460     bool typeRegex = skillUriType.back() == WILDCARD;
461     if (typeRegex) {
462         // config is string/*
463         std::string prefix = skillUriType.substr(0, skillUriType.length() - 1);
464         return type.find(prefix) == 0;
465     } else {
466         return type == skillUriType;
467     }
468 }
469 
MatchUtd(const std::string & paramType,const std::string & skillUriType,bool & containsUtd) const470 bool Skill::MatchUtd(const std::string &paramType, const std::string &skillUriType, bool &containsUtd) const
471 {
472 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
473     bool isParamUtd = IsUtd(paramType);
474     bool isSkillUtd = IsUtd(skillUriType);
475 
476     containsUtd = isParamUtd || isSkillUtd;
477 
478     if (!isParamUtd && !isSkillUtd) {
479         // 1.param : mimeType, skill : mimeType
480         return false;
481     } else if (isParamUtd && isSkillUtd) {
482         // 2.param : utd, skill : utd
483         return IsUtdMatch(paramType, skillUriType);
484     } else if (!isParamUtd && isSkillUtd) {
485         // 3.param : mimeType, skill : utd
486         std::vector<std::string> paramUtdVector;
487         auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByMIMEType(paramType, paramUtdVector);
488         if (ret != ERR_OK || paramUtdVector.empty()) {
489             return false;
490         }
491         for (const std::string &paramUtd : paramUtdVector) {
492             if (IsUtdMatch(paramUtd, skillUriType)) {
493                 return true;
494             }
495         }
496         return false;
497     } else {
498         // 4.param : utd, skill : mimeType
499         std::vector<std::string> skillUtdVector;
500         auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByMIMEType(skillUriType, skillUtdVector);
501         if (ret != ERR_OK || skillUtdVector.empty()) {
502             return false;
503         }
504         for (const std::string &skillUtd : skillUtdVector) {
505             if (IsUtdMatch(paramType, skillUtd)) {
506                 return true;
507             }
508         }
509         return false;
510     }
511 #else
512     containsUtd = false;
513     return false;
514 #endif
515 }
516 
IsUtdMatch(const std::string & paramUtd,const std::string & skillUtd) const517 bool Skill::IsUtdMatch(const std::string &paramUtd, const std::string &skillUtd) const
518 {
519 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
520     std::shared_ptr<UDMF::TypeDescriptor> paramTypeDescriptor;
521     auto ret = UDMF::UtdClient::GetInstance().GetTypeDescriptor(paramUtd, paramTypeDescriptor);
522     if (ret != ERR_OK || paramTypeDescriptor == nullptr) {
523         return false;
524     }
525     bool isMatch = false;
526     ret = paramTypeDescriptor->BelongsTo(skillUtd, isMatch);
527     if (ret != ERR_OK) {
528         return false;
529     }
530     return isMatch;
531 #else
532     return false;
533 #endif
534 }
535 
IsUtd(const std::string & param) const536 bool Skill::IsUtd(const std::string &param) const
537 {
538 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
539     bool isUtd = false;
540     auto ret = UDMF::UtdClient::GetInstance().IsUtd(param, isUtd);
541     return ret == ERR_OK && isUtd;
542 #else
543     return false;
544 #endif
545 }
546 
MatchMimeType(const std::string & uriString) const547 bool Skill::MatchMimeType(const std::string & uriString) const
548 {
549     std::vector<std::string> paramUtdVector;
550     if (!MimeTypeMgr::GetUtdVectorByUri(uriString, paramUtdVector)) {
551         return false;
552     }
553     for (const SkillUri &skillUri : uris) {
554         for (const std::string &paramUtd : paramUtdVector) {
555             if ((MatchUri(uriString, skillUri) ||
556                 (skillUri.scheme.empty() && uriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
557                 MatchType(paramUtd, skillUri.type)) {
558                 return true;
559             }
560         }
561     }
562     return false;
563 }
564 
565 
MatchMimeType(const std::string & uriString,size_t & matchUriIndex) const566 bool Skill::MatchMimeType(const std::string & uriString, size_t &matchUriIndex) const
567 {
568     std::vector<std::string> paramUtdVector;
569     if (!MimeTypeMgr::GetUtdVectorByUri(uriString, paramUtdVector)) {
570         return false;
571     }
572     for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
573         const SkillUri &skillUri = uris[uriIndex];
574         for (const std::string &paramUtd : paramUtdVector) {
575             if ((MatchUri(uriString, skillUri) ||
576                 (skillUri.scheme.empty() && uriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
577                 MatchType(paramUtd, skillUri.type)) {
578                 matchUriIndex = uriIndex;
579                 return true;
580             }
581         }
582     }
583     return false;
584 }
585 
ReadFromParcel(Parcel & parcel)586 bool Skill::ReadFromParcel(Parcel &parcel)
587 {
588     int32_t actionsSize;
589     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, actionsSize);
590     CONTAINER_SECURITY_VERIFY(parcel, actionsSize, &actions);
591     for (auto i = 0; i < actionsSize; i++) {
592         actions.emplace_back(Str16ToStr8(parcel.ReadString16()));
593     }
594 
595     int32_t entitiesSize;
596     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, entitiesSize);
597     CONTAINER_SECURITY_VERIFY(parcel, entitiesSize, &entities);
598     for (auto i = 0; i < entitiesSize; i++) {
599         entities.emplace_back(Str16ToStr8(parcel.ReadString16()));
600     }
601 
602     int32_t urisSize;
603     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, urisSize);
604     CONTAINER_SECURITY_VERIFY(parcel, urisSize, &uris);
605     for (auto i = 0; i < urisSize; i++) {
606         SkillUri uri;
607         uri.scheme = Str16ToStr8(parcel.ReadString16());
608         uri.host = Str16ToStr8(parcel.ReadString16());
609         uri.port = Str16ToStr8(parcel.ReadString16());
610         uri.path = Str16ToStr8(parcel.ReadString16());
611         uri.pathStartWith = Str16ToStr8(parcel.ReadString16());
612         uri.pathRegex = Str16ToStr8(parcel.ReadString16());
613         uri.type = Str16ToStr8(parcel.ReadString16());
614         uri.utd = Str16ToStr8(parcel.ReadString16());
615         uri.maxFileSupported = parcel.ReadInt32();
616         uri.linkFeature = Str16ToStr8(parcel.ReadString16());
617         uris.emplace_back(uri);
618     }
619 
620     int32_t permissionsSize;
621     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissionsSize);
622     CONTAINER_SECURITY_VERIFY(parcel, permissionsSize, &permissions);
623     for (auto i = 0; i < permissionsSize; i++) {
624         permissions.emplace_back(Str16ToStr8(parcel.ReadString16()));
625     }
626     domainVerify = parcel.ReadBool();
627     return true;
628 }
629 
Unmarshalling(Parcel & parcel)630 Skill *Skill::Unmarshalling(Parcel &parcel)
631 {
632     Skill *skill = new (std::nothrow) Skill();
633     if (skill && !skill->ReadFromParcel(parcel)) {
634         APP_LOGW("read from parcel failed");
635         delete skill;
636         skill = nullptr;
637     }
638     return skill;
639 }
640 
Marshalling(Parcel & parcel) const641 bool Skill::Marshalling(Parcel &parcel) const
642 {
643     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, actions.size());
644     for (auto &action : actions) {
645         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(action));
646     }
647 
648     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, entities.size());
649     for (auto &entitiy : entities) {
650         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(entitiy));
651     }
652 
653     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uris.size());
654     for (auto &uri : uris) {
655         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.scheme));
656         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.host));
657         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.port));
658         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.path));
659         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.pathStartWith));
660         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.pathRegex));
661         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.type));
662         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.utd));
663         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uri.maxFileSupported);
664         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.linkFeature));
665     }
666     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissions.size());
667     for (auto &permission : permissions) {
668         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(permission));
669     }
670     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, domainVerify);
671     return true;
672 }
673 
Dump(std::string prefix,int fd)674 void Skill::Dump(std::string prefix, int fd)
675 {
676     APP_LOGI("called dump Skill");
677     if (fd < 0) {
678         APP_LOGE("dump Skill fd error");
679         return;
680     }
681     int flags = fcntl(fd, F_GETFL);
682     if (flags < 0) {
683         APP_LOGE("dump Skill fcntl error : %{public}d", errno);
684         return;
685     }
686     uint uflags = static_cast<uint>(flags);
687     uflags &= O_ACCMODE;
688     if ((uflags == O_WRONLY) || (uflags == O_RDWR)) {
689         nlohmann::json jsonObject = *this;
690         std::string result;
691         result.append(prefix);
692         result.append(jsonObject.dump(Constants::DUMP_INDENT));
693         int ret = TEMP_FAILURE_RETRY(write(fd, result.c_str(), result.size()));
694         if (ret < 0) {
695             APP_LOGE("dump Abilityinfo write error : %{public}d", errno);
696         }
697     }
698     return;
699 }
700 
from_json(const nlohmann::json & jsonObject,SkillUri & uri)701 void from_json(const nlohmann::json &jsonObject, SkillUri &uri)
702 {
703     const auto &jsonObjectEnd = jsonObject.end();
704     int32_t parseResult = ERR_OK;
705     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_SCHEME,
706     uri.scheme, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
707     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_HOST,
708         uri.host, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
709     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_PORT,
710         uri.port, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
711     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_PATH,
712         uri.path, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
713     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_PATHSTARTWITH,
714         uri.pathStartWith, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
715     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, BUNDLE_MODULE_PROFILE_KEY_PATHREGX,
716         uri.pathRegex, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
717     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_PATHREGEX,
718         uri.pathRegex, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
719     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_TYPE,
720         uri.type, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
721     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_UTD,
722         uri.utd, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
723     GetValueIfFindKey<int32_t>(jsonObject, jsonObjectEnd, JSON_KEY_MAXFILESUPPORTED,
724         uri.maxFileSupported, JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
725     GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_LINKFEATURE,
726         uri.linkFeature, JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
727 }
728 
from_json(const nlohmann::json & jsonObject,Skill & skill)729 void from_json(const nlohmann::json &jsonObject, Skill &skill)
730 {
731     const auto &jsonObjectEnd = jsonObject.end();
732     int32_t parseResult = ERR_OK;
733     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
734         jsonObjectEnd,
735         JSON_KEY_ACTIONS,
736         skill.actions,
737         JsonType::ARRAY,
738         false,
739         parseResult,
740         ArrayType::STRING);
741     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
742         jsonObjectEnd,
743         JSON_KEY_ENTITIES,
744         skill.entities,
745         JsonType::ARRAY,
746         false,
747         parseResult,
748         ArrayType::STRING);
749     GetValueIfFindKey<std::vector<SkillUri>>(jsonObject,
750         jsonObjectEnd,
751         JSON_KEY_URIS,
752         skill.uris,
753         JsonType::ARRAY,
754         false,
755         parseResult,
756         ArrayType::OBJECT);
757     GetValueIfFindKey<std::vector<std::string>>(jsonObject,
758         jsonObjectEnd,
759         JSON_KEY_PERMISSIONS,
760         skill.permissions,
761         JsonType::ARRAY,
762         false,
763         parseResult,
764         ArrayType::STRING);
765     GetValueIfFindKey<bool>(jsonObject,
766         jsonObjectEnd,
767         JSON_KEY_DOMAINVERIFY,
768         skill.domainVerify,
769         JsonType::BOOLEAN,
770         false,
771         parseResult,
772         ArrayType::NOT_ARRAY);
773 }
774 
to_json(nlohmann::json & jsonObject,const SkillUri & uri)775 void to_json(nlohmann::json &jsonObject, const SkillUri &uri)
776 {
777     jsonObject = nlohmann::json {
778         {JSON_KEY_SCHEME, uri.scheme},
779         {JSON_KEY_HOST, uri.host},
780         {JSON_KEY_PORT, uri.port},
781         {JSON_KEY_PATH, uri.path},
782         {JSON_KEY_PATHSTARTWITH,  uri.pathStartWith},
783         {JSON_KEY_PATHREGEX, uri.pathRegex},
784         {JSON_KEY_TYPE, uri.type},
785         {JSON_KEY_UTD, uri.utd},
786         {JSON_KEY_MAXFILESUPPORTED, uri.maxFileSupported},
787         {JSON_KEY_LINKFEATURE, uri.linkFeature},
788     };
789 }
790 
to_json(nlohmann::json & jsonObject,const Skill & skill)791 void to_json(nlohmann::json &jsonObject, const Skill &skill)
792 {
793     jsonObject = nlohmann::json {
794         {JSON_KEY_ACTIONS, skill.actions},
795         {JSON_KEY_ENTITIES, skill.entities},
796         {JSON_KEY_URIS, skill.uris},
797         {JSON_KEY_PERMISSIONS, skill.permissions},
798         {JSON_KEY_DOMAINVERIFY, skill.domainVerify}
799     };
800 }
801 }  // namespace AppExecFwk
802 }  // namespace OHOS
803