1eace7efcSopenharmony_ci/*
2eace7efcSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License.
5eace7efcSopenharmony_ci * You may obtain a copy of the License at
6eace7efcSopenharmony_ci *
7eace7efcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8eace7efcSopenharmony_ci *
9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and
13eace7efcSopenharmony_ci * limitations under the License.
14eace7efcSopenharmony_ci */
15eace7efcSopenharmony_ci
16eace7efcSopenharmony_ci#include "call_container.h"
17eace7efcSopenharmony_ci
18eace7efcSopenharmony_ci#include "ability_connect_callback_stub.h"
19eace7efcSopenharmony_ci#include "ability_util.h"
20eace7efcSopenharmony_ci#include "ability_manager_service.h"
21eace7efcSopenharmony_ci
22eace7efcSopenharmony_cinamespace OHOS {
23eace7efcSopenharmony_cinamespace AAFwk {
24eace7efcSopenharmony_ciCallContainer::CallContainer()
25eace7efcSopenharmony_ci{}
26eace7efcSopenharmony_ci
27eace7efcSopenharmony_ciCallContainer::~CallContainer()
28eace7efcSopenharmony_ci{
29eace7efcSopenharmony_ci    std::for_each(deathRecipientMap_.begin(),
30eace7efcSopenharmony_ci        deathRecipientMap_.end(),
31eace7efcSopenharmony_ci        [&](RecipientMapType::reference recipient) {
32eace7efcSopenharmony_ci            recipient.first->RemoveDeathRecipient(recipient.second);
33eace7efcSopenharmony_ci        });
34eace7efcSopenharmony_ci
35eace7efcSopenharmony_ci    deathRecipientMap_.clear();
36eace7efcSopenharmony_ci    callRecordMap_.clear();
37eace7efcSopenharmony_ci}
38eace7efcSopenharmony_ci
39eace7efcSopenharmony_cistd::shared_ptr<CallRecord> CallContainer::FindCallRecordMap(sptr<IRemoteObject> object) const
40eace7efcSopenharmony_ci{
41eace7efcSopenharmony_ci    std::lock_guard lock(callRecordMapLock_);
42eace7efcSopenharmony_ci    auto record = callRecordMap_.find(object);
43eace7efcSopenharmony_ci    if (record != callRecordMap_.end()) {
44eace7efcSopenharmony_ci        return record->second;
45eace7efcSopenharmony_ci    }
46eace7efcSopenharmony_ci    return nullptr;
47eace7efcSopenharmony_ci}
48eace7efcSopenharmony_ci
49eace7efcSopenharmony_cistd::shared_ptr<CallRecord> CallContainer::RemoveCallRecordMap(sptr<IRemoteObject> object)
50eace7efcSopenharmony_ci{
51eace7efcSopenharmony_ci    std::shared_ptr<CallRecord> result;
52eace7efcSopenharmony_ci    std::lock_guard lock(callRecordMapLock_);
53eace7efcSopenharmony_ci    auto record = callRecordMap_.find(object);
54eace7efcSopenharmony_ci    if (record != callRecordMap_.end()) {
55eace7efcSopenharmony_ci        result = record->second;
56eace7efcSopenharmony_ci        callRecordMap_.erase(record);
57eace7efcSopenharmony_ci    }
58eace7efcSopenharmony_ci    return result;
59eace7efcSopenharmony_ci}
60eace7efcSopenharmony_ci
61eace7efcSopenharmony_civoid CallContainer::InsertCallRecordMap(sptr<IRemoteObject> object, std::shared_ptr<CallRecord> callRecord)
62eace7efcSopenharmony_ci{
63eace7efcSopenharmony_ci    std::lock_guard lock(callRecordMapLock_);
64eace7efcSopenharmony_ci    callRecordMap_.emplace(object, callRecord);
65eace7efcSopenharmony_ci}
66eace7efcSopenharmony_ci
67eace7efcSopenharmony_ciCallContainer::CallMapType CallContainer::CopyCallRecordMap() const
68eace7efcSopenharmony_ci{
69eace7efcSopenharmony_ci    std::lock_guard lock(callRecordMapLock_);
70eace7efcSopenharmony_ci    return callRecordMap_;
71eace7efcSopenharmony_ci}
72eace7efcSopenharmony_ci
73eace7efcSopenharmony_cibool CallContainer::EmptyCallRecordMap()
74eace7efcSopenharmony_ci{
75eace7efcSopenharmony_ci    std::lock_guard lock(callRecordMapLock_);
76eace7efcSopenharmony_ci    return callRecordMap_.empty();
77eace7efcSopenharmony_ci}
78eace7efcSopenharmony_ci
79eace7efcSopenharmony_civoid CallContainer::AddCallRecord(const sptr<IAbilityConnection> & connect,
80eace7efcSopenharmony_ci    const std::shared_ptr<CallRecord>& callRecord)
81eace7efcSopenharmony_ci{
82eace7efcSopenharmony_ci    CHECK_POINTER(callRecord);
83eace7efcSopenharmony_ci    CHECK_POINTER(connect);
84eace7efcSopenharmony_ci    CHECK_POINTER(connect->AsObject());
85eace7efcSopenharmony_ci
86eace7efcSopenharmony_ci    auto record = RemoveCallRecordMap(connect->AsObject());
87eace7efcSopenharmony_ci    if (record != nullptr) {
88eace7efcSopenharmony_ci        RemoveConnectDeathRecipient(connect);
89eace7efcSopenharmony_ci    }
90eace7efcSopenharmony_ci
91eace7efcSopenharmony_ci    AddConnectDeathRecipient(connect);
92eace7efcSopenharmony_ci    callRecord->SetConCallBack(connect);
93eace7efcSopenharmony_ci    InsertCallRecordMap(connect->AsObject(), callRecord);
94eace7efcSopenharmony_ci
95eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::ABILITYMGR, "Add call record to callcontainer, target: %{public}s",
96eace7efcSopenharmony_ci        callRecord->GetTargetServiceName().GetURI().c_str());
97eace7efcSopenharmony_ci}
98eace7efcSopenharmony_ci
99eace7efcSopenharmony_cistd::shared_ptr<CallRecord> CallContainer::GetCallRecord(const sptr<IAbilityConnection> & connect) const
100eace7efcSopenharmony_ci{
101eace7efcSopenharmony_ci    CHECK_POINTER_AND_RETURN(connect, nullptr);
102eace7efcSopenharmony_ci    CHECK_POINTER_AND_RETURN(connect->AsObject(), nullptr);
103eace7efcSopenharmony_ci
104eace7efcSopenharmony_ci    auto record = FindCallRecordMap(connect->AsObject());
105eace7efcSopenharmony_ci    return record;
106eace7efcSopenharmony_ci}
107eace7efcSopenharmony_ci
108eace7efcSopenharmony_cibool CallContainer::RemoveCallRecord(const sptr<IAbilityConnection> & connect)
109eace7efcSopenharmony_ci{
110eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::ABILITYMGR, "call container release call record by callback.");
111eace7efcSopenharmony_ci    CHECK_POINTER_AND_RETURN(connect, false);
112eace7efcSopenharmony_ci    CHECK_POINTER_AND_RETURN(connect->AsObject(), false);
113eace7efcSopenharmony_ci
114eace7efcSopenharmony_ci    auto record = RemoveCallRecordMap(connect->AsObject());
115eace7efcSopenharmony_ci    if (record != nullptr) {
116eace7efcSopenharmony_ci        record->SchedulerDisconnectDone();
117eace7efcSopenharmony_ci        RemoveConnectDeathRecipient(connect);
118eace7efcSopenharmony_ci        TAG_LOGD(AAFwkTag::ABILITYMGR, "remove call record is success.");
119eace7efcSopenharmony_ci        return true;
120eace7efcSopenharmony_ci    }
121eace7efcSopenharmony_ci
122eace7efcSopenharmony_ci    if (EmptyCallRecordMap()) {
123eace7efcSopenharmony_ci        // notify soft resouce service.
124eace7efcSopenharmony_ci        TAG_LOGD(AAFwkTag::ABILITYMGR, "this ability has no callrecord.");
125eace7efcSopenharmony_ci    }
126eace7efcSopenharmony_ci
127eace7efcSopenharmony_ci    TAG_LOGW(AAFwkTag::ABILITYMGR, "remove call record not exist");
128eace7efcSopenharmony_ci    return false;
129eace7efcSopenharmony_ci}
130eace7efcSopenharmony_ci
131eace7efcSopenharmony_civoid CallContainer::OnConnectionDied(const wptr<IRemoteObject> &remote)
132eace7efcSopenharmony_ci{
133eace7efcSopenharmony_ci    TAG_LOGW(AAFwkTag::ABILITYMGR, "call back died");
134eace7efcSopenharmony_ci    auto object = remote.promote();
135eace7efcSopenharmony_ci    CHECK_POINTER(object);
136eace7efcSopenharmony_ci
137eace7efcSopenharmony_ci    std::shared_ptr<CallRecord> callRecord = FindCallRecordMap(object);
138eace7efcSopenharmony_ci    auto abilityManagerService = DelayedSingleton<AbilityManagerService>::GetInstance();
139eace7efcSopenharmony_ci    CHECK_POINTER(abilityManagerService);
140eace7efcSopenharmony_ci    auto handler = abilityManagerService->GetTaskHandler();
141eace7efcSopenharmony_ci    CHECK_POINTER(handler);
142eace7efcSopenharmony_ci    auto task = [abilityManagerService, callRecord]() {
143eace7efcSopenharmony_ci        abilityManagerService->OnCallConnectDied(callRecord);
144eace7efcSopenharmony_ci    };
145eace7efcSopenharmony_ci    handler->SubmitTask(task);
146eace7efcSopenharmony_ci}
147eace7efcSopenharmony_ci
148eace7efcSopenharmony_cibool CallContainer::CallRequestDone(const sptr<IRemoteObject> &callStub)
149eace7efcSopenharmony_ci{
150eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::ABILITYMGR, "start");
151eace7efcSopenharmony_ci    CHECK_POINTER_AND_RETURN(callStub, false);
152eace7efcSopenharmony_ci    CallMapType copyCallRecordMap = CopyCallRecordMap();
153eace7efcSopenharmony_ci    for (const auto &iter : copyCallRecordMap) {
154eace7efcSopenharmony_ci        std::shared_ptr<CallRecord> callRecord = iter.second;
155eace7efcSopenharmony_ci        if (callRecord && callRecord->IsCallState(CallState::REQUESTING)) {
156eace7efcSopenharmony_ci            callRecord->SetCallStub(callStub);
157eace7efcSopenharmony_ci            callRecord->SchedulerConnectDone();
158eace7efcSopenharmony_ci        }
159eace7efcSopenharmony_ci    }
160eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::ABILITYMGR, "end");
161eace7efcSopenharmony_ci    return true;
162eace7efcSopenharmony_ci}
163eace7efcSopenharmony_ci
164eace7efcSopenharmony_civoid CallContainer::Dump(std::vector<std::string> &info) const
165eace7efcSopenharmony_ci{
166eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::ABILITYMGR, "dump call records");
167eace7efcSopenharmony_ci    CallMapType copyCallRecordMap = CopyCallRecordMap();
168eace7efcSopenharmony_ci    for (const auto &iter : copyCallRecordMap) {
169eace7efcSopenharmony_ci        auto callRecord = iter.second;
170eace7efcSopenharmony_ci        if (callRecord) {
171eace7efcSopenharmony_ci            callRecord->Dump(info);
172eace7efcSopenharmony_ci        }
173eace7efcSopenharmony_ci    }
174eace7efcSopenharmony_ci}
175eace7efcSopenharmony_ci
176eace7efcSopenharmony_cibool CallContainer::IsNeedToCallRequest() const
177eace7efcSopenharmony_ci{
178eace7efcSopenharmony_ci    CallMapType copyCallRecordMap = CopyCallRecordMap();
179eace7efcSopenharmony_ci    for (const auto &iter : copyCallRecordMap) {
180eace7efcSopenharmony_ci        auto callRecord = iter.second;
181eace7efcSopenharmony_ci        if (callRecord && !callRecord->IsCallState(CallState::REQUESTED)) {
182eace7efcSopenharmony_ci            return true;
183eace7efcSopenharmony_ci        }
184eace7efcSopenharmony_ci    }
185eace7efcSopenharmony_ci    return false;
186eace7efcSopenharmony_ci}
187eace7efcSopenharmony_ci
188eace7efcSopenharmony_civoid CallContainer::AddConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
189eace7efcSopenharmony_ci{
190eace7efcSopenharmony_ci    CHECK_POINTER(connect);
191eace7efcSopenharmony_ci    CHECK_POINTER(connect->AsObject());
192eace7efcSopenharmony_ci    auto it = deathRecipientMap_.find(connect->AsObject());
193eace7efcSopenharmony_ci    if (it != deathRecipientMap_.end()) {
194eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::ABILITYMGR, "death recipient been added");
195eace7efcSopenharmony_ci        return;
196eace7efcSopenharmony_ci    } else {
197eace7efcSopenharmony_ci        std::weak_ptr<CallContainer> thisWeakPtr(shared_from_this());
198eace7efcSopenharmony_ci        sptr<IRemoteObject::DeathRecipient> deathRecipient =
199eace7efcSopenharmony_ci            new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
200eace7efcSopenharmony_ci                auto callContainer = thisWeakPtr.lock();
201eace7efcSopenharmony_ci                if (callContainer) {
202eace7efcSopenharmony_ci                    callContainer->OnConnectionDied(remote);
203eace7efcSopenharmony_ci                }
204eace7efcSopenharmony_ci            });
205eace7efcSopenharmony_ci        if (!connect->AsObject()->AddDeathRecipient(deathRecipient)) {
206eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::ABILITYMGR, "addDeathRecipient failed");
207eace7efcSopenharmony_ci        }
208eace7efcSopenharmony_ci        deathRecipientMap_.emplace(connect->AsObject(), deathRecipient);
209eace7efcSopenharmony_ci    }
210eace7efcSopenharmony_ci}
211eace7efcSopenharmony_ci
212eace7efcSopenharmony_civoid CallContainer::RemoveConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
213eace7efcSopenharmony_ci{
214eace7efcSopenharmony_ci    CHECK_POINTER(connect);
215eace7efcSopenharmony_ci    CHECK_POINTER(connect->AsObject());
216eace7efcSopenharmony_ci    auto it = deathRecipientMap_.find(connect->AsObject());
217eace7efcSopenharmony_ci    if (it != deathRecipientMap_.end()) {
218eace7efcSopenharmony_ci        it->first->RemoveDeathRecipient(it->second);
219eace7efcSopenharmony_ci        deathRecipientMap_.erase(it);
220eace7efcSopenharmony_ci        return;
221eace7efcSopenharmony_ci    }
222eace7efcSopenharmony_ci}
223eace7efcSopenharmony_ci
224eace7efcSopenharmony_cibool CallContainer::IsExistConnection(const sptr<IAbilityConnection> &connect)
225eace7efcSopenharmony_ci{
226eace7efcSopenharmony_ci    return FindCallRecordMap(connect->AsObject()) != nullptr;
227eace7efcSopenharmony_ci}
228eace7efcSopenharmony_ci}  // namespace AAFwk
229eace7efcSopenharmony_ci}  // namesspace OHOS
230