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