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