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 
22 namespace OHOS {
23 namespace AAFwk {
PendingWantRecord()24 PendingWantRecord::PendingWantRecord()
25 {}
26 
PendingWantRecord(const std::shared_ptr<PendingWantManager> & pendingWantManager,int32_t uid,int32_t callerTokenId,const sptr<IRemoteObject> & callerToken,std::shared_ptr<PendingWantKey> key)27 PendingWantRecord::PendingWantRecord(const std::shared_ptr<PendingWantManager> &pendingWantManager, int32_t uid,
28     int32_t callerTokenId, const sptr<IRemoteObject> &callerToken, std::shared_ptr<PendingWantKey> key)
29     : pendingWantManager_(pendingWantManager), uid_(uid), callerTokenId_(callerTokenId),
30     callerToken_(callerToken), key_(key)
31 {}
32 
~PendingWantRecord()33 PendingWantRecord::~PendingWantRecord()
34 {}
35 
Send(SenderInfo & senderInfo)36 void PendingWantRecord::Send(SenderInfo &senderInfo)
37 {
38     SenderInner(senderInfo);
39 }
40 
RegisterCancelListener(const sptr<IWantReceiver> & receiver)41 void PendingWantRecord::RegisterCancelListener(const sptr<IWantReceiver> &receiver)
42 {
43     if (receiver == nullptr) {
44         return;
45     }
46     mCancelCallbacks_.emplace_back(receiver);
47 }
48 
UnregisterCancelListener(const sptr<IWantReceiver> & receiver)49 void PendingWantRecord::UnregisterCancelListener(const sptr<IWantReceiver> &receiver)
50 {
51     if (receiver == nullptr) {
52         return;
53     }
54     if (mCancelCallbacks_.size()) {
55         auto it = std::find(mCancelCallbacks_.cbegin(), mCancelCallbacks_.cend(), receiver);
56         if (it != mCancelCallbacks_.cend()) {
57             mCancelCallbacks_.erase(it);
58         }
59     }
60 }
61 
SenderInner(SenderInfo & senderInfo)62 int32_t PendingWantRecord::SenderInner(SenderInfo &senderInfo)
63 {
64     std::lock_guard<ffrt::mutex> locker(lock_);
65     if (canceled_) {
66         if (senderInfo.finishedReceiver != nullptr) {
67             Want want;
68             WantParams wantParams = {};
69             senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "canceled", wantParams, false, false, 0);
70         }
71         return START_CANCELED;
72     }
73 
74     auto pendingWantManager = pendingWantManager_.lock();
75     if (pendingWantManager == nullptr) {
76         TAG_LOGE(AAFwkTag::WANTAGENT, "pendingWantManager is nullptr");
77         return ERR_INVALID_VALUE;
78     }
79 
80     if (((uint32_t)key_->GetFlags() & (uint32_t)Flags::ONE_TIME_FLAG) != 0) {
81         pendingWantManager->CancelWantSenderLocked(*this, true);
82     }
83 
84     Want want;
85     BuildSendWant(senderInfo, want);
86 
87     bool sendFinish = (senderInfo.finishedReceiver != nullptr);
88     int32_t res = ExecuteOperation(pendingWantManager, senderInfo, want);
89     if (sendFinish && res != START_CANCELED) {
90         WantParams wantParams = {};
91         senderInfo.finishedReceiver->PerformReceive(want, senderInfo.code, "", wantParams, false, false, 0);
92     }
93 
94     return res;
95 }
96 
ExecuteOperation(std::shared_ptr<PendingWantManager> pendingWantManager,SenderInfo & senderInfo,Want & want)97 int32_t PendingWantRecord::ExecuteOperation(
98     std::shared_ptr<PendingWantManager> pendingWantManager, SenderInfo &senderInfo, Want &want)
99 {
100     int32_t res = NO_ERROR;
101     switch (key_->GetType()) {
102         case static_cast<int32_t>(OperationType::START_ABILITY):
103             res = pendingWantManager->PendingWantStartAbility(want, senderInfo.startOptions,
104                 callerToken_, -1, callerUid_, callerTokenId_);
105             break;
106         case static_cast<int32_t>(OperationType::START_ABILITIES): {
107             std::vector<WantsInfo> allWantsInfos = key_->GetAllWantsInfos();
108             allWantsInfos.back().want = want;
109             res = pendingWantManager->PendingWantStartAbilitys(
110                 allWantsInfos, senderInfo.startOptions, callerToken_, -1, callerUid_, callerTokenId_);
111             break;
112         }
113         case static_cast<int32_t>(OperationType::START_SERVICE):
114         case static_cast<int32_t>(OperationType::START_FOREGROUND_SERVICE):
115             res = pendingWantManager->PendingWantStartAbility(want, nullptr, callerToken_,
116                 -1, callerUid_, callerTokenId_);
117             break;
118         case static_cast<int32_t>(OperationType::SEND_COMMON_EVENT):
119             res = pendingWantManager->PendingWantPublishCommonEvent(want, senderInfo, callerUid_, callerTokenId_);
120             break;
121         case static_cast<int32_t>(OperationType::START_SERVICE_EXTENSION):
122             res = pendingWantManager->PendingWantStartServiceExtension(want, callerToken_);
123             break;
124         default:
125             break;
126     }
127     return res;
128 }
129 
BuildSendWant(SenderInfo & senderInfo,Want & want)130 void PendingWantRecord::BuildSendWant(SenderInfo &senderInfo, Want &want)
131 {
132     if (key_->GetAllWantsInfos().size() != 0) {
133         want = key_->GetRequestWant();
134     }
135     uint32_t flags = static_cast<uint32_t>(key_->GetFlags());
136     bool immutable = false;
137     if (((flags & static_cast<uint32_t>(Flags::CONSTANT_FLAG)) != 0) ||
138         ((flags & static_cast<uint32_t>(Flags::ALLOW_CANCEL_FLAG)) != 0)) {
139         immutable = true;
140     }
141     senderInfo.resolvedType = key_->GetRequestResolvedType();
142     if (!immutable) {
143         want.AddFlags(key_->GetFlags());
144     }
145     WantParams wantParams = want.GetParams();
146     auto sendInfoWantParams = senderInfo.want.GetParams().GetParams();
147     for (auto mapIter = sendInfoWantParams.begin(); mapIter != sendInfoWantParams.end(); mapIter++) {
148         std::string sendInfoWantParamKey = mapIter->first;
149         if (want.GetParams().GetParam(sendInfoWantParamKey) == nullptr) {
150             wantParams.SetParam(sendInfoWantParamKey, mapIter->second);
151         }
152     }
153 
154     if (!wantParams.HasParam("ohos.extra.param.key.appCloneIndex")) {
155         wantParams.SetParam("ohos.extra.param.key.appCloneIndex", Integer::Box(key_->GetAppIndex()));
156     }
157 
158     want.SetParams(wantParams);
159 }
160 
GetKey()161 std::shared_ptr<PendingWantKey> PendingWantRecord::GetKey()
162 {
163     return key_;
164 }
165 
GetUid() const166 int32_t PendingWantRecord::GetUid() const
167 {
168     return uid_;
169 }
170 
SetCanceled()171 void PendingWantRecord::SetCanceled()
172 {
173     canceled_ = true;
174 }
GetCanceled()175 bool PendingWantRecord::GetCanceled()
176 {
177     return canceled_;
178 }
179 
SetCallerUid(const int32_t callerUid)180 void PendingWantRecord::SetCallerUid(const int32_t callerUid)
181 {
182     callerUid_ = callerUid;
183 }
184 
GetCancelCallbacks()185 std::list<sptr<IWantReceiver>> PendingWantRecord::GetCancelCallbacks()
186 {
187     return mCancelCallbacks_;
188 }
189 }  // namespace AAFwk
190 }  // namespace OHOS
191