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