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