1 /*
2 * Copyright (c) 2021-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 "pending_want_record.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "pending_want_manager.h"
20 #include "int_wrapper.h"
21 #include "multi_app_utils.h"
22
23 namespace OHOS {
24 namespace AAFwk {
25 std::string APP_MULTI_INSTANCE{ "ohos.extra.param.key.appInstance" };
26 constexpr int32_t INVALID_UID = -1;
27
PendingWantRecord()28 PendingWantRecord::PendingWantRecord()
29 {}
30
PendingWantRecord(const std::shared_ptr<PendingWantManager> & pendingWantManager,int32_t uid,int32_t callerTokenId,const sptr<IRemoteObject> & callerToken,std::shared_ptr<PendingWantKey> key)31 PendingWantRecord::PendingWantRecord(const std::shared_ptr<PendingWantManager> &pendingWantManager, int32_t uid,
32 int32_t callerTokenId, const sptr<IRemoteObject> &callerToken, std::shared_ptr<PendingWantKey> key)
33 : uid_(uid), callerTokenId_(callerTokenId), callerToken_(callerToken), pendingWantManager_(pendingWantManager),
34 key_(key)
35 {}
36
~PendingWantRecord()37 PendingWantRecord::~PendingWantRecord()
38 {}
39
Send(SenderInfo & senderInfo)40 void PendingWantRecord::Send(SenderInfo &senderInfo)
41 {
42 SenderInner(senderInfo);
43 }
44
RegisterCancelListener(const sptr<IWantReceiver> & receiver)45 void PendingWantRecord::RegisterCancelListener(const sptr<IWantReceiver> &receiver)
46 {
47 std::lock_guard guard(mCancelCallbacksMutex_);
48 if (receiver == nullptr) {
49 return;
50 }
51 mCancelCallbacks_.emplace_back(receiver);
52 }
53
UnregisterCancelListener(const sptr<IWantReceiver> & receiver)54 void PendingWantRecord::UnregisterCancelListener(const sptr<IWantReceiver> &receiver)
55 {
56 std::lock_guard guard(mCancelCallbacksMutex_);
57 if (receiver == nullptr) {
58 return;
59 }
60 if (mCancelCallbacks_.size()) {
61 auto it = std::find(mCancelCallbacks_.cbegin(), mCancelCallbacks_.cend(), receiver);
62 if (it != mCancelCallbacks_.cend()) {
63 mCancelCallbacks_.erase(it);
64 }
65 }
66 }
67
SenderInner(SenderInfo & senderInfo)68 int32_t PendingWantRecord::SenderInner(SenderInfo &senderInfo)
69 {
70 std::lock_guard<ffrt::mutex> locker(lock_);
71 if (canceled_) {
72 if (senderInfo.finishedReceiver != nullptr) {
73 Want want;
74 WantParams wantParams = {};
75 senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "canceled", wantParams, false, false, 0);
76 }
77 TAG_LOGE(AAFwkTag::WANTAGENT, "wantagent has been canceled");
78 return ERR_WANTAGENT_CANCELED;
79 }
80
81 auto pendingWantManager = pendingWantManager_.lock();
82 if (pendingWantManager == nullptr) {
83 TAG_LOGE(AAFwkTag::WANTAGENT, "null pendingWantManager");
84 return ERR_INVALID_VALUE;
85 }
86
87 TAG_LOGI(AAFwkTag::WANTAGENT, "before CancelWantSenderLocked");
88 if (((uint32_t)key_->GetFlags() & (uint32_t)Flags::ONE_TIME_FLAG) != 0) {
89 pendingWantManager->CancelWantSenderLocked(*this, true);
90 }
91
92 Want want;
93 BuildSendWant(senderInfo, want);
94
95 bool sendFinish = (senderInfo.finishedReceiver != nullptr);
96 int32_t res = ExecuteOperation(pendingWantManager, senderInfo, want);
97 TAG_LOGI(AAFwkTag::WANTAGENT, "ExecuteOperation return %{public}d, sendFinish %{public}d", res, sendFinish);
98 if (sendFinish && res != ERR_WANTAGENT_CANCELED) {
99 WantParams wantParams = {};
100 TAG_LOGI(AAFwkTag::WANTAGENT, "start callback");
101 senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "", wantParams, false, false, 0);
102 }
103 if (res != NO_ERROR) {
104 return ERR_INVALID_VALUE;
105 }
106 return res;
107 }
108
ExecuteOperation(std::shared_ptr<PendingWantManager> pendingWantManager,SenderInfo & senderInfo,Want & want)109 int32_t PendingWantRecord::ExecuteOperation(
110 std::shared_ptr<PendingWantManager> pendingWantManager, SenderInfo &senderInfo, Want &want)
111 {
112 TAG_LOGI(AAFwkTag::WANTAGENT, "start ability type:%{public}d, bundleName: %{public}s, ability: %{public}s",
113 key_->GetType(), want.GetBundle().c_str(), want.GetElement().GetAbilityName().c_str());
114 int32_t res = NO_ERROR;
115 switch (key_->GetType()) {
116 case static_cast<int32_t>(OperationType::START_ABILITY):
117 res = pendingWantManager->PendingWantStartAbility(want, senderInfo.startOptions,
118 senderInfo.callerToken, -1, callerUid_, callerTokenId_);
119 break;
120 case static_cast<int32_t>(OperationType::START_ABILITIES): {
121 std::vector<WantsInfo> allWantsInfos = key_->GetAllWantsInfos();
122 allWantsInfos.back().want = want;
123 res = pendingWantManager->PendingWantStartAbilitys(
124 allWantsInfos, senderInfo.startOptions, senderInfo.callerToken, -1, callerUid_, callerTokenId_);
125 break;
126 }
127 case static_cast<int32_t>(OperationType::START_SERVICE):
128 case static_cast<int32_t>(OperationType::START_FOREGROUND_SERVICE):
129 res = pendingWantManager->PendingWantStartAbility(want, nullptr, senderInfo.callerToken,
130 -1, callerUid_, callerTokenId_);
131 break;
132 case static_cast<int32_t>(OperationType::SEND_COMMON_EVENT):
133 res = pendingWantManager->PendingWantPublishCommonEvent(want, senderInfo, callerUid_, callerTokenId_);
134 break;
135 case static_cast<int32_t>(OperationType::START_SERVICE_EXTENSION):
136 res = pendingWantManager->PendingWantStartServiceExtension(want, senderInfo.callerToken);
137 break;
138 default:
139 break;
140 }
141 return res;
142 }
143
BuildSendWant(SenderInfo & senderInfo,Want & want)144 void PendingWantRecord::BuildSendWant(SenderInfo &senderInfo, Want &want)
145 {
146 if (key_->GetAllWantsInfos().size() != 0) {
147 want = key_->GetRequestWant();
148 }
149 uint32_t flags = static_cast<uint32_t>(key_->GetFlags());
150 bool immutable = false;
151 if (((flags & static_cast<uint32_t>(Flags::CONSTANT_FLAG)) != 0) ||
152 ((flags & static_cast<uint32_t>(Flags::ALLOW_CANCEL_FLAG)) != 0)) {
153 immutable = true;
154 }
155 senderInfo.resolvedType = key_->GetRequestResolvedType();
156 if (!immutable) {
157 want.AddFlags(key_->GetFlags());
158 }
159 WantParams wantParams = want.GetParams();
160 auto sendInfoWantParams = senderInfo.want.GetParams().GetParams();
161 for (auto mapIter = sendInfoWantParams.begin(); mapIter != sendInfoWantParams.end(); mapIter++) {
162 std::string sendInfoWantParamKey = mapIter->first;
163 if (want.GetParams().GetParam(sendInfoWantParamKey) == nullptr) {
164 wantParams.SetParam(sendInfoWantParamKey, mapIter->second);
165 }
166 }
167
168 if (!wantParams.HasParam(Want::PARAM_APP_CLONE_INDEX_KEY)) {
169 int32_t appIndex = key_->GetAppIndex();
170 if (GetUid() != INVALID_UID && !want.GetBundle().empty()) {
171 MultiAppUtils::GetRunningMultiAppIndex(want.GetBundle(), GetUid(), appIndex);
172 }
173 wantParams.SetParam(Want::PARAM_APP_CLONE_INDEX_KEY, Integer::Box(appIndex));
174 }
175 CheckAppInstanceKey(want.GetBundle(), wantParams);
176 want.SetParams(wantParams);
177 }
178
GetKey()179 std::shared_ptr<PendingWantKey> PendingWantRecord::GetKey()
180 {
181 return key_;
182 }
183
GetUid() const184 int32_t PendingWantRecord::GetUid() const
185 {
186 return uid_;
187 }
188
SetCanceled()189 void PendingWantRecord::SetCanceled()
190 {
191 canceled_ = true;
192 }
GetCanceled()193 bool PendingWantRecord::GetCanceled()
194 {
195 return canceled_;
196 }
197
SetCallerUid(const int32_t callerUid)198 void PendingWantRecord::SetCallerUid(const int32_t callerUid)
199 {
200 callerUid_ = callerUid;
201 }
202
GetCancelCallbacks()203 std::list<sptr<IWantReceiver>> PendingWantRecord::GetCancelCallbacks()
204 {
205 std::lock_guard guard(mCancelCallbacksMutex_);
206 return mCancelCallbacks_;
207 }
208
CheckAppInstanceKey(const std::string & bundleName,WantParams & wantParams)209 void PendingWantRecord::CheckAppInstanceKey(const std::string& bundleName, WantParams &wantParams)
210 {
211 if (key_ == nullptr) {
212 TAG_LOGE(AAFwkTag::WANTAGENT, "pending want key is null");
213 return;
214 }
215
216 auto currType = key_->GetType();
217 if (!(static_cast<int32_t>(OperationType::START_ABILITY) == currType ||
218 static_cast<int32_t>(OperationType::START_ABILITIES) == currType)) {
219 TAG_LOGD(AAFwkTag::WANTAGENT, "want agent type mismatch");
220 return;
221 }
222
223 auto appKey = wantParams.GetStringParam(APP_MULTI_INSTANCE);
224 if (appKey.empty()) {
225 TAG_LOGD(AAFwkTag::WANTAGENT, "want params non-existent app instance value");
226 return;
227 }
228
229 auto pendingWantManager = pendingWantManager_.lock();
230 if (pendingWantManager == nullptr) {
231 TAG_LOGE(AAFwkTag::WANTAGENT, "pending want manager is null");
232 return;
233 }
234
235 if (bundleName.empty()) {
236 TAG_LOGE(AAFwkTag::WANTAGENT, "bundle name is empty");
237 return;
238 }
239
240 std::vector<std::string> appKeyVec;
241 auto result = pendingWantManager->GetAllRunningInstanceKeysByBundleName(bundleName, appKeyVec);
242 if (result != ERR_OK) {
243 TAG_LOGE(AAFwkTag::WANTAGENT, "get app key error");
244 return;
245 }
246
247 auto find = std::find(appKeyVec.begin(), appKeyVec.end(), appKey);
248 if (find == appKeyVec.end()) {
249 TAG_LOGD(AAFwkTag::WANTAGENT, "%{public}s non-existent instance key %{public}s",
250 bundleName.c_str(), appKey.c_str());
251 wantParams.Remove(APP_MULTI_INSTANCE);
252 }
253 }
254 } // namespace AAFwk
255 } // namespace OHOS
256