* Copyright (C) 2022 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 "accessibility_window_connection.h"
namespace OHOS {
namespace Accessibility {
namespace {
constexpr int32_t SCENE_BOARD_WINDOW_ID = 1;
}
AccessibilityWindowConnection::AccessibilityWindowConnection(
const int32_t windowId, const int32_t accountId)
{
windowId_ = windowId;
accountId_ = accountId;
}
AccessibilityWindowConnection::AccessibilityWindowConnection(const int32_t windowId, const int32_t treeId,
const sptr<IAccessibilityElementOperator> &elementOperator, const int32_t accountId)
{
windowId_ = windowId;
treeId_ = treeId;
accountId_ = accountId;
cardProxy_.EnsureInsert(treeId, elementOperator);
}
AccessibilityWindowConnection::~AccessibilityWindowConnection()
{}
RetError AccessibilityWindowConnection::SetCardProxy(const int32_t treeId,
sptr<IAccessibilityElementOperator> operation)
{
if (!operation) {
HILOG_DEBUG("SetCardProxy : operation is nullptr");
return RET_ERR_FAILED;
}
cardProxy_.EnsureInsert(treeId, operation);
return RET_OK;
}
sptr<IAccessibilityElementOperator> AccessibilityWindowConnection::GetCardProxy(const int32_t treeId)
{
sptr<IAccessibilityElementOperator> connection = nullptr;
bool ret = cardProxy_.Find(treeId, connection);
HILOG_DEBUG("GetCardProxy : operation is %{public}d", connection != nullptr);
return connection;
}
RetError AccessibilityWindowConnection::SetTokenIdMap(const int32_t treeId,
const uint32_t tokenId)
{
HILOG_DEBUG("treeId : %{public}d", treeId);
tokenIdMap_.EnsureInsert(treeId, tokenId);
return RET_OK;
}
uint32_t AccessibilityWindowConnection::GetTokenIdMap(const int32_t treeId)
{
HILOG_DEBUG("treeId : %{public}d", treeId);
return tokenIdMap_.ReadVal(treeId);
}
void AccessibilityWindowConnection::GetAllTreeId(std::vector<int32_t> &treeIds)
{
auto getAllTreeIdFunc = [&treeIds](const int32_t treeId, sptr<IAccessibilityElementOperator> connection) {
treeIds.emplace_back(treeId);
};
cardProxy_.Iterate(getAllTreeIdFunc);
}
RetError AccessibilityWindowConnection::GetRootParentId(int32_t treeId, int64_t &elementId)
{
bool ret = treeIdParentId_.Find(treeId, elementId);
return ret == true ? RET_OK : RET_ERR_FAILED;
}
RetError AccessibilityWindowConnection::SetRootParentId(const int32_t treeId, const int64_t elementId)
{
treeIdParentId_.EnsureInsert(treeId, elementId);
return RET_OK;
}
void AccessibilityWindowConnection::EraseProxy(const int32_t treeId)
{
sptr<IAccessibilityElementOperator> connection = nullptr;
bool ret = cardProxy_.Find(treeId, connection);
if (ret) {
cardProxy_.Erase(treeId);
}
}
void AccessibilityWindowConnection::SetProxy(uint64_t displayId, sptr<IAccessibilityElementOperator> proxy)
{
AddDeathRecipient(proxy, false, displayId);
}
void AccessibilityWindowConnection::SetBrokerProxy(sptr<IAccessibilityElementOperator> proxy)
{
AddDeathRecipient(proxy, true, 0);
}
void AccessibilityWindowConnection::AddDeathRecipient(
sptr<IAccessibilityElementOperator> elementOperator, bool isBroker, uint64_t displayId)
{
if (!elementOperator || !elementOperator->AsObject()) {
return;
}
sptr<IRemoteObject::DeathRecipient> deathRecipient =
new(std::nothrow) InteractionOperationDeathRecipient(windowId_, accountId_, displayId);
if (!deathRecipient) {
HILOG_ERROR("Create interactionOperationDeathRecipient failed");
return;
}
if (elementOperator->AsObject()->AddDeathRecipient(deathRecipient)) {
std::lock_guard<ffrt::mutex> lock(proxyMutex_);
if (isBroker) {
brokerProxy_ = elementOperator;
brokerProxyDeathRecipient_ = deathRecipient;
} else {
proxyMap_.insert({displayId, {elementOperator, deathRecipient}});
}
}
}
void AccessibilityWindowConnection::AddTreeDeathRecipient(
int32_t windowId, int32_t accountId, int32_t treeId, uint64_t displayId)
{
sptr<IAccessibilityElementOperator> elementOperator = GetCardProxy(treeId);
if (!elementOperator || !elementOperator->AsObject()) {
return;
}
sptr<IRemoteObject::DeathRecipient> deathRecipient =
new(std::nothrow) InteractionOperationDeathRecipient(windowId, treeId, accountId, displayId);
if (!deathRecipient) {
HILOG_ERROR("Create interactionOperationDeathRecipient failed");
}
if (elementOperator->AsObject()->AddDeathRecipient(deathRecipient)) {
childTreeProxyDeathRecipient_.EnsureInsert(treeId, deathRecipient);
}
}
void AccessibilityWindowConnection::RemoveTreeDeathRecipient(int32_t treeId)
{
sptr<IAccessibilityElementOperator> elementOperator = GetCardProxy(treeId);
if (!elementOperator || !elementOperator->AsObject()) {
return;
}
sptr<IRemoteObject::DeathRecipient> deathRecipient = nullptr;
childTreeProxyDeathRecipient_.Find(treeId, deathRecipient);
if (!deathRecipient) {
return;
}
elementOperator->AsObject()->RemoveDeathRecipient(deathRecipient);
childTreeProxyDeathRecipient_.Erase(treeId);
}
void AccessibilityWindowConnection::InteractionOperationDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
{
HILOG_INFO();
}
void AccessibilityWindowConnection::ResetProxy()
{
HILOG_INFO();
}
void AccessibilityWindowConnection::ResetBrokerProxy()
{
HILOG_INFO();
}
bool AccessibilityWindowConnection::CheckScbTokenIdMap(uint32_t tokenId)
{
return scbTokenMap_.count(tokenId) != 0;
}
sptr<IAccessibilityElementOperator> AccessibilityWindowConnection::GetProxy(uint64_t displayId)
{
std::lock_guard<ffrt::mutex> lock(proxyMutex_);
if (windowId_ != SCENE_BOARD_WINDOW_ID) {
displayId = 0;
}
if (isUseBrokerProxy_.load()) {
return brokerProxy_;
} else {
return proxyMap_[displayId].first;
}
}
sptr<IAccessibilityElementOperator> AccessibilityWindowConnection::GetRawProxy(uint64_t displayId)
{
std::lock_guard<ffrt::mutex> lock(proxyMutex_);
auto iter = proxyMap_.find(displayId);
if (iter != proxyMap_.end()) {
return iter->second.first;
}
return nullptr;
}
}
}