1 /*
2 * Copyright (c) 2022-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 "call_container.h"
17
18 #include "ability_connect_callback_stub.h"
19 #include "ability_util.h"
20 #include "ability_manager_service.h"
21
22 namespace OHOS {
23 namespace AAFwk {
CallContainer()24 CallContainer::CallContainer()
25 {}
26
~CallContainer()27 CallContainer::~CallContainer()
28 {
29 std::for_each(deathRecipientMap_.begin(),
30 deathRecipientMap_.end(),
31 [&](RecipientMapType::reference recipient) {
32 recipient.first->RemoveDeathRecipient(recipient.second);
33 });
34
35 deathRecipientMap_.clear();
36 callRecordMap_.clear();
37 }
38
FindCallRecordMap(sptr<IRemoteObject> object) const39 std::shared_ptr<CallRecord> CallContainer::FindCallRecordMap(sptr<IRemoteObject> object) const
40 {
41 std::lock_guard lock(callRecordMapLock_);
42 auto record = callRecordMap_.find(object);
43 if (record != callRecordMap_.end()) {
44 return record->second;
45 }
46 return nullptr;
47 }
48
RemoveCallRecordMap(sptr<IRemoteObject> object)49 std::shared_ptr<CallRecord> CallContainer::RemoveCallRecordMap(sptr<IRemoteObject> object)
50 {
51 std::shared_ptr<CallRecord> result;
52 std::lock_guard lock(callRecordMapLock_);
53 auto record = callRecordMap_.find(object);
54 if (record != callRecordMap_.end()) {
55 result = record->second;
56 callRecordMap_.erase(record);
57 }
58 return result;
59 }
60
InsertCallRecordMap(sptr<IRemoteObject> object,std::shared_ptr<CallRecord> callRecord)61 void CallContainer::InsertCallRecordMap(sptr<IRemoteObject> object, std::shared_ptr<CallRecord> callRecord)
62 {
63 std::lock_guard lock(callRecordMapLock_);
64 callRecordMap_.emplace(object, callRecord);
65 }
66
CopyCallRecordMap() const67 CallContainer::CallMapType CallContainer::CopyCallRecordMap() const
68 {
69 std::lock_guard lock(callRecordMapLock_);
70 return callRecordMap_;
71 }
72
EmptyCallRecordMap()73 bool CallContainer::EmptyCallRecordMap()
74 {
75 std::lock_guard lock(callRecordMapLock_);
76 return callRecordMap_.empty();
77 }
78
AddCallRecord(const sptr<IAbilityConnection> & connect,const std::shared_ptr<CallRecord> & callRecord)79 void CallContainer::AddCallRecord(const sptr<IAbilityConnection> & connect,
80 const std::shared_ptr<CallRecord>& callRecord)
81 {
82 CHECK_POINTER(callRecord);
83 CHECK_POINTER(connect);
84 CHECK_POINTER(connect->AsObject());
85
86 auto record = RemoveCallRecordMap(connect->AsObject());
87 if (record != nullptr) {
88 RemoveConnectDeathRecipient(connect);
89 }
90
91 AddConnectDeathRecipient(connect);
92 callRecord->SetConCallBack(connect);
93 InsertCallRecordMap(connect->AsObject(), callRecord);
94
95 TAG_LOGD(AAFwkTag::ABILITYMGR, "Add call record to callcontainer, target: %{public}s",
96 callRecord->GetTargetServiceName().GetURI().c_str());
97 }
98
GetCallRecord(const sptr<IAbilityConnection> & connect) const99 std::shared_ptr<CallRecord> CallContainer::GetCallRecord(const sptr<IAbilityConnection> & connect) const
100 {
101 CHECK_POINTER_AND_RETURN(connect, nullptr);
102 CHECK_POINTER_AND_RETURN(connect->AsObject(), nullptr);
103
104 auto record = FindCallRecordMap(connect->AsObject());
105 return record;
106 }
107
RemoveCallRecord(const sptr<IAbilityConnection> & connect)108 bool CallContainer::RemoveCallRecord(const sptr<IAbilityConnection> & connect)
109 {
110 TAG_LOGD(AAFwkTag::ABILITYMGR, "call container release call record by callback.");
111 CHECK_POINTER_AND_RETURN(connect, false);
112 CHECK_POINTER_AND_RETURN(connect->AsObject(), false);
113
114 auto record = RemoveCallRecordMap(connect->AsObject());
115 if (record != nullptr) {
116 record->SchedulerDisconnectDone();
117 RemoveConnectDeathRecipient(connect);
118 TAG_LOGD(AAFwkTag::ABILITYMGR, "remove call record is success.");
119 return true;
120 }
121
122 if (EmptyCallRecordMap()) {
123 // notify soft resouce service.
124 TAG_LOGD(AAFwkTag::ABILITYMGR, "this ability has no callrecord.");
125 }
126
127 TAG_LOGW(AAFwkTag::ABILITYMGR, "remove call record is not exist.");
128 return false;
129 }
130
OnConnectionDied(const wptr<IRemoteObject> & remote)131 void CallContainer::OnConnectionDied(const wptr<IRemoteObject> &remote)
132 {
133 TAG_LOGW(AAFwkTag::ABILITYMGR, "Call back is died.");
134 auto object = remote.promote();
135 CHECK_POINTER(object);
136
137 std::shared_ptr<CallRecord> callRecord = FindCallRecordMap(object);
138 auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
139 CHECK_POINTER(abilityManagerService);
140 auto handler = abilityManagerService->GetTaskHandler();
141 CHECK_POINTER(handler);
142 auto task = [abilityManagerService, callRecord]() {
143 abilityManagerService->OnCallConnectDied(callRecord);
144 };
145 handler->SubmitTask(task);
146 }
147
CallRequestDone(const sptr<IRemoteObject> & callStub)148 bool CallContainer::CallRequestDone(const sptr<IRemoteObject> &callStub)
149 {
150 TAG_LOGI(AAFwkTag::ABILITYMGR, "Call Request Done start.");
151 CHECK_POINTER_AND_RETURN(callStub, false);
152 CallMapType copyCallRecordMap = CopyCallRecordMap();
153 for (const auto &iter : copyCallRecordMap) {
154 std::shared_ptr<CallRecord> callRecord = iter.second;
155 if (callRecord && callRecord->IsCallState(CallState::REQUESTING)) {
156 callRecord->SetCallStub(callStub);
157 callRecord->SchedulerConnectDone();
158 }
159 }
160 TAG_LOGI(AAFwkTag::ABILITYMGR, "Call Request Done end.");
161 return true;
162 }
163
Dump(std::vector<std::string> & info) const164 void CallContainer::Dump(std::vector<std::string> &info) const
165 {
166 TAG_LOGI(AAFwkTag::ABILITYMGR, "Dump call records.");
167 CallMapType copyCallRecordMap = CopyCallRecordMap();
168 for (const auto &iter : copyCallRecordMap) {
169 auto callRecord = iter.second;
170 if (callRecord) {
171 callRecord->Dump(info);
172 }
173 }
174 }
175
IsNeedToCallRequest() const176 bool CallContainer::IsNeedToCallRequest() const
177 {
178 CallMapType copyCallRecordMap = CopyCallRecordMap();
179 for (const auto &iter : copyCallRecordMap) {
180 auto callRecord = iter.second;
181 if (callRecord && !callRecord->IsCallState(CallState::REQUESTED)) {
182 return true;
183 }
184 }
185 return false;
186 }
187
AddConnectDeathRecipient(const sptr<IAbilityConnection> & connect)188 void CallContainer::AddConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
189 {
190 CHECK_POINTER(connect);
191 CHECK_POINTER(connect->AsObject());
192 auto it = deathRecipientMap_.find(connect->AsObject());
193 if (it != deathRecipientMap_.end()) {
194 TAG_LOGE(AAFwkTag::ABILITYMGR, "This death recipient has been added.");
195 return;
196 } else {
197 std::weak_ptr<CallContainer> thisWeakPtr(shared_from_this());
198 sptr<IRemoteObject::DeathRecipient> deathRecipient =
199 new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
200 auto callContainer = thisWeakPtr.lock();
201 if (callContainer) {
202 callContainer->OnConnectionDied(remote);
203 }
204 });
205 if (!connect->AsObject()->AddDeathRecipient(deathRecipient)) {
206 TAG_LOGE(AAFwkTag::ABILITYMGR, "AddDeathRecipient failed.");
207 }
208 deathRecipientMap_.emplace(connect->AsObject(), deathRecipient);
209 }
210 }
211
RemoveConnectDeathRecipient(const sptr<IAbilityConnection> & connect)212 void CallContainer::RemoveConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
213 {
214 CHECK_POINTER(connect);
215 CHECK_POINTER(connect->AsObject());
216 auto it = deathRecipientMap_.find(connect->AsObject());
217 if (it != deathRecipientMap_.end()) {
218 it->first->RemoveDeathRecipient(it->second);
219 deathRecipientMap_.erase(it);
220 return;
221 }
222 }
223
IsExistConnection(const sptr<IAbilityConnection> & connect)224 bool CallContainer::IsExistConnection(const sptr<IAbilityConnection> &connect)
225 {
226 return FindCallRecordMap(connect->AsObject()) != nullptr;
227 }
228 } // namespace AAFwk
229 } // namesspace OHOS
230