/* * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "call_container.h" #include "ability_connect_callback_stub.h" #include "ability_util.h" #include "ability_manager_service.h" namespace OHOS { namespace AAFwk { CallContainer::CallContainer() {} CallContainer::~CallContainer() { std::for_each(deathRecipientMap_.begin(), deathRecipientMap_.end(), [&](RecipientMapType::reference recipient) { recipient.first->RemoveDeathRecipient(recipient.second); }); deathRecipientMap_.clear(); callRecordMap_.clear(); } std::shared_ptr CallContainer::FindCallRecordMap(sptr object) const { std::lock_guard lock(callRecordMapLock_); auto record = callRecordMap_.find(object); if (record != callRecordMap_.end()) { return record->second; } return nullptr; } std::shared_ptr CallContainer::RemoveCallRecordMap(sptr object) { std::shared_ptr result; std::lock_guard lock(callRecordMapLock_); auto record = callRecordMap_.find(object); if (record != callRecordMap_.end()) { result = record->second; callRecordMap_.erase(record); } return result; } void CallContainer::InsertCallRecordMap(sptr object, std::shared_ptr callRecord) { std::lock_guard lock(callRecordMapLock_); callRecordMap_.emplace(object, callRecord); } CallContainer::CallMapType CallContainer::CopyCallRecordMap() const { std::lock_guard lock(callRecordMapLock_); return callRecordMap_; } bool CallContainer::EmptyCallRecordMap() { std::lock_guard lock(callRecordMapLock_); return callRecordMap_.empty(); } void CallContainer::AddCallRecord(const sptr & connect, const std::shared_ptr& callRecord) { CHECK_POINTER(callRecord); CHECK_POINTER(connect); CHECK_POINTER(connect->AsObject()); auto record = RemoveCallRecordMap(connect->AsObject()); if (record != nullptr) { RemoveConnectDeathRecipient(connect); } AddConnectDeathRecipient(connect); callRecord->SetConCallBack(connect); InsertCallRecordMap(connect->AsObject(), callRecord); TAG_LOGD(AAFwkTag::ABILITYMGR, "Add call record to callcontainer, target: %{public}s", callRecord->GetTargetServiceName().GetURI().c_str()); } std::shared_ptr CallContainer::GetCallRecord(const sptr & connect) const { CHECK_POINTER_AND_RETURN(connect, nullptr); CHECK_POINTER_AND_RETURN(connect->AsObject(), nullptr); auto record = FindCallRecordMap(connect->AsObject()); return record; } bool CallContainer::RemoveCallRecord(const sptr & connect) { TAG_LOGD(AAFwkTag::ABILITYMGR, "call container release call record by callback."); CHECK_POINTER_AND_RETURN(connect, false); CHECK_POINTER_AND_RETURN(connect->AsObject(), false); auto record = RemoveCallRecordMap(connect->AsObject()); if (record != nullptr) { record->SchedulerDisconnectDone(); RemoveConnectDeathRecipient(connect); TAG_LOGD(AAFwkTag::ABILITYMGR, "remove call record is success."); return true; } if (EmptyCallRecordMap()) { // notify soft resouce service. TAG_LOGD(AAFwkTag::ABILITYMGR, "this ability has no callrecord."); } TAG_LOGW(AAFwkTag::ABILITYMGR, "remove call record is not exist."); return false; } void CallContainer::OnConnectionDied(const wptr &remote) { TAG_LOGW(AAFwkTag::ABILITYMGR, "Call back is died."); auto object = remote.promote(); CHECK_POINTER(object); std::shared_ptr callRecord = FindCallRecordMap(object); auto abilityManagerService = DelayedSingleton::GetInstance(); CHECK_POINTER(abilityManagerService); auto handler = abilityManagerService->GetTaskHandler(); CHECK_POINTER(handler); auto task = [abilityManagerService, callRecord]() { abilityManagerService->OnCallConnectDied(callRecord); }; handler->SubmitTask(task); } bool CallContainer::CallRequestDone(const sptr &callStub) { TAG_LOGI(AAFwkTag::ABILITYMGR, "Call Request Done start."); CHECK_POINTER_AND_RETURN(callStub, false); CallMapType copyCallRecordMap = CopyCallRecordMap(); for (const auto &iter : copyCallRecordMap) { std::shared_ptr callRecord = iter.second; if (callRecord && callRecord->IsCallState(CallState::REQUESTING)) { callRecord->SetCallStub(callStub); callRecord->SchedulerConnectDone(); } } TAG_LOGI(AAFwkTag::ABILITYMGR, "Call Request Done end."); return true; } void CallContainer::Dump(std::vector &info) const { TAG_LOGI(AAFwkTag::ABILITYMGR, "Dump call records."); CallMapType copyCallRecordMap = CopyCallRecordMap(); for (const auto &iter : copyCallRecordMap) { auto callRecord = iter.second; if (callRecord) { callRecord->Dump(info); } } } bool CallContainer::IsNeedToCallRequest() const { CallMapType copyCallRecordMap = CopyCallRecordMap(); for (const auto &iter : copyCallRecordMap) { auto callRecord = iter.second; if (callRecord && !callRecord->IsCallState(CallState::REQUESTED)) { return true; } } return false; } void CallContainer::AddConnectDeathRecipient(const sptr &connect) { CHECK_POINTER(connect); CHECK_POINTER(connect->AsObject()); auto it = deathRecipientMap_.find(connect->AsObject()); if (it != deathRecipientMap_.end()) { TAG_LOGE(AAFwkTag::ABILITYMGR, "This death recipient has been added."); return; } else { std::weak_ptr thisWeakPtr(shared_from_this()); sptr deathRecipient = new AbilityConnectCallbackRecipient([thisWeakPtr](const wptr &remote) { auto callContainer = thisWeakPtr.lock(); if (callContainer) { callContainer->OnConnectionDied(remote); } }); if (!connect->AsObject()->AddDeathRecipient(deathRecipient)) { TAG_LOGE(AAFwkTag::ABILITYMGR, "AddDeathRecipient failed."); } deathRecipientMap_.emplace(connect->AsObject(), deathRecipient); } } void CallContainer::RemoveConnectDeathRecipient(const sptr &connect) { CHECK_POINTER(connect); CHECK_POINTER(connect->AsObject()); auto it = deathRecipientMap_.find(connect->AsObject()); if (it != deathRecipientMap_.end()) { it->first->RemoveDeathRecipient(it->second); deathRecipientMap_.erase(it); return; } } bool CallContainer::IsExistConnection(const sptr &connect) { return FindCallRecordMap(connect->AsObject()) != nullptr; } } // namespace AAFwk } // namesspace OHOS