1 /*
2  * Copyright (c) 2023-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 #ifndef OHOS_ABILITY_RUNTIME_SERVICE_ROUTER_FRAMEWORK_SERVICES_INCLUDE_SERVICE_ROUTER_UTIL_H
17 #define OHOS_ABILITY_RUNTIME_SERVICE_ROUTER_FRAMEWORK_SERVICES_INCLUDE_SERVICE_ROUTER_UTIL_H
18 
19 #include <string>
20 #include <vector>
21 
22 #include "bundle_constants.h"
23 #include "bundle_info.h"
24 #include "hilog_tag_wrapper.h"
25 #include "inner_service_info.h"
26 #include "service_info.h"
27 #include "sr_constants.h"
28 #include "string_ex.h"
29 
30 namespace OHOS {
31 namespace AbilityRuntime {
32 namespace {
33     static std::unordered_map<std::string, BusinessType> BUSINESS_TYPE_MAP = {
34         {"share", BusinessType::SHARE}};
35 }
36 class BundleInfoResolveUtil {
37 public:
ResolveBundleInfo(const BundleInfo & bundleInfo,std::vector<PurposeInfo> & purposeInfos,std::vector<BusinessAbilityInfo> & businessAbilityInfos,const AppInfo & appInfo)38     static bool ResolveBundleInfo(const BundleInfo &bundleInfo, std::vector<PurposeInfo> &purposeInfos,
39         std::vector<BusinessAbilityInfo> &businessAbilityInfos, const AppInfo &appInfo)
40     {
41         if (bundleInfo.name.empty()) {
42             TAG_LOGE(AAFwkTag::SER_ROUTER, "BundleInfo invalid");
43             return false;
44         }
45         ResolveAbilityInfos(bundleInfo.abilityInfos, purposeInfos, appInfo);
46         ResolveExtAbilityInfos(bundleInfo.extensionInfos, purposeInfos, businessAbilityInfos, appInfo);
47         if (purposeInfos.empty() && businessAbilityInfos.empty()) {
48             TAG_LOGE(AAFwkTag::SER_ROUTER,
49                 "Not support, bundleName: %{public}s", bundleInfo.name.c_str());
50             return false;
51         }
52         return true;
53     }
54 
findBusinessType(const std::string businessType)55     static BusinessType findBusinessType(const std::string businessType)
56     {
57         if (businessType.empty()) {
58             return BusinessType::UNSPECIFIED;
59         }
60 
61         auto item = BUSINESS_TYPE_MAP.find(LowerStr(businessType));
62         if (item != BUSINESS_TYPE_MAP.end()) {
63             return item->second;
64         }
65         return BusinessType::UNSPECIFIED;
66     }
67 
GetBusinessType(const std::vector<Metadata> & metadata)68     static BusinessType GetBusinessType(const std::vector<Metadata> &metadata)
69     {
70         std::string businessType = GetExtAbilityMetadataValue(metadata, SrConstants::METADATA_SERVICE_TYPE_KEY);
71         return findBusinessType(businessType);
72     }
73 
74 private:
ResolveAbilityInfos(const std::vector<AbilityInfo> & abilityInfos,std::vector<PurposeInfo> & purposeInfos,const AppInfo & appInfo)75     static void ResolveAbilityInfos(const std::vector<AbilityInfo> &abilityInfos,
76         std::vector<PurposeInfo> &purposeInfos, const AppInfo &appInfo)
77     {
78         if (abilityInfos.empty()) {
79             return;
80         }
81         for (const auto &abilityInfo : abilityInfos) {
82             ConvertAbilityToPurposes(abilityInfo, purposeInfos, appInfo);
83         }
84     }
85 
ResolveExtAbilityInfos(const std::vector<ExtensionAbilityInfo> & extensionInfos,std::vector<PurposeInfo> & purposeInfos,std::vector<BusinessAbilityInfo> & businessAbilityInfos,const AppInfo & appInfo)86     static void ResolveExtAbilityInfos(const std::vector<ExtensionAbilityInfo> &extensionInfos,
87         std::vector<PurposeInfo> &purposeInfos, std::vector<BusinessAbilityInfo> &businessAbilityInfos,
88         const AppInfo &appInfo)
89     {
90         if (extensionInfos.empty()) {
91             return;
92         }
93         for (const auto &extensionInfo : extensionInfos) {
94             ConvertExtAbilityToPurposes(extensionInfo, purposeInfos, appInfo);
95             ConvertExtAbilityToService(extensionInfo, businessAbilityInfos, appInfo);
96         }
97     }
98 
ConvertAbilityToPurposes(const AbilityInfo & abilityInfo,std::vector<PurposeInfo> & purposeInfos,const AppInfo & appInfo)99     static void ConvertAbilityToPurposes(const AbilityInfo &abilityInfo, std::vector<PurposeInfo> &purposeInfos,
100         const AppInfo &appInfo)
101     {
102         TAG_LOGI(AAFwkTag::SER_ROUTER, "Called");
103         std::string supportPurpose = GetAbilityMetadataValue(abilityInfo, SrConstants::METADATA_SUPPORT_PURPOSE_KEY);
104         if (supportPurpose.empty()) {
105             return;
106         }
107         std::vector<std::string> purposeNames;
108         SplitStr(supportPurpose, SrConstants::MUTIL_SPLIT_KEY, purposeNames);
109         for (std::string &name : purposeNames) {
110             PurposeInfo purposeInfo;
111             purposeInfo.purposeName = name;
112             purposeInfo.abilityName = abilityInfo.name;
113             purposeInfo.moduleName = abilityInfo.moduleName;
114             purposeInfo.bundleName = abilityInfo.bundleName;
115             purposeInfo.componentType = ComponentType::UI_ABILITY;
116             purposeInfo.appInfo = appInfo;
117             purposeInfos.emplace_back(purposeInfo);
118             TAG_LOGD(AAFwkTag::SER_ROUTER,
119                 "Bundle: %{public}s ,ability: %{public}s, purposeName: %{public}s",
120                 abilityInfo.bundleName.c_str(), abilityInfo.name.c_str(), name.c_str());
121         }
122     }
123 
ConvertExtAbilityToPurposes(const ExtensionAbilityInfo & extAbilityInfo,std::vector<PurposeInfo> & purposeInfos,const AppInfo & appInfo)124     static void ConvertExtAbilityToPurposes(const ExtensionAbilityInfo &extAbilityInfo,
125         std::vector<PurposeInfo> &purposeInfos, const AppInfo &appInfo)
126     {
127         TAG_LOGI(AAFwkTag::SER_ROUTER, "Called");
128         if (extAbilityInfo.type != ExtensionAbilityType::FORM && extAbilityInfo.type != ExtensionAbilityType::UI) {
129             return;
130         }
131         std::string supportPurpose = GetExtAbilityMetadataValue(extAbilityInfo.metadata,
132             SrConstants::METADATA_SUPPORT_PURPOSE_KEY);
133         if (supportPurpose.empty()) {
134             return;
135         }
136         std::vector<std::string> purposes;
137         SplitStr(supportPurpose, SrConstants::MUTIL_SPLIT_KEY, purposes);
138         for (std::string &purposeAndCard : purposes) {
139             PurposeInfo purposeInfo;
140             purposeInfo.abilityName = extAbilityInfo.name;
141             purposeInfo.moduleName = extAbilityInfo.moduleName;
142             purposeInfo.bundleName = extAbilityInfo.bundleName;
143             purposeInfo.appInfo = appInfo;
144             if (extAbilityInfo.type == ExtensionAbilityType::UI) {
145                 purposeInfo.purposeName = purposeAndCard;
146                 purposeInfo.componentType = ComponentType::UI_EXTENSION;
147                 purposeInfos.emplace_back(purposeInfo);
148                 TAG_LOGD(AAFwkTag::SER_ROUTER,
149                     "UIExtToPurposes, bundle: %{public}s, abilityName: %{public}s, purposeName: %{public}s",
150                     extAbilityInfo.bundleName.c_str(), extAbilityInfo.name.c_str(), purposeAndCard.c_str());
151             } else {
152                 std::vector<std::string> purposeNameAndCardName;
153                 SplitStr(purposeAndCard, SrConstants::FORM_PURPOSE_CARD_SPLIT_KEY, purposeNameAndCardName);
154                 if (purposeNameAndCardName.size() == SrConstants::FORM_PURPOSE_CARD_SPLIT_SIZE) {
155                     purposeInfo.purposeName = purposeNameAndCardName[0];
156                     purposeInfo.cardName = purposeNameAndCardName[1];
157                     purposeInfo.componentType = ComponentType::FORM;
158                     purposeInfos.emplace_back(purposeInfo);
159                     TAG_LOGD(AAFwkTag::SER_ROUTER,
160                         "FormToPurposes, bundle: %{public}s, abilityName: %{public}s, purposeName: %{public}s",
161                         extAbilityInfo.bundleName.c_str(), extAbilityInfo.name.c_str(),
162                         purposeInfo.purposeName.c_str());
163                 } else {
164                     TAG_LOGW(AAFwkTag::SER_ROUTER, "FormToPurposes invalid");
165                 }
166             }
167         }
168     }
169 
ConvertExtAbilityToService(const ExtensionAbilityInfo & extAbilityInfo,std::vector<BusinessAbilityInfo> & businessAbilityInfos,const AppInfo & appInfo)170     static void ConvertExtAbilityToService(const ExtensionAbilityInfo &extAbilityInfo,
171         std::vector<BusinessAbilityInfo> &businessAbilityInfos, const AppInfo &appInfo)
172     {
173         if (extAbilityInfo.type != ExtensionAbilityType::UI) {
174             return;
175         }
176         BusinessType type = GetBusinessType(extAbilityInfo.metadata);
177         TAG_LOGD(AAFwkTag::SER_ROUTER, "AbilityName: %{public}s, businessType: %{public}d",
178             extAbilityInfo.name.c_str(), static_cast<int>(type));
179         if (type != BusinessType::UNSPECIFIED) {
180             BusinessAbilityInfo businessAbilityInfo;
181             businessAbilityInfo.appInfo = appInfo;
182             businessAbilityInfo.abilityName = extAbilityInfo.name;
183             businessAbilityInfo.moduleName = extAbilityInfo.moduleName;
184             businessAbilityInfo.bundleName = extAbilityInfo.bundleName;
185             businessAbilityInfo.businessType = type;
186             businessAbilityInfo.iconId = extAbilityInfo.iconId;
187             businessAbilityInfo.labelId = extAbilityInfo.labelId;
188             businessAbilityInfo.descriptionId = extAbilityInfo.descriptionId;
189             businessAbilityInfo.permissions = extAbilityInfo.permissions;
190             businessAbilityInfos.emplace_back(businessAbilityInfo);
191         }
192     }
193 
GetAbilityMetadataValue(const AbilityInfo & abilityInfo,const std::string & name)194     static std::string GetAbilityMetadataValue(const AbilityInfo &abilityInfo, const std::string &name)
195     {
196         if (abilityInfo.metadata.empty()) {
197             return Constants::EMPTY_STRING;
198         }
199         for (auto &metadata : abilityInfo.metadata) {
200             if (name == metadata.name && !metadata.value.empty()) {
201                 return metadata.value;
202             }
203         }
204         return Constants::EMPTY_STRING;
205     }
206 
GetExtAbilityMetadataValue(const std::vector<Metadata> & metadata,const std::string & name)207     static std::string GetExtAbilityMetadataValue(const std::vector<Metadata> &metadata, const std::string &name)
208     {
209         if (metadata.empty()) {
210             return Constants::EMPTY_STRING;
211         }
212         for (auto &metadata : metadata) {
213             if (name == metadata.name && !metadata.value.empty()) {
214                 return metadata.value;
215             }
216         }
217         return Constants::EMPTY_STRING;
218     }
219 }; // namespace ServiceRouterUtil
220 } // namespace AbilityRuntime
221 } // namespace OHOS
222 #endif // OHOS_ABILITY_RUNTIME_SERVICE_ROUTER_FRAMEWORK_SERVICES_INCLUDE_SERVICE_ROUTER_UTIL_H
223