• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &param, 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> &param, 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> &param,
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> &param)
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> &param,
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> &param,
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> &param,
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> &param,
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