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_execute_manager.h"
17
18 #include "ability_config.h"
19 #include "ability_util.h"
20 #include "ability_manager_errors.h"
21 #include "extract_insight_intent_profile.h"
22 #include "hilog_tag_wrapper.h"
23 #include "insight_intent_execute_callback_interface.h"
24 #include "insight_intent_db_cache.h"
25 #include "insight_intent_utils.h"
26 #include "permission_verification.h"
27 #include "want_params_wrapper.h"
28 #include "time_util.h"
29 #include "res_sched_util.h"
30
31 namespace OHOS {
32 namespace AAFwk {
33 namespace {
34 constexpr size_t INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE = 256;
35 constexpr char EXECUTE_INSIGHT_INTENT_PERMISSION[] = "ohos.permission.EXECUTE_INSIGHT_INTENT";
36 constexpr char PERMISSION_GET_BUNDLE_INFO_PRIVILEGED[] = "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED";
37 constexpr int32_t OPERATION_DURATION = 10000;
38 }
39 using namespace AppExecFwk;
40 using InsightIntentType = AbilityRuntime::InsightIntentType;
41 using ExtractInsightIntentInfo = AbilityRuntime::ExtractInsightIntentInfo;
42 using InsightIntentPageInfo = AbilityRuntime::InsightIntentPageInfo;
43 using InsightIntentFunctionInfo = AbilityRuntime::InsightIntentFunctionInfo;
44 using InsightIntentEntryInfo = AbilityRuntime::InsightIntentEntryInfo;
45
OnRemoteDied(const wptr<OHOS::IRemoteObject> & remote)46 void InsightIntentExecuteRecipient::OnRemoteDied(const wptr<OHOS::IRemoteObject> &remote)
47 {
48 TAG_LOGD(AAFwkTag::INTENT, "InsightIntentExecuteRecipient OnRemoteDied, %{public}" PRIu64, intentId_);
49 auto object = remote.promote();
50 if (object == nullptr) {
51 TAG_LOGE(AAFwkTag::INTENT, "null object");
52 return;
53 }
54 DelayedSingleton<InsightIntentExecuteManager>::GetInstance()->RemoteDied(intentId_);
55 }
56
57 InsightIntentExecuteManager::InsightIntentExecuteManager() = default;
58
59 InsightIntentExecuteManager::~InsightIntentExecuteManager() = default;
60
CheckAndUpdateParam(uint64_t key,const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,std::string callerBundleName,const bool ignoreAbilityName)61 int32_t InsightIntentExecuteManager::CheckAndUpdateParam(uint64_t key, const sptr<IRemoteObject> &callerToken,
62 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m, std::string callerBundleName,
63 const bool ignoreAbilityName)
64 {
65 int32_t result = CheckCallerPermission();
66 if (result != ERR_OK) {
67 return result;
68 }
69 if (callerToken == nullptr) {
70 TAG_LOGE(AAFwkTag::INTENT, "null callerToken");
71 return ERR_INVALID_VALUE;
72 }
73 if (param == nullptr) {
74 TAG_LOGE(AAFwkTag::INTENT, "null param");
75 return ERR_INVALID_VALUE;
76 }
77 if (param->bundleName_.empty() || param->moduleName_.empty() ||
78 (!ignoreAbilityName && param->abilityName_.empty()) || param->insightIntentName_.empty()) {
79 TAG_LOGE(AAFwkTag::INTENT, "invalid param");
80 return ERR_INVALID_VALUE;
81 }
82 uint64_t intentId = 0;
83 result = AddRecord(key, callerToken, param->bundleName_, intentId, callerBundleName);
84 if (result != ERR_OK) {
85 return result;
86 }
87
88 param->insightIntentId_ = intentId;
89 return ERR_OK;
90 }
91
CheckAndUpdateWant(Want & want,ExecuteMode executeMode,std::string callerBundleName)92 int32_t InsightIntentExecuteManager::CheckAndUpdateWant(Want &want, ExecuteMode executeMode,
93 std::string callerBundleName)
94 {
95 auto uriVec = want.GetStringArrayParam(AbilityConfig::PARAMS_STREAM);
96 auto uriVecTemp = want.GetStringArrayParam(INSIGHT_INTENT_EXECUTE_PARAM_URI);
97 uriVec.insert(uriVec.begin(), uriVecTemp.begin(), uriVecTemp.end());
98 want.SetParam(AbilityConfig::PARAMS_STREAM, uriVec);
99 auto myflags = want.GetIntParam(INSIGHT_INTENT_EXECUTE_PARAM_FLAGS, 0);
100 myflags |= want.GetFlags();
101 want.SetFlags(myflags);
102
103 int32_t result = IsValidCall(want);
104 if (result != ERR_OK) {
105 return result;
106 }
107 uint64_t intentId = 0;
108 ElementName elementName = want.GetElement();
109 result = AddRecord(0, nullptr, want.GetBundle(), intentId, callerBundleName);
110 if (result != ERR_OK) {
111 return result;
112 }
113
114 std::string srcEntry;
115 std::string intentName = want.GetStringParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME);
116 auto ret = AbilityRuntime::InsightIntentUtils::GetSrcEntry(elementName, intentName, executeMode, srcEntry);
117 if (ret != ERR_OK || srcEntry.empty()) {
118 TAG_LOGW(AAFwkTag::INTENT, "empty srcEntry");
119 if (UpdateEntryDecoratorParams(want, executeMode) != ERR_OK) {
120 return ERR_INVALID_VALUE;
121 }
122 }
123
124 want.SetParam(INSIGHT_INTENT_SRC_ENTRY, srcEntry);
125 want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_ID, std::to_string(intentId));
126 want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_MODE, executeMode);
127 TAG_LOGD(AAFwkTag::INTENT, "check done. insightIntentId: %{public}" PRIu64, intentId);
128 return ERR_OK;
129 }
130
UpdateEntryDecoratorParams(Want & want,ExecuteMode executeMode)131 int32_t InsightIntentExecuteManager::UpdateEntryDecoratorParams(Want &want, ExecuteMode executeMode)
132 {
133 std::string intentName = want.GetStringParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME);
134 ExtractInsightIntentInfo info;
135 const int32_t userId = IPCSkeleton::GetCallingUid() / AppExecFwk::Constants::BASE_USER_RANGE;
136 DelayedSingleton<AbilityRuntime::InsightIntentDbCache>::GetInstance()->GetInsightIntentInfo(
137 want.GetBundle(), want.GetModuleName(), intentName, userId, info);
138 if (info.genericInfo.decoratorType != AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_ENTRY) {
139 TAG_LOGW(AAFwkTag::INTENT, "decorator %{public}s misMatch", info.genericInfo.decoratorType.c_str());
140 return ERR_INVALID_VALUE;
141 }
142 InsightIntentType type = InsightIntentType::DECOR_ENTRY;
143 want.SetParam(INSIGHT_INTENT_DECORATOR_TYPE, static_cast<int>(type));
144 std::string srcEntrance = info.decoratorFile;
145 want.SetParam(INSIGHT_INTENT_SRC_ENTRANCE, srcEntrance);
146 std::vector<ExecuteMode> supportModes = info.genericInfo.get<InsightIntentEntryInfo>().executeMode;
147 TAG_LOGD(AAFwkTag::INTENT, "support mode size %{public}zu", supportModes.size());
148 bool found = std::find(supportModes.begin(), supportModes.end(), executeMode) != supportModes.end();
149 if (!found) {
150 TAG_LOGE(AAFwkTag::INTENT, "execute mode mismatch");
151 return ERR_INVALID_VALUE;
152 }
153 if (want.GetElement().GetAbilityName() != info.genericInfo.get<InsightIntentEntryInfo>().abilityName) {
154 TAG_LOGE(AAFwkTag::INTENT, "ability name mismatch");
155 return ERR_INVALID_VALUE;
156 }
157 return ERR_OK;
158 }
159
AddRecord(uint64_t key,const sptr<IRemoteObject> & callerToken,const std::string & bundleName,uint64_t & intentId,const std::string & callerBundleName)160 int32_t InsightIntentExecuteManager::AddRecord(uint64_t key, const sptr<IRemoteObject> &callerToken,
161 const std::string &bundleName, uint64_t &intentId, const std::string &callerBundleName)
162 {
163 std::lock_guard<ffrt::mutex> lock(mutex_);
164 intentId = ++intentIdCount_;
165 auto record = std::make_shared<InsightIntentExecuteRecord>();
166 record->key = key;
167 record->state = InsightIntentExecuteState::EXECUTING;
168 record->callerToken = callerToken;
169 record->bundleName = bundleName;
170 record->callerBundleName = callerBundleName;
171 if (callerToken != nullptr) {
172 record->deathRecipient = sptr<InsightIntentExecuteRecipient>::MakeSptr(intentId);
173 callerToken->AddDeathRecipient(record->deathRecipient);
174 }
175
176 // replace
177 records_[intentId] = record;
178 if (intentId > INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE) {
179 // save the latest INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE records
180 records_.erase(intentId - INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE);
181 }
182 TAG_LOGI(AAFwkTag::INTENT, "init done, records_ size: %{public}zu", records_.size());
183 return ERR_OK;
184 }
185
RemoveExecuteIntent(uint64_t intentId)186 int32_t InsightIntentExecuteManager::RemoveExecuteIntent(uint64_t intentId)
187 {
188 std::lock_guard<ffrt::mutex> lock(mutex_);
189 records_.erase(intentId);
190 TAG_LOGI(AAFwkTag::INTENT, "remove intentId: %{public}" PRIu64 ", records_ size: %{public}zu",
191 intentId, records_.size());
192 return ERR_OK;
193 }
194
ExecuteIntentDone(uint64_t intentId,int32_t resultCode,const AppExecFwk::InsightIntentExecuteResult & result)195 int32_t InsightIntentExecuteManager::ExecuteIntentDone(uint64_t intentId, int32_t resultCode,
196 const AppExecFwk::InsightIntentExecuteResult &result)
197 {
198 TAG_LOGI(AAFwkTag::INTENT, "execute start, intentId: %{public}" PRIu64 ", records_ size: %{public}zu",
199 intentId, records_.size());
200 std::lock_guard<ffrt::mutex> lock(mutex_);
201 EventInfo eventInfo;
202 auto findResult = records_.find(intentId);
203 if (findResult == records_.end()) {
204 TAG_LOGE(AAFwkTag::INTENT, "intent not found, id: %{public}" PRIu64, intentId);
205 eventInfo.errReason = "intent not found";
206 SendIntentReport(eventInfo, INTENT_NOT_EXIST);
207 return ERR_INVALID_VALUE;
208 }
209
210 std::shared_ptr<InsightIntentExecuteRecord> record = findResult->second;
211 if (record == nullptr) {
212 TAG_LOGE(AAFwkTag::INTENT, "null record, id: %{public}" PRIu64, intentId);
213 return ERR_INVALID_VALUE;
214 }
215
216 TAG_LOGD(AAFwkTag::INTENT, "callback start, id:%{public}" PRIu64, intentId);
217 if (record->state != InsightIntentExecuteState::EXECUTING) {
218 TAG_LOGW(AAFwkTag::INTENT, "insight intent execute state is not EXECUTING, id:%{public}" PRIu64, intentId);
219 eventInfo.errReason = "intent state error";
220 SendIntentReport(eventInfo, INTENT_STATE_NOT_EXECUTING);
221 return ERR_INVALID_OPERATION;
222 }
223 record->state = InsightIntentExecuteState::EXECUTE_DONE;
224 sptr<IInsightIntentExecuteCallback> remoteCallback = iface_cast<IInsightIntentExecuteCallback>(record->callerToken);
225 if (remoteCallback == nullptr) {
226 TAG_LOGE(AAFwkTag::INTENT, "intentExecuteCallback empty,"
227 " intentId: %{public}" PRIu64 ", records_ size: %{public}zu", intentId, records_.size());
228 return ERR_INVALID_VALUE;
229 }
230 remoteCallback->OnExecuteDone(record->key, resultCode, result);
231 if (record->callerToken != nullptr) {
232 record->callerToken->RemoveDeathRecipient(record->deathRecipient);
233 record->callerToken = nullptr;
234 }
235 TAG_LOGI(AAFwkTag::INTENT, "execute done, intentId: %{public}" PRIu64 ", records_ size: %{public}zu",
236 intentId, records_.size());
237 return ERR_OK;
238 }
239
RemoteDied(uint64_t intentId)240 int32_t InsightIntentExecuteManager::RemoteDied(uint64_t intentId)
241 {
242 std::lock_guard<ffrt::mutex> lock(mutex_);
243 auto result = records_.find(intentId);
244 if (result == records_.end()) {
245 TAG_LOGE(AAFwkTag::INTENT, "intent not found, id: %{public}" PRIu64, intentId);
246 return ERR_INVALID_VALUE;
247 }
248 if (result->second == nullptr) {
249 TAG_LOGE(AAFwkTag::INTENT, "null intent record , id: %{public}" PRIu64, intentId);
250 return ERR_INVALID_VALUE;
251 }
252 result->second->callerToken = nullptr;
253 result->second->state = InsightIntentExecuteState::REMOTE_DIED;
254 return ERR_OK;
255 }
256
GetBundleName(uint64_t intentId,std::string & bundleName) const257 int32_t InsightIntentExecuteManager::GetBundleName(uint64_t intentId, std::string &bundleName) const
258 {
259 std::lock_guard<ffrt::mutex> lock(mutex_);
260 auto result = records_.find(intentId);
261 if (result == records_.end()) {
262 TAG_LOGE(AAFwkTag::INTENT, "intent not found, id: %{public}" PRIu64, intentId);
263 return ERR_INVALID_VALUE;
264 }
265 if (result->second == nullptr) {
266 TAG_LOGE(AAFwkTag::INTENT, "null intent record,id: %{public}" PRIu64, intentId);
267 return ERR_INVALID_VALUE;
268 }
269 bundleName = result->second->bundleName;
270 return ERR_OK;
271 }
272
GetCallerBundleName(uint64_t intentId,std::string & callerBundleName) const273 int32_t InsightIntentExecuteManager::GetCallerBundleName(uint64_t intentId, std::string &callerBundleName) const
274 {
275 std::lock_guard<ffrt::mutex> lock(mutex_);
276 auto result = records_.find(intentId);
277 if (result == records_.end()) {
278 TAG_LOGE(AAFwkTag::INTENT, "intent not found, id: %{public}" PRIu64, intentId);
279 return ERR_INVALID_VALUE;
280 }
281 if (result->second == nullptr) {
282 TAG_LOGE(AAFwkTag::INTENT, "null intent record,id: %{public}" PRIu64, intentId);
283 return ERR_INVALID_VALUE;
284 }
285 callerBundleName = result->second->callerBundleName;
286 return ERR_OK;
287 }
288
AddWantUirsAndFlagsFromParam(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,Want & want)289 int32_t InsightIntentExecuteManager::AddWantUirsAndFlagsFromParam(
290 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m, Want &want)
291 {
292 if (param == nullptr) {
293 TAG_LOGE(AAFwkTag::INTENT, "null param");
294 return ERR_INVALID_VALUE;
295 }
296 if (param->uris_.size() > 0) {
297 auto uriVec = want.GetStringArrayParam(AbilityConfig::PARAMS_STREAM);
298 for (auto &uri : param->uris_) {
299 if (!uri.empty()) {
300 uriVec.insert(uriVec.begin(), uri);
301 }
302 }
303 want.SetParam(AbilityConfig::PARAMS_STREAM, uriVec);
304 auto flags = want.GetFlags();
305 flags |= param->flags_;
306 want.SetFlags(flags);
307 }
308 return ERR_OK;
309 }
310
UpdateFuncDecoratorParams(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,ExtractInsightIntentInfo & info,Want & want)311 int32_t InsightIntentExecuteManager::UpdateFuncDecoratorParams(
312 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m,
313 ExtractInsightIntentInfo &info, Want &want)
314 {
315 if (param->executeMode_ != AppExecFwk::ExecuteMode::UI_ABILITY_BACKGROUND) {
316 TAG_LOGE(AAFwkTag::INTENT, "invalid execute mode %{public}d", param->executeMode_);
317 return ERR_INVALID_VALUE;
318 }
319
320 if (param->abilityName_.empty()) {
321 param->abilityName_ = GetMainElementName(param);
322 }
323 if (param->abilityName_.empty()) {
324 TAG_LOGE(AAFwkTag::INTENT, "ability name empty");
325 return ERR_INVALID_VALUE;
326 }
327 want.SetElementName("", param->bundleName_, param->abilityName_, param->moduleName_);
328
329 std::string srcEntrance = info.decoratorFile;
330 want.SetParam(INSIGHT_INTENT_SRC_ENTRANCE, srcEntrance);
331
332 std::string className = info.decoratorClass;
333 std::string methodName = info.genericInfo.get<InsightIntentFunctionInfo>().functionName;
334 std::vector<std::string> methodParams = info.genericInfo.get<InsightIntentFunctionInfo>().functionParams;
335 if (className.empty() || methodName.empty()) {
336 TAG_LOGE(AAFwkTag::INTENT, "invalid func param");
337 return ERR_INVALID_VALUE;
338 }
339 want.SetParam(INSIGHT_INTENT_FUNC_PARAM_CLASSNAME, className);
340 want.SetParam(INSIGHT_INTENT_FUNC_PARAM_METHODNAME, methodName);
341 want.SetParam(INSIGHT_INTENT_FUNC_PARAM_METHODPARAMS, methodParams);
342 return ERR_OK;
343 }
344
GetMainElementName(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param)345 std::string InsightIntentExecuteManager::GetMainElementName(
346 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m)
347 {
348 auto bms = AbilityUtil::GetBundleManagerHelper();
349 if (bms == nullptr) {
350 TAG_LOGE(AAFwkTag::INTENT, "get bms failed");
351 return "";
352 }
353
354 const int32_t userId = IPCSkeleton::GetCallingUid() / AppExecFwk::Constants::BASE_USER_RANGE;
355 std::vector<AppExecFwk::AbilityInfo> abilityInfos;
356 if (IN_PROCESS_CALL(bms->GetLauncherAbilityInfoSync(param->bundleName_, userId, abilityInfos)) != ERR_OK) {
357 TAG_LOGE(AAFwkTag::INTENT, "get launcher ability info failed");
358 return "";
359 }
360
361 for (auto &info: abilityInfos) {
362 TAG_LOGD(AAFwkTag::INTENT, "moduleName %{public}s", param->moduleName_.c_str());
363 if (info.moduleName == param->moduleName_) {
364 TAG_LOGI(AAFwkTag::INTENT, "ability matched %{public}s", info.name.c_str());
365 return info.name;
366 }
367 }
368
369 return "";
370 }
371
UpdatePageDecoratorParams(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,ExtractInsightIntentInfo & info,Want & want)372 int32_t InsightIntentExecuteManager::UpdatePageDecoratorParams(
373 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m,
374 ExtractInsightIntentInfo &info, Want &want)
375 {
376 if (param->executeMode_ != AppExecFwk::ExecuteMode::UI_ABILITY_FOREGROUND) {
377 TAG_LOGE(AAFwkTag::INTENT, "invalid execute mode %{public}d", param->executeMode_);
378 return ERR_INVALID_VALUE;
379 }
380
381 std::string srcEntrance = info.decoratorFile;
382 want.SetParam(INSIGHT_INTENT_SRC_ENTRANCE, srcEntrance);
383
384 std::string pagePath = info.genericInfo.get<InsightIntentPageInfo>().pagePath;
385 std::string navigationId = info.genericInfo.get<InsightIntentPageInfo>().navigationId;
386 std::string navDestinationName = info.genericInfo.get<InsightIntentPageInfo>().navDestinationName;
387 std::string uiAbilityName = info.genericInfo.get<InsightIntentPageInfo>().uiAbility;
388 if (pagePath.empty() || uiAbilityName != param->abilityName_) {
389 TAG_LOGE(AAFwkTag::INTENT, "invalid page param, pagePath %{public}s, uiability %{public}s, %{public}s",
390 pagePath.c_str(), uiAbilityName.c_str(), param->abilityName_.c_str());
391 return ERR_INVALID_VALUE;
392 }
393 if (uiAbilityName.empty()) {
394 uiAbilityName = GetMainElementName(param);
395 }
396 if (uiAbilityName.empty()) {
397 TAG_LOGE(AAFwkTag::INTENT, "ability name empty");
398 return ERR_INVALID_VALUE;
399 }
400 param->abilityName_ = uiAbilityName;
401 want.SetElementName("", param->bundleName_, param->abilityName_, param->moduleName_);
402 want.SetParam(INSIGHT_INTENT_PAGE_PARAM_PAGEPATH, pagePath);
403 want.SetParam(INSIGHT_INTENT_PAGE_PARAM_NAVIGATIONID, navigationId);
404 want.SetParam(INSIGHT_INTENT_PAGE_PARAM_NAVDESTINATIONNAME, navDestinationName);
405 return ERR_OK;
406 }
407
UpdateEntryDecoratorParams(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,ExtractInsightIntentInfo & info,Want & want)408 int32_t InsightIntentExecuteManager::UpdateEntryDecoratorParams(
409 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m,
410 ExtractInsightIntentInfo &info, Want &want)
411 {
412 TAG_LOGD(AAFwkTag::INTENT, "update entry params");
413 std::string srcEntrance = info.decoratorFile;
414 want.SetParam(INSIGHT_INTENT_SRC_ENTRANCE, srcEntrance);
415 auto executeMode = param->executeMode_;
416 std::vector<ExecuteMode> supportModes = info.genericInfo.get<InsightIntentEntryInfo>().executeMode;
417 TAG_LOGD(AAFwkTag::INTENT, "support mode size %{public}zu", supportModes.size());
418 bool found = std::find(supportModes.begin(), supportModes.end(), executeMode) != supportModes.end();
419 if (!found) {
420 TAG_LOGE(AAFwkTag::INTENT, "execute mode %{public}d mismatch", executeMode);
421 return ERR_INVALID_VALUE;
422 }
423 if (param->abilityName_ != info.genericInfo.get<InsightIntentEntryInfo>().abilityName) {
424 TAG_LOGE(AAFwkTag::INTENT, "ability name mismatch");
425 return ERR_INVALID_VALUE;
426 }
427 return ERR_OK;
428 }
429
CheckAndUpdateDecoratorParams(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,const AbilityRuntime::ExtractInsightIntentGenericInfo & decoratorInfo,Want & want)430 int32_t InsightIntentExecuteManager::CheckAndUpdateDecoratorParams(
431 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m,
432 const AbilityRuntime::ExtractInsightIntentGenericInfo &decoratorInfo,
433 Want &want)
434 {
435 // ExtractInsightIntentGenericInfo don't satisfy for now
436 ExtractInsightIntentInfo info;
437 const int32_t userId = IPCSkeleton::GetCallingUid() / AppExecFwk::Constants::BASE_USER_RANGE;
438 DelayedSingleton<AbilityRuntime::InsightIntentDbCache>::GetInstance()->GetInsightIntentInfo(
439 param->bundleName_, param->moduleName_, param->insightIntentName_, userId, info);
440
441 InsightIntentType type = InsightIntentType::DECOR_NONE;
442 std::string decoratorType = info.genericInfo.decoratorType;
443 TAG_LOGD(AAFwkTag::INTENT, "intentName %{public}s, decoratorType %{public}s", param->insightIntentName_.c_str(),
444 decoratorType.c_str());
445 static const std::unordered_map<std::string, InsightIntentType> mapping = {
446 {AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_LINK, InsightIntentType::DECOR_LINK},
447 {AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_PAGE, InsightIntentType::DECOR_PAGE},
448 {AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_ENTRY, InsightIntentType::DECOR_ENTRY},
449 {AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_FUNCTION, InsightIntentType::DECOR_FUNC},
450 {AbilityRuntime::INSIGHT_INTENTS_DECORATOR_TYPE_FORM, InsightIntentType::DECOR_FORM}
451 };
452 auto it = mapping.find(decoratorType);
453 if (it != mapping.end()) {
454 type = it->second;
455 }
456
457 want.SetParam(INSIGHT_INTENT_DECORATOR_TYPE, static_cast<int>(type));
458 TAG_LOGI(AAFwkTag::INTENT, "intentName %{public}s, type %{public}d", param->insightIntentName_.c_str(),
459 static_cast<int8_t>(type));
460 switch (type) {
461 case InsightIntentType::DECOR_FUNC: {
462 return UpdateFuncDecoratorParams(param, info, want);
463 }
464 case InsightIntentType::DECOR_PAGE: {
465 return UpdatePageDecoratorParams(param, info, want);
466 }
467 case InsightIntentType::DECOR_ENTRY: {
468 return UpdateEntryDecoratorParams(param, info, want);
469 }
470 case InsightIntentType::DECOR_NONE:
471 case InsightIntentType::DECOR_LINK:
472 case InsightIntentType::DECOR_FORM:
473 default:
474 break;
475 }
476 return ERR_OK;
477 }
478
GenerateWant(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,const AbilityRuntime::ExtractInsightIntentGenericInfo & decoratorInfo,Want & want)479 int32_t InsightIntentExecuteManager::GenerateWant(
480 const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> ¶m,
481 const AbilityRuntime::ExtractInsightIntentGenericInfo &decoratorInfo,
482 Want &want)
483 {
484 if (param == nullptr) {
485 TAG_LOGE(AAFwkTag::INTENT, "null param");
486 return ERR_INVALID_VALUE;
487 }
488 want.SetElementName("", param->bundleName_, param->abilityName_, param->moduleName_);
489
490 if (param->insightIntentParam_ != nullptr) {
491 sptr<AAFwk::IWantParams> pExecuteParams = WantParamWrapper::Box(*param->insightIntentParam_);
492 if (pExecuteParams != nullptr) {
493 WantParams wantParams;
494 wantParams.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_PARAM, pExecuteParams);
495 want.SetParams(wantParams);
496 }
497 }
498
499 std::string srcEntry;
500 auto ret = AbilityRuntime::InsightIntentUtils::GetSrcEntry(want.GetElement(), param->insightIntentName_,
501 static_cast<AppExecFwk::ExecuteMode>(param->executeMode_), srcEntry);
502 if (!srcEntry.empty()) {
503 want.SetParam(INSIGHT_INTENT_SRC_ENTRY, srcEntry);
504 } else if (decoratorInfo.decoratorType == "" && ret == ERR_INSIGHT_INTENT_GET_PROFILE_FAILED &&
505 param->executeMode_ == AppExecFwk::ExecuteMode::UI_ABILITY_FOREGROUND) {
506 TAG_LOGI(AAFwkTag::INTENT, "insight intent srcEntry invalid, try free install ondemand");
507 std::string startTime = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
508 std::chrono::system_clock::now().time_since_epoch()).count());
509 want.SetParam(Want::PARAM_RESV_START_TIME, startTime);
510 want.AddFlags(Want::FLAG_INSTALL_ON_DEMAND);
511 } else if (decoratorInfo.decoratorType == "") {
512 // decoratorType is empty indicate no decorator
513 TAG_LOGE(AAFwkTag::INTENT, "insight intent srcEntry invalid");
514 return ERR_INVALID_VALUE;
515 }
516
517 want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME, param->insightIntentName_);
518 want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_MODE, param->executeMode_);
519 want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_ID, std::to_string(param->insightIntentId_));
520 if (param->displayId_ != INVALID_DISPLAY_ID) {
521 want.SetParam(Want::PARAM_RESV_DISPLAY_ID, param->displayId_);
522 TAG_LOGD(AAFwkTag::INTENT, "Generate want with displayId: %{public}d", param->displayId_);
523 }
524
525 auto intRet = AddWantUirsAndFlagsFromParam(param, want);
526 if (intRet != ERR_OK) {
527 return intRet;
528 }
529
530 intRet = CheckAndUpdateDecoratorParams(param, decoratorInfo, want);
531 if (intRet != ERR_OK) {
532 // log has print in sub method
533 return intRet;
534 }
535
536 return ERR_OK;
537 }
538
IsValidCall(const Want & want)539 int32_t InsightIntentExecuteManager::IsValidCall(const Want &want)
540 {
541 std::string insightIntentName = want.GetStringParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME);
542 if (insightIntentName.empty()) {
543 TAG_LOGE(AAFwkTag::INTENT, "empty insightIntentName");
544 return ERR_INVALID_VALUE;
545 }
546 TAG_LOGD(AAFwkTag::INTENT, "insightIntentName: %{public}s", insightIntentName.c_str());
547
548 int32_t ret = CheckCallerPermission();
549 if (ret != ERR_OK) {
550 return ret;
551 }
552 return ERR_OK;
553 }
554
CheckCallerPermission()555 int32_t InsightIntentExecuteManager::CheckCallerPermission()
556 {
557 bool isSystemAppCall = PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI();
558 if (!isSystemAppCall) {
559 TAG_LOGE(AAFwkTag::INTENT, "system-api cannot use");
560 return ERR_NOT_SYSTEM_APP;
561 }
562
563 bool isCallingPerm = PermissionVerification::GetInstance()->VerifyCallingPermission(
564 EXECUTE_INSIGHT_INTENT_PERMISSION);
565 if (!isCallingPerm) {
566 TAG_LOGE(AAFwkTag::INTENT, "permission %{public}s verification failed", EXECUTE_INSIGHT_INTENT_PERMISSION);
567 return ERR_PERMISSION_DENIED;
568 }
569 return ERR_OK;
570 }
571
CheckGetInsightIntenInfoPermission()572 int32_t InsightIntentExecuteManager::CheckGetInsightIntenInfoPermission()
573 {
574 bool isSystemAppCall = PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI();
575 if (!isSystemAppCall) {
576 TAG_LOGE(AAFwkTag::INTENT, "system-api cannot use");
577 return ERR_NOT_SYSTEM_APP;
578 }
579
580 bool isCallingPerm = PermissionVerification::GetInstance()->VerifyGetBundleInfoPrivilegedPermission();
581 if (!isCallingPerm) {
582 TAG_LOGE(AAFwkTag::INTENT, "permission %{public}s verification failed", PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
583 return ERR_PERMISSION_DENIED;
584 }
585 return ERR_OK;
586 }
587
SetIntentExemptionInfo(int32_t uid)588 void InsightIntentExecuteManager::SetIntentExemptionInfo(int32_t uid)
589 {
590 std::lock_guard<ffrt::mutex> guard(intentExemptionLock_);
591 std::map<int32_t, int64_t>::iterator iter = intentExemptionDeadlineTime_.find(uid);
592 intentExemptionDeadlineTime_[uid] = AbilityRuntime::TimeUtil::CurrentTimeMillis();
593 }
594
CheckIntentIsExemption(int32_t uid)595 bool InsightIntentExecuteManager::CheckIntentIsExemption(int32_t uid)
596 {
597 std::lock_guard<ffrt::mutex> guard(intentExemptionLock_);
598 if (intentExemptionDeadlineTime_.find(uid) != intentExemptionDeadlineTime_.end()) {
599 if (AbilityRuntime::TimeUtil::CurrentTimeMillis() - INTENT_EXEMPTION_DURATION <=
600 intentExemptionDeadlineTime_[uid]) {
601 TAG_LOGD(AAFwkTag::ABILITYMGR, "exemption check uid:%{public}d", uid);
602 return true;
603 } else {
604 intentExemptionDeadlineTime_.erase(uid);
605 return false;
606 }
607 }
608 return false;
609 }
610
GetAllIntentExemptionInfo() const611 std::map<int32_t, int64_t> InsightIntentExecuteManager::GetAllIntentExemptionInfo() const
612 {
613 std::lock_guard<ffrt::mutex> guard(intentExemptionLock_);
614 return intentExemptionDeadlineTime_;
615 }
616
SendIntentReport(EventInfo & eventInfo,int32_t errCode)617 void InsightIntentExecuteManager::SendIntentReport(EventInfo &eventInfo, int32_t errCode)
618 {
619 eventInfo.errCode = errCode;
620 EventReport::SendExecuteIntentEvent(EventName::EXECUTE_INSIGHT_INTENT_ERROR, HiSysEventType::FAULT, eventInfo);
621 }
622 } // namespace AAFwk
623 } // namespace OHOS
624