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