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