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 #include "insight_intent_profile.h"
17 
18 #include "hilog_tag_wrapper.h"
19 #include "json_util.h"
20 
21 namespace OHOS {
22 namespace AbilityRuntime {
23 using JsonType = AppExecFwk::JsonType;
24 using ArrayType = AppExecFwk::ArrayType;
25 
26 namespace {
27 int32_t g_parseResult = ERR_OK;
28 std::mutex g_mutex;
29 
30 const std::string INSIGHT_INTENTS = "insightIntents";
31 const std::string INSIGHT_INTENT_NAME = "intentName";
32 const std::string INSIGHT_INTENT_DOMAIN = "domain";
33 const std::string INSIGHT_INTENT_VERSION = "intentVersion";
34 const std::string INSIGHT_INTENT_SRC_ENTRY = "srcEntry";
35 const std::string INSIGHT_INTENT_UI_ABILITY = "uiAbility";
36 const std::string INSIGHT_INTENT_UI_EXTENSION = "uiExtension";
37 const std::string INSIGHT_INTENT_SERVICE_EXTENSION = "serviceExtension";
38 const std::string INSIGHT_INTENT_FORM = "form";
39 const std::string INSIGHT_INTENT_ABILITY = "ability";
40 const std::string INSIGHT_INTENT_EXECUTE_MODE = "executeMode";
41 const std::string INSIGHT_INTENT_FORM_NAME = "formName";
42 
43 const std::map<std::string, ExecuteMode> executeModeMap = {
44     {"foreground", ExecuteMode::UI_ABILITY_FOREGROUND},
45     {"background", ExecuteMode::UI_ABILITY_BACKGROUND}
46 };
47 
48 struct UIAbilityProfileInfo {
49     std::string abilityName;
50     std::vector<std::string> supportExecuteMode {};
51 };
52 
53 struct UIExtensionProfileInfo {
54     std::string abilityName;
55 };
56 
57 struct ServiceExtensionProfileInfo {
58     std::string abilityName;
59 };
60 
61 struct FormProfileInfo {
62     std::string abilityName;
63     std::string formName;
64 };
65 
66 struct InsightIntentProfileInfo {
67     std::string intentName;
68     std::string intentDomain;
69     std::string intentVersion;
70     std::string srcEntry;
71     UIAbilityProfileInfo uiAbilityProfileInfo;
72     UIExtensionProfileInfo uiExtensionProfileInfo;
73     ServiceExtensionProfileInfo serviceExtensionProfileInfo;
74     FormProfileInfo formProfileInfo;
75 };
76 
77 struct InsightIntentProfileInfoVec {
78     std::vector<InsightIntentProfileInfo> insightIntents {};
79 };
80 
from_json(const nlohmann::json & jsonObject,UIAbilityProfileInfo & info)81 void from_json(const nlohmann::json &jsonObject, UIAbilityProfileInfo &info)
82 {
83     const auto &jsonObjectEnd = jsonObject.end();
84     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
85         jsonObjectEnd,
86         INSIGHT_INTENT_ABILITY,
87         info.abilityName,
88         JsonType::STRING,
89         true,
90         g_parseResult,
91         ArrayType::NOT_ARRAY);
92     AppExecFwk::GetValueIfFindKey<std::vector<std::string>>(jsonObject,
93         jsonObjectEnd,
94         INSIGHT_INTENT_EXECUTE_MODE,
95         info.supportExecuteMode,
96         JsonType::ARRAY,
97         true,
98         g_parseResult,
99         ArrayType::STRING);
100 }
101 
from_json(const nlohmann::json & jsonObject,UIExtensionProfileInfo & info)102 void from_json(const nlohmann::json &jsonObject, UIExtensionProfileInfo &info)
103 {
104     const auto &jsonObjectEnd = jsonObject.end();
105     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
106         jsonObjectEnd,
107         INSIGHT_INTENT_ABILITY,
108         info.abilityName,
109         JsonType::STRING,
110         true,
111         g_parseResult,
112         ArrayType::NOT_ARRAY);
113 }
114 
from_json(const nlohmann::json & jsonObject,ServiceExtensionProfileInfo & info)115 void from_json(const nlohmann::json &jsonObject, ServiceExtensionProfileInfo &info)
116 {
117     const auto &jsonObjectEnd = jsonObject.end();
118     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
119         jsonObjectEnd,
120         INSIGHT_INTENT_ABILITY,
121         info.abilityName,
122         JsonType::STRING,
123         true,
124         g_parseResult,
125         ArrayType::NOT_ARRAY);
126 }
127 
from_json(const nlohmann::json & jsonObject,FormProfileInfo & info)128 void from_json(const nlohmann::json &jsonObject, FormProfileInfo &info)
129 {
130     const auto &jsonObjectEnd = jsonObject.end();
131     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
132         jsonObjectEnd,
133         INSIGHT_INTENT_ABILITY,
134         info.abilityName,
135         JsonType::STRING,
136         true,
137         g_parseResult,
138         ArrayType::NOT_ARRAY);
139     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
140         jsonObjectEnd,
141         INSIGHT_INTENT_FORM_NAME,
142         info.formName,
143         JsonType::STRING,
144         true,
145         g_parseResult,
146         ArrayType::NOT_ARRAY);
147 }
148 
from_json(const nlohmann::json & jsonObject,InsightIntentProfileInfo & insightIntentInfo)149 void from_json(const nlohmann::json &jsonObject, InsightIntentProfileInfo &insightIntentInfo)
150 {
151     const auto &jsonObjectEnd = jsonObject.end();
152     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
153         jsonObjectEnd,
154         INSIGHT_INTENT_NAME,
155         insightIntentInfo.intentName,
156         JsonType::STRING,
157         true,
158         g_parseResult,
159         ArrayType::NOT_ARRAY);
160     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
161         jsonObjectEnd,
162         INSIGHT_INTENT_DOMAIN,
163         insightIntentInfo.intentDomain,
164         JsonType::STRING,
165         true,
166         g_parseResult,
167         ArrayType::NOT_ARRAY);
168     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
169         jsonObjectEnd,
170         INSIGHT_INTENT_VERSION,
171         insightIntentInfo.intentVersion,
172         JsonType::STRING,
173         true,
174         g_parseResult,
175         ArrayType::NOT_ARRAY);
176     AppExecFwk::GetValueIfFindKey<std::string>(jsonObject,
177         jsonObjectEnd,
178         INSIGHT_INTENT_SRC_ENTRY,
179         insightIntentInfo.srcEntry,
180         JsonType::STRING,
181         true,
182         g_parseResult,
183         ArrayType::NOT_ARRAY);
184     AppExecFwk::GetValueIfFindKey<UIAbilityProfileInfo>(jsonObject,
185         jsonObjectEnd,
186         INSIGHT_INTENT_UI_ABILITY,
187         insightIntentInfo.uiAbilityProfileInfo,
188         JsonType::OBJECT,
189         false,
190         g_parseResult,
191         ArrayType::NOT_ARRAY);
192     AppExecFwk::GetValueIfFindKey<UIExtensionProfileInfo>(jsonObject,
193         jsonObjectEnd,
194         INSIGHT_INTENT_UI_EXTENSION,
195         insightIntentInfo.uiExtensionProfileInfo,
196         JsonType::OBJECT,
197         false,
198         g_parseResult,
199         ArrayType::NOT_ARRAY);
200     AppExecFwk::GetValueIfFindKey<ServiceExtensionProfileInfo>(jsonObject,
201         jsonObjectEnd,
202         INSIGHT_INTENT_SERVICE_EXTENSION,
203         insightIntentInfo.serviceExtensionProfileInfo,
204         JsonType::OBJECT,
205         false,
206         g_parseResult,
207         ArrayType::NOT_ARRAY);
208     AppExecFwk::GetValueIfFindKey<FormProfileInfo>(jsonObject,
209         jsonObjectEnd,
210         INSIGHT_INTENT_FORM,
211         insightIntentInfo.formProfileInfo,
212         JsonType::OBJECT,
213         false,
214         g_parseResult,
215         ArrayType::NOT_ARRAY);
216 }
217 
from_json(const nlohmann::json & jsonObject,InsightIntentProfileInfoVec & infos)218 void from_json(const nlohmann::json &jsonObject, InsightIntentProfileInfoVec &infos)
219 {
220     const auto &jsonObjectEnd = jsonObject.end();
221     AppExecFwk::GetValueIfFindKey<std::vector<InsightIntentProfileInfo>>(jsonObject,
222         jsonObjectEnd,
223         INSIGHT_INTENTS,
224         infos.insightIntents,
225         JsonType::ARRAY,
226         false,
227         g_parseResult,
228         ArrayType::OBJECT);
229 }
230 
TransformToInsightIntentInfo(const InsightIntentProfileInfo & insightIntent,InsightIntentInfo & info)231 bool TransformToInsightIntentInfo(const InsightIntentProfileInfo &insightIntent, InsightIntentInfo &info)
232 {
233     if (insightIntent.intentName.empty()) {
234         TAG_LOGE(AAFwkTag::INTENT, "Intent name is empty");
235         return false;
236     }
237 
238     info.intentName = insightIntent.intentName;
239     info.intentDomain = insightIntent.intentDomain;
240     info.intentVersion = insightIntent.intentVersion;
241     info.srcEntry = insightIntent.srcEntry;
242 
243     info.uiAbilityIntentInfo.abilityName = insightIntent.uiAbilityProfileInfo.abilityName;
244     for (const auto &executeMode: insightIntent.uiAbilityProfileInfo.supportExecuteMode) {
245         auto mode = std::find_if(std::begin(executeModeMap), std::end(executeModeMap),
246             [&executeMode](const auto &item) {
247                 return item.first == executeMode;
248             });
249         if (mode == executeModeMap.end()) {
250             continue;
251         }
252         info.uiAbilityIntentInfo.supportExecuteMode.emplace_back(mode->second);
253     }
254 
255     info.uiExtensionIntentInfo.abilityName = insightIntent.uiExtensionProfileInfo.abilityName;
256     info.serviceExtensionIntentInfo.abilityName = insightIntent.serviceExtensionProfileInfo.abilityName;
257     info.formIntentInfo.abilityName = insightIntent.formProfileInfo.abilityName;
258     info.formIntentInfo.formName = insightIntent.formProfileInfo.formName;
259     return true;
260 }
261 
TransformToInfos(const InsightIntentProfileInfoVec & profileInfos,std::vector<InsightIntentInfo> & intentInfos)262 bool TransformToInfos(const InsightIntentProfileInfoVec &profileInfos, std::vector<InsightIntentInfo> &intentInfos)
263 {
264     TAG_LOGD(AAFwkTag::INTENT, "called");
265     for (const auto &insightIntent : profileInfos.insightIntents) {
266         InsightIntentInfo info;
267         if (!TransformToInsightIntentInfo(insightIntent, info)) {
268             return false;
269         }
270         intentInfos.push_back(info);
271     }
272     return true;
273 }
274 } // namespace
275 
TransformTo(const std::string & profileStr,std::vector<InsightIntentInfo> & intentInfos)276 bool InsightIntentProfile::TransformTo(const std::string &profileStr, std::vector<InsightIntentInfo> &intentInfos)
277 {
278     TAG_LOGD(AAFwkTag::INTENT, "called");
279     auto jsonObject = nlohmann::json::parse(profileStr, nullptr, false);
280     if (jsonObject.is_discarded()) {
281         TAG_LOGE(AAFwkTag::INTENT, "jsonObject is discarded");
282         return false;
283     }
284 
285     InsightIntentProfileInfoVec profileInfos;
286     {
287         std::lock_guard<std::mutex> lock(g_mutex);
288         g_parseResult = ERR_OK;
289         profileInfos = jsonObject.get<InsightIntentProfileInfoVec>();
290         if (g_parseResult != ERR_OK) {
291             TAG_LOGE(AAFwkTag::INTENT, "g_parseResult is %{public}d", g_parseResult);
292             int32_t ret = g_parseResult;
293             // need recover parse result to ERR_OK
294             g_parseResult = ERR_OK;
295             return ret;
296         }
297     }
298 
299     return TransformToInfos(profileInfos, intentInfos);
300 }
301 } // namespace AbilityRuntime
302 } // namespace OHOS
303