• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <cinttypes>
19 
20 #include "ability_manager_errors.h"
21 #include "hilog_wrapper.h"
22 #include "insight_intent_execute_callback_interface.h"
23 #include "insight_intent_utils.h"
24 #include "permission_verification.h"
25 #include "want_params_wrapper.h"
26 
27 namespace OHOS {
28 namespace AAFwk {
29 namespace {
30 constexpr size_t INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE = 256;
31 constexpr char EXECUTE_INSIGHT_INTENT_PERMISSION[] = "ohos.permission.EXECUTE_INSIGHT_INTENT";
32 }
33 using namespace AppExecFwk;
34 
OnRemoteDied(const wptr<OHOS::IRemoteObject> & remote)35 void InsightIntentExecuteRecipient::OnRemoteDied(const wptr<OHOS::IRemoteObject> &remote)
36 {
37     HILOG_DEBUG("InsightIntentExecuteRecipient OnRemoteDied, %{public}" PRIu64, intentId_);
38     auto object = remote.promote();
39     if (object == nullptr) {
40         HILOG_ERROR("remote object is nullptr");
41         return;
42     }
43     DelayedSingleton<InsightIntentExecuteManager>::GetInstance()->RemoteDied(intentId_);
44 }
45 
46 InsightIntentExecuteManager::InsightIntentExecuteManager() = default;
47 
48 InsightIntentExecuteManager::~InsightIntentExecuteManager() = default;
49 
CheckAndUpdateParam(uint64_t key,const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param)50 int32_t InsightIntentExecuteManager::CheckAndUpdateParam(uint64_t key, const sptr<IRemoteObject> &callerToken,
51     const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> &param)
52 {
53     int32_t result = CheckCallerPermission();
54     if (result != ERR_OK) {
55         return result;
56     }
57     if (callerToken == nullptr) {
58         HILOG_ERROR("callerToken is nullptr");
59         return ERR_INVALID_VALUE;
60     }
61     if (param == nullptr) {
62         HILOG_ERROR("param is nullptr");
63         return ERR_INVALID_VALUE;
64     }
65     if (param->bundleName_.empty() || param->moduleName_.empty() || param->abilityName_.empty() ||
66         param->insightIntentName_.empty()) {
67         HILOG_ERROR("invalid param");
68         return ERR_INVALID_VALUE;
69     }
70     uint64_t intentId = 0;
71     result = AddRecord(key, callerToken, param->bundleName_, intentId);
72     if (result != ERR_OK) {
73         return result;
74     }
75 
76     param->insightIntentId_ = intentId;
77     return ERR_OK;
78 }
79 
CheckAndUpdateWant(Want & want,ExecuteMode executeMode)80 int32_t InsightIntentExecuteManager::CheckAndUpdateWant(Want &want, ExecuteMode executeMode)
81 {
82     int32_t result = IsValidCall(want);
83     if (result != ERR_OK) {
84         return result;
85     }
86     uint64_t intentId = 0;
87     ElementName elementName = want.GetElement();
88     result = AddRecord(0, nullptr, want.GetBundle(), intentId);
89     if (result != ERR_OK) {
90         return result;
91     }
92     auto srcEntry = AbilityRuntime::InsightIntentUtils::GetSrcEntry(elementName.GetBundleName(),
93         elementName.GetModuleName(), want.GetStringParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME));
94     if (srcEntry.empty()) {
95         HILOG_ERROR("Insight intent srcEntry invalid.");
96         return ERR_INVALID_VALUE;
97     }
98     want.SetParam(INSIGHT_INTENT_SRC_ENTRY, srcEntry);
99     want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_ID, std::to_string(intentId));
100     want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_MODE, executeMode);
101     HILOG_DEBUG("check done. insightIntentId: %{public}" PRIu64, intentId);
102     return ERR_OK;
103 }
104 
AddRecord(uint64_t key,const sptr<IRemoteObject> & callerToken,const std::string & bundleName,uint64_t & intentId)105 int32_t InsightIntentExecuteManager::AddRecord(uint64_t key, const sptr<IRemoteObject> &callerToken,
106     const std::string &bundleName, uint64_t &intentId)
107 {
108     std::lock_guard<ffrt::mutex> lock(mutex_);
109     intentId = ++intentIdCount_;
110     auto record = std::make_shared<InsightIntentExecuteRecord>();
111     record->key = key;
112     record->state = InsightIntentExecuteState::EXECUTING;
113     record->callerToken = callerToken;
114     record->bundleName = bundleName;
115     if (callerToken != nullptr) {
116         record->deathRecipient = sptr<InsightIntentExecuteRecipient>::MakeSptr(intentId);
117         callerToken->AddDeathRecipient(record->deathRecipient);
118     }
119 
120     // replace
121     records_[intentId] = record;
122     if (intentId > INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE) {
123         // save the latest INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE records
124         records_.erase(intentId - INSIGHT_INTENT_EXECUTE_RECORDS_MAX_SIZE);
125     }
126     HILOG_DEBUG("init done, records_ size: %{public}zu", records_.size());
127     return ERR_OK;
128 }
129 
RemoveExecuteIntent(uint64_t intentId)130 int32_t InsightIntentExecuteManager::RemoveExecuteIntent(uint64_t intentId)
131 {
132     std::lock_guard<ffrt::mutex> lock(mutex_);
133     records_.erase(intentId);
134     return ERR_OK;
135 }
136 
ExecuteIntentDone(uint64_t intentId,int32_t resultCode,const AppExecFwk::InsightIntentExecuteResult & result)137 int32_t InsightIntentExecuteManager::ExecuteIntentDone(uint64_t intentId, int32_t resultCode,
138     const AppExecFwk::InsightIntentExecuteResult &result)
139 {
140     std::lock_guard<ffrt::mutex> lock(mutex_);
141     auto findResult = records_.find(intentId);
142     if (findResult == records_.end()) {
143         HILOG_ERROR("intent not found, id: %{public}" PRIu64, intentId);
144         return ERR_INVALID_VALUE;
145     }
146 
147     std::shared_ptr<InsightIntentExecuteRecord> record = findResult->second;
148     if (record == nullptr) {
149         HILOG_ERROR("intent record is null, id: %{public}" PRIu64, intentId);
150         return ERR_INVALID_VALUE;
151     }
152 
153     HILOG_DEBUG("callback start, id:%{public}" PRIu64, intentId);
154     if (record->state != InsightIntentExecuteState::EXECUTING) {
155         HILOG_WARN("Insight intent execute state is not EXECUTING, id:%{public}" PRIu64, intentId);
156         return ERR_INVALID_OPERATION;
157     }
158     record->state = InsightIntentExecuteState::EXECUTE_DONE;
159     sptr<IInsightIntentExecuteCallback> remoteCallback = iface_cast<IInsightIntentExecuteCallback>(record->callerToken);
160     if (remoteCallback == nullptr) {
161         HILOG_ERROR("Failed to get IIntentExecuteCallback");
162         return ERR_INVALID_VALUE;
163     }
164     remoteCallback->OnExecuteDone(record->key, resultCode, result);
165     if (record->callerToken != nullptr) {
166         record->callerToken->RemoveDeathRecipient(record->deathRecipient);
167         record->callerToken = nullptr;
168     }
169     HILOG_DEBUG("execute done, records_ size: %{public}zu", records_.size());
170     return ERR_OK;
171 }
172 
RemoteDied(uint64_t intentId)173 int32_t InsightIntentExecuteManager::RemoteDied(uint64_t intentId)
174 {
175     std::lock_guard<ffrt::mutex> lock(mutex_);
176     auto result = records_.find(intentId);
177     if (result == records_.end()) {
178         HILOG_ERROR("intent not found, id: %{public}" PRIu64, intentId);
179         return ERR_INVALID_VALUE;
180     }
181     if (result->second == nullptr) {
182         HILOG_ERROR("intent record is null, id: %{public}" PRIu64, intentId);
183         return ERR_INVALID_VALUE;
184     }
185     result->second->callerToken = nullptr;
186     result->second->state = InsightIntentExecuteState::REMOTE_DIED;
187     return ERR_OK;
188 }
189 
GetBundleName(uint64_t intentId,std::string & bundleName) const190 int32_t InsightIntentExecuteManager::GetBundleName(uint64_t intentId, std::string &bundleName) const
191 {
192     std::lock_guard<ffrt::mutex> lock(mutex_);
193     auto result = records_.find(intentId);
194     if (result == records_.end()) {
195         HILOG_ERROR("intent not found, id: %{public}" PRIu64, intentId);
196         return ERR_INVALID_VALUE;
197     }
198     if (result->second == nullptr) {
199         HILOG_ERROR("intent record is null, id: %{public}" PRIu64, intentId);
200         return ERR_INVALID_VALUE;
201     }
202     bundleName = result->second->bundleName;
203     return ERR_OK;
204 }
205 
GenerateWant(const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> & param,Want & want)206 int32_t InsightIntentExecuteManager::GenerateWant(
207     const std::shared_ptr<AppExecFwk::InsightIntentExecuteParam> &param, Want &want)
208 {
209     if (param == nullptr) {
210         HILOG_ERROR("param is nullptr");
211         return ERR_INVALID_VALUE;
212     }
213     want.SetElementName("", param->bundleName_, param->abilityName_, param->moduleName_);
214 
215     if (param->insightIntentParam_ != nullptr) {
216         sptr<AAFwk::IWantParams> pExecuteParams = WantParamWrapper::Box(*param->insightIntentParam_);
217         if (pExecuteParams != nullptr) {
218             WantParams wantParams;
219             wantParams.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_PARAM, pExecuteParams);
220             want.SetParams(wantParams);
221         }
222     }
223 
224     auto srcEntry = AbilityRuntime::InsightIntentUtils::GetSrcEntry(param->bundleName_, param->moduleName_,
225         param->insightIntentName_);
226     if (srcEntry.empty()) {
227         HILOG_ERROR("Insight intent srcEntry invalid.");
228         return ERR_INVALID_VALUE;
229     }
230     want.SetParam(INSIGHT_INTENT_SRC_ENTRY, srcEntry);
231 
232     want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME, param->insightIntentName_);
233     want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_MODE, param->executeMode_);
234     want.SetParam(INSIGHT_INTENT_EXECUTE_PARAM_ID, std::to_string(param->insightIntentId_));
235     return ERR_OK;
236 }
237 
IsValidCall(const Want & want)238 int32_t InsightIntentExecuteManager::IsValidCall(const Want &want)
239 {
240     std::string insightIntentName = want.GetStringParam(INSIGHT_INTENT_EXECUTE_PARAM_NAME);
241     if (insightIntentName.empty()) {
242         HILOG_ERROR("insightIntentName is empty");
243         return ERR_INVALID_VALUE;
244     }
245     HILOG_DEBUG("insightIntentName: %{public}s", insightIntentName.c_str());
246 
247     int32_t ret = CheckCallerPermission();
248     if (ret != ERR_OK) {
249         return ret;
250     }
251     return ERR_OK;
252 }
253 
CheckCallerPermission()254 int32_t InsightIntentExecuteManager::CheckCallerPermission()
255 {
256     bool isSystemAppCall = PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI();
257     if (!isSystemAppCall) {
258         HILOG_ERROR("The caller is not system-app, can not use system-api");
259         return ERR_NOT_SYSTEM_APP;
260     }
261 
262     bool isCallingPerm = PermissionVerification::GetInstance()->VerifyCallingPermission(
263         EXECUTE_INSIGHT_INTENT_PERMISSION);
264     if (!isCallingPerm) {
265         HILOG_ERROR("Permission %{public}s verification failed", EXECUTE_INSIGHT_INTENT_PERMISSION);
266         return ERR_PERMISSION_DENIED;
267     }
268     return ERR_OK;
269 }
270 } // namespace AAFwk
271 } // namespace OHOS
272