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> ¶mEntities) 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 ¶mUtd : 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 ¶mType, 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 ¶mUtd : 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 ¶mUtd, 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 ¶m) 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 ¶mUtd : 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 ¶mUtd : 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