* Copyright (C) 2022-2026 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 "accessible_ability_channel.h"
#include "accessible_ability_manager_service.h"
#include "accessibility_window_connection.h"
#include "accessibility_window_manager.h"
#include "accessible_ability_connection.h"
#include "display_manager.h"
#include "hilog_wrapper.h"
#include <cinttypes>
#include <unordered_map>
#ifdef OHOS_BUILD_ENABLE_POWER_MANAGER
#include "accessibility_power_manager.h"
#endif
#include "utils.h"
namespace OHOS {
namespace Accessibility {
namespace {
constexpr int32_t WINDOW_ID_INVALID = -1;
constexpr int64_t ELEMENT_ID_INVALID = -1;
const int32_t LONG_PRESS_EVENT_INTERVAL = 550;
const int32_t DOUBLE_CLICK_EVENT_INTERVAL = 100;
MMI::InputManager* inputManager_ = MMI::InputManager::GetInstance();
std::map<int32_t, std::pair<bool, std::pair<int32_t, int32_t>>> accessibleKeyCodeTable = {
{ActionType::ACCESSIBILITY_ACTION_HOME,
{false, {MMI::KeyEvent::KEYCODE_META_LEFT, MMI::KeyEvent::KEYCODE_D}}},
{ActionType::ACCESSIBILITY_ACTION_RECENTTASK,
{false, {MMI::KeyEvent::KEYCODE_META_LEFT, MMI::KeyEvent::KEYCODE_TAB}}},
{ActionType::ACCESSIBILITY_ACTION_BACK,
{true, {MMI::KeyEvent::KEYCODE_BACK, MMI::KeyEvent::KEYCODE_BACK}}},
{ActionType::ACCESSIBILITY_ACTION_NOTIFICATIONCENTER,
{true, {MMI::KeyEvent::KEYCODE_CALL_NOTIFICATION_CENTER, MMI::KeyEvent::KEYCODE_CALL_NOTIFICATION_CENTER}}},
{ActionType::ACCESSIBILITY_ACTION_CONTROLCENTER,
{true, {MMI::KeyEvent::KEYCODE_CALL_CONTROL_CENTER, MMI::KeyEvent::KEYCODE_CALL_CONTROL_CENTER}}}};
InjectActionType StringToInjectAction(const std::string& injectActionType)
{
static const std::unordered_map<std::string, InjectActionType> actionMap = {
{"click", INJECT_ACTION_TYPE_CLICK},
{"doubleClick", INJECT_ACTION_TYPE_DOUBLE_CLICK},
{"longClick", INJECT_ACTION_TYPE_LONG_CLICK},
{"1", INJECT_ACTION_TYPE_CLICK},
{"2", INJECT_ACTION_TYPE_DOUBLE_CLICK},
{"3", INJECT_ACTION_TYPE_LONG_CLICK}
};
auto it = actionMap.find(injectActionType);
if (it != actionMap.end()) {
return it->second;
}
return INJECT_ACTION_TYPE_INVALID;
}
}
AccessibleAbilityChannel::AccessibleAbilityChannel(
const int32_t accountId, const std::string &clientName, const wptr<AccessibilityAccountData> &accountData)
: clientName_(clientName), accountId_(accountId), accountData_(accountData)
{
eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
Singleton<AccessibleAbilityManagerService>::GetInstance().GetChannelRunner());
}
RetError AccessibleAbilityChannel::SearchElementInfoByAccessibilityId(const ElementBasicInfo elementBasicInfo,
const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
const int32_t mode, bool isFilter, bool systemApi)
{
int32_t treeId = elementBasicInfo.treeId;
int32_t windowId = elementBasicInfo.windowId;
int64_t elementId = elementBasicInfo.elementId;
HILOG_DEBUG("elementId:%{public}" PRId64 " winId: %{public}d treeId: %{public}d", elementId, windowId, treeId);
if (systemApi && !Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("SearchElementInfoByAccessibilityId permission denied.");
return RET_ERR_NO_PERMISSION;
}
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr || callback == nullptr) {
HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
callback != nullptr);
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, syncPromise, windowId, elementId, treeId, requestId,
callback, mode, isFilter]() {
HILOG_DEBUG("search element accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID, clientName,
elementOperator, treeId);
if (ret != RET_OK || !CheckWinFromAwm(windowId, ret)) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
syncPromise->set_value(ret);
if (elementOperator != nullptr) {
HILOG_INFO("before elementOperator release, refCount is [%{public}d]",
elementOperator->GetSptrRefCount());
}
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return;
}
int64_t realElementId = accountData->GetWindowManager().GetSceneBoardElementId(windowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(windowId, treeId, requestId, callback);
ret = elementOperator->SearchElementInfoByAccessibilityId(realElementId, requestId,
callback, mode, isFilter);
if (ret != RET_OK) {
HILOG_ERROR("SearchElementInfoByAccessibilityId IPC Failed.");
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
syncPromise->set_value(ret);
return;
}
HILOG_DEBUG("AccessibleAbilityChannel::SearchElementInfoByAccessibilityId successfully");
syncPromise->set_value(RET_OK);
}, "SearchElementInfoByAccessibilityId");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SearchElementInfoByAccessibilityId result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::SearchDefaultFocusedByWindowId(const ElementBasicInfo elementBasicInfo,
const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
const int32_t mode, bool isFilter)
{
int32_t windowId = elementBasicInfo.windowId;
int64_t elementId = elementBasicInfo.elementId;
int32_t treeId = elementBasicInfo.treeId;
HILOG_DEBUG("elementId:%{public}" PRId64 " winId: %{public}d treeId: %{public}d", elementId, windowId, treeId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr || callback == nullptr) {
HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
callback != nullptr);
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, syncPromise, windowId, elementId, treeId, requestId,
callback, mode, isFilter]() {
HILOG_DEBUG("search element accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID, clientName,
elementOperator, treeId);
if (ret != RET_OK || !CheckWinFromAwm(windowId, ret)) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchDefaultFocusByWindowIdResult(infos, requestId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
syncPromise->set_value(RET_ERR_FAILED);
return;
}
if (windowId == SCENE_BOARD_WINDOW_ID && accountData->GetWindowManager().IsInnerWindowRootElement(elementId)) {
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchDefaultFocusByWindowIdResult(infos, requestId);
} else {
accountData->GetElementOperatorManager().AddRequestId(windowId, treeId, requestId, callback);
elementOperator->SearchDefaultFocusedByWindowId(windowId, requestId, callback, mode, isFilter);
HILOG_DEBUG("AccessibleAbilityChannel::SearchElementInfoByAccessibilityId successfully");
}
syncPromise->set_value(RET_OK);
}, "SearchElementInfoByAccessibilityId");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SearchElementInfoByAccessibilityId result");
return RET_ERR_TIME_OUT;
}
return RET_OK;
}
RetError AccessibleAbilityChannel::SearchElementInfosByText(const int32_t accessibilityWindowId,
const int64_t elementId, const std::string &text, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback, bool systemApi)
{
HILOG_DEBUG("SearchElementInfosByText :channel SearchElementInfo elementId: %{public}" PRId64 " winId: %{public}d",
elementId, accessibilityWindowId);
if (systemApi && !Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
return RET_ERR_NO_PERMISSION;
}
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
if (callback == nullptr) {
HILOG_ERROR("callback is nullptr.");
return RET_ERR_NULLPTR;
}
int32_t treeId = Utils::GetTreeIdBySplitElementId(elementId);
HILOG_DEBUG("SearchElementInfosByText :channel SearchElementInfo treeId: %{public}d", treeId);
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId, text,
requestId, callback]() {
HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
syncPromise->set_value(RET_ERR_FAILED);
return;
}
int64_t realElementId =
accountData->GetWindowManager().GetSceneBoardElementId(accessibilityWindowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(accessibilityWindowId, treeId, requestId, callback);
elementOperator->SearchElementInfosByText(realElementId, text, requestId, callback);
syncPromise->set_value(RET_OK);
}, "SearchElementInfosByText");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SearchElementInfosByText result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::FindFocusedElementInfo(const int32_t accessibilityWindowId,
const int64_t elementId, const int32_t focusType, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback, bool systemApi)
{
HILOG_DEBUG("channel FindFocusedElementInfo elementId: %{public}" PRId64 " winId: %{public}d",
elementId, accessibilityWindowId);
if (systemApi && !Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
return RET_ERR_NO_PERMISSION;
}
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
if (callback == nullptr) {
HILOG_ERROR("callback is nullptr.");
return RET_ERR_NULLPTR;
}
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t treeId = Utils::GetTreeIdBySplitElementId(elementId);
HILOG_DEBUG("FindFocusedElementInfo :channel FindFocusedElementInfo treeId: %{public}d", treeId);
int32_t accountId = accountId_;
std::string clientName = clientName_;
eventHandler_->PostTask([this, accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId,
focusType, requestId, callback]() {
HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, accessibilityWindowId, focusType,
clientName, elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
syncPromise->set_value(RET_ERR_FAILED);
return;
}
int64_t realElementId = ROOT_NODE_ID;
if (treeId <= 0) {
realElementId = accountData->GetWindowManager().GetSceneBoardElementId(accessibilityWindowId, elementId);
}
accountData->GetElementOperatorManager().AddRequestId(accessibilityWindowId, treeId, requestId, callback);
elementOperator->FindFocusedElementInfo(realElementId, focusType, requestId, callback);
syncPromise->set_value(RET_OK);
}, "FindFocusedElementInfo");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait FindFocusedElementInfo result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::FocusMoveSearch(const int32_t accessibilityWindowId, const int64_t elementId,
const int32_t direction, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
bool systemApi)
{
HILOG_DEBUG("FocusMoveSearch :channel FocusMoveSearch elementId: %{public}" PRId64 " winId: %{public}d",
elementId, accessibilityWindowId);
if (systemApi && !Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
return RET_ERR_NO_PERMISSION;
}
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
if (callback == nullptr) {
HILOG_ERROR("callback is nullptr.");
return RET_ERR_NULLPTR;
}
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t treeId = Utils::GetTreeIdBySplitElementId(elementId);
HILOG_DEBUG("FocusMoveSearch :channel FocusMoveSearch treeId: %{public}d", treeId);
int32_t accountId = accountId_;
std::string clientName = clientName_;
eventHandler_->PostTask([this, accountId, clientName, syncPromise, accessibilityWindowId,
elementId, treeId, direction, requestId, callback]() {
HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
std::vector<AccessibilityElementInfo> infos = {};
callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
syncPromise->set_value(RET_ERR_FAILED);
HILOG_ERROR("accountData is nullptr");
return;
}
int64_t realElementId =
accountData->GetWindowManager().GetSceneBoardElementId(accessibilityWindowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(accessibilityWindowId, treeId, requestId, callback);
elementOperator->FocusMoveSearch(realElementId, direction, requestId, callback);
syncPromise->set_value(RET_OK);
}, "FocusMoveSearch");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait FocusMoveSearch result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
void AccessibleAbilityChannel::SetKeyCodeToMmi(std::shared_ptr<MMI::KeyEvent>& keyEvent, const bool isPress,
const int32_t keyCode)
{
HILOG_DEBUG();
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (keyEvent == nullptr) {
HILOG_ERROR("KeyEvent is nullptr");
return;
}
MMI::KeyEvent::KeyItem item;
item.SetPressed(isPress);
item.SetKeyCode(keyCode);
keyEvent->AddKeyItem(item);
keyEvent->SetKeyCode(keyCode);
}
RetError AccessibleAbilityChannel::TransmitActionToMmi(const int32_t action)
{
HILOG_DEBUG("The action is %{public}d", action);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
std::shared_ptr<MMI::KeyEvent> keyEventUp = MMI::KeyEvent::Create();
std::shared_ptr<MMI::KeyEvent> keyEventDown = MMI::KeyEvent::Create();
if (keyEventUp == nullptr || keyEventDown == nullptr) {
HILOG_ERROR("KeyEvent is nullptr");
return RET_ERR_NULLPTR;
}
if (!inputManager_) {
HILOG_ERROR("inputManager_ is nullptr");
return RET_ERR_NULLPTR;
}
HILOG_INFO("Transmit keycode to MMI");
if (accessibleKeyCodeTable.find(action) == accessibleKeyCodeTable.end()) {
HILOG_ERROR("Unrecognized action!");
return RET_ERR_INVALID_PARAM;
}
if (accessibleKeyCodeTable.at(action).first) {
SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.first);
SetKeyCodeToMmi(keyEventUp, false, accessibleKeyCodeTable.at(action).second.first);
} else {
SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.first);
SetKeyCodeToMmi(keyEventUp, false, accessibleKeyCodeTable.at(action).second.first);
SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.second);
}
keyEventDown->SetKeyAction(MMI::KeyEvent::KEY_ACTION_DOWN);
keyEventUp->SetKeyAction(MMI::KeyEvent::KEY_ACTION_UP);
inputManager_->SimulateInputEvent(keyEventDown);
inputManager_->SimulateInputEvent(keyEventUp);
return RET_OK;
}
RetError AccessibleAbilityChannel::EnableScreenCurtain(bool isEnable)
{
HILOG_DEBUG();
auto& aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
aams.PostDelayUnloadTask();
return aams.SetCurtainScreenUsingStatus(isEnable);
}
RetError AccessibleAbilityChannel::HoldRunningLock()
{
HILOG_DEBUG();
if (!Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("HoldRunningLock permission denied.");
return RET_ERR_NO_PERMISSION;
}
#ifdef OHOS_BUILD_ENABLE_POWER_MANAGER
std::string bundleName = "";
if (!Utils::GetBundleNameByCallingUid(bundleName)) {
return RET_ERR_FAILED;
}
if (!Singleton<AccessibilityPowerManager>::GetInstance().HoldRunningLock(bundleName)) {
HILOG_ERROR("Failed to hold running lock.");
return RET_ERR_FAILED;
}
#endif
return RET_OK;
}
RetError AccessibleAbilityChannel::UnholdRunningLock()
{
HILOG_DEBUG();
if (!Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("UnholdRunningLock permission denied.");
return RET_ERR_NO_PERMISSION;
}
#ifdef OHOS_BUILD_ENABLE_POWER_MANAGER
std::string bundleName = "";
if (!Utils::GetBundleNameByCallingUid(bundleName)) {
return RET_ERR_FAILED;
}
auto &powerManager = Singleton<AccessibilityPowerManager>::GetInstance();
if (!powerManager.UnholdRunningLock(bundleName)) {
HILOG_ERROR("Failed to unhold running lock.");
return RET_ERR_FAILED;
}
#endif
return RET_OK;
}
RetError AccessibleAbilityChannel::ExecuteAction(const int32_t accessibilityWindowId, const int64_t elementId,
const int32_t action, const std::map<std::string, std::string> &actionArguments, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback, const Rect &rect)
{
HILOG_DEBUG("ExecuteAction elementId:%{public}" PRId64 " winId:%{public}d, action:%{public}d, requestId:%{public}d",
elementId, accessibilityWindowId, action, requestId);
if (actionArguments.find("sysapi_check_perm") != actionArguments.end()) {
if (!Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("system api permission denied.");
return RET_ERR_NO_PERMISSION;
}
}
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr || callback == nullptr) {
HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
callback != nullptr);
return RET_ERR_NULLPTR;
}
if (accessibleKeyCodeTable.find(action) != accessibleKeyCodeTable.end()) {
RetError ret = TransmitActionToMmi(action);
if (ret != RET_OK) {
HILOG_ERROR("Transmit Action To Mmi failed!");
callback->SetExecuteActionResult(false, requestId);
return RET_ERR_FAILED;
}
callback->SetExecuteActionResult(true, requestId);
return RET_OK;
}
if (action == ActionType::ACCESSIBILITY_ACTION_INJECT_ACTION) {
RetError ret = HandleInjectAction(actionArguments, rect);
if (ret != RET_OK) {
HILOG_ERROR("Handle Inject Click failed!");
callback->SetExecuteActionResult(false, requestId);
return RET_ERR_FAILED;
}
callback->SetExecuteActionResult(true, requestId);
return RET_OK;
}
return ExecuteActionAsync(accessibilityWindowId, elementId, action, actionArguments, requestId, callback);
}
RetError AccessibleAbilityChannel::HandleInjectAction(const std::map<std::string, std::string> &actionArguments,
const Rect &rect)
{
HILOG_DEBUG();
auto it = actionArguments.find("injectActionType");
if (it == actionArguments.end()) {
HILOG_ERROR("HandleInjectAction injectActionType not found in actionArguments");
return RET_ERR_INVALID_PARAM;
}
std::string clickTypeStr = it->second;
HILOG_INFO("HandleInjectAction clickType: %{public}s", clickTypeStr.c_str());
InjectActionType injectActionType = StringToInjectAction(clickTypeStr);
if (injectActionType == INJECT_ACTION_TYPE_INVALID) {
HILOG_ERROR("HandleInjectAction invalid clickType: %{public}s", clickTypeStr.c_str());
return RET_ERR_INVALID_PARAM;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return RET_ERR_FAILED;
}
int32_t xPos = 0;
int32_t yPos = 0;
int32_t windowId = accountData->GetWindowManager().GetActiveWindowId();
if (!accountData->GetElementOperatorManager().CalculateClickPosition(rect, xPos, yPos, windowId)) {
HILOG_ERROR("CalculateClickPosition failed, element is out of window bounds");
return RET_ERR_FAILED;
}
InjectEventToInput(xPos, yPos, injectActionType);
return RET_OK;
}
void AccessibleAbilityChannel::InjectEventToInput(int32_t xPos, int32_t yPos, InjectActionType injectActionType)
{
HILOG_INFO("InjectEventToInput injectActionType: %{public}d, position: [%{public}d, %{public}d]",
injectActionType, xPos, yPos);
if (xPos < 0 || yPos < 0) {
HILOG_ERROR("InjectEventToInput invalid position: [%{public}d, %{public}d]", xPos, yPos);
return;
}
auto injectTouchEvent = [](int32_t x, int32_t y, int32_t action) {
std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
pointerEvent->SetPointerAction(action);
pointerEvent->AddFlag(MMI::InputEvent::EVENT_FLAG_ACCESSIBILITY);
pointerEvent->AddFlag(MMI::InputEvent::EVENT_FLAG_NO_INTERCEPT);
MMI::PointerEvent::PointerItem item;
item.SetDisplayX(x);
item.SetDisplayY(y);
item.SetRawDisplayX(x);
item.SetRawDisplayY(y);
item.SetPointerId(0);
pointerEvent->AddPointerItem(item);
pointerEvent->SetPointerId(0);
MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
};
if (injectActionType == INJECT_ACTION_TYPE_CLICK) {
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_DOWN);
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_UP);
} else if (injectActionType == INJECT_ACTION_TYPE_DOUBLE_CLICK) {
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_DOWN);
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_UP);
std::this_thread::sleep_for(std::chrono::milliseconds(DOUBLE_CLICK_EVENT_INTERVAL));
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_DOWN);
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_UP);
} else if (injectActionType == INJECT_ACTION_TYPE_LONG_CLICK) {
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_DOWN);
std::this_thread::sleep_for(std::chrono::milliseconds(LONG_PRESS_EVENT_INTERVAL));
injectTouchEvent(xPos, yPos, MMI::PointerEvent::POINTER_ACTION_UP);
}
}
RetError AccessibleAbilityChannel::ExecuteActionAsync(const int32_t accessibilityWindowId, const int64_t elementId,
const int32_t action, const std::map<std::string, std::string> &actionArguments, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback)
{
SetFocusWindowIdAndElementId(accessibilityWindowId, elementId, action);
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t treeId = Utils::GetTreeIdBySplitElementId(elementId);
int32_t accountId = accountId_;
std::string clientName = clientName_;
eventHandler_->PostTask([this, accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId, action,
actionArguments, requestId, callback]() {
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, clientName,
elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
syncPromise->set_value(RET_ERR_FAILED);
return;
}
int32_t realElementId =
accountData->GetWindowManager().GetSceneBoardElementId(accessibilityWindowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(accessibilityWindowId, treeId, requestId, callback);
elementOperator->ExecuteAction(realElementId, action, actionArguments, requestId, callback);
syncPromise->set_value(RET_OK);
}, "ExecuteAction");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_1000MS));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait ExecuteAction result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
void AccessibleAbilityChannel::SetFocusWindowIdAndElementId(const int32_t accessibilityWindowId,
const int64_t elementId, const int32_t action)
{
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
return;
}
auto& awm = Singleton<AccessibleAbilityManagerService>::GetInstance();
if ((action == ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS)) {
accountData->GetElementOperatorManager().SetFocusWindowId(accessibilityWindowId);
accountData->GetElementOperatorManager().SetFocusElementId(elementId);
} else if (action == ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS) {
accountData->GetElementOperatorManager().SetFocusWindowId(WINDOW_ID_INVALID);
accountData->GetElementOperatorManager().SetFocusElementId(ELEMENT_ID_INVALID);
}
}
RetError AccessibleAbilityChannel::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
{
HILOG_DEBUG("windowId:%{public}d", windowId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
std::shared_ptr<AccessibilityWindowInfo> tmpWindowInfo = std::make_shared<AccessibilityWindowInfo>(windowInfo);
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, windowId, tmpWindowInfo, syncPromise]() {
HILOG_DEBUG("windowId:%{public}d", windowId);
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
syncPromise->set_value(RET_ERR_NO_CONNECTION);
return;
}
if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
HILOG_ERROR("AccessibleAbilityChannel::GetWindow failed: no capability");
syncPromise->set_value(RET_ERR_NO_CAPABILITY);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
syncPromise->set_value(RET_ERR_NULLPTR);
return;
}
if (accountData->GetWindowManager().GetAccessibilityWindow(windowId, *tmpWindowInfo)) {
syncPromise->set_value(RET_OK);
} else {
syncPromise->set_value(RET_ERR_NO_WINDOW_CONNECTION);
}
}, "GetWindow");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait GetWindow result");
return RET_ERR_TIME_OUT;
}
windowInfo = *tmpWindowInfo;
return syncFuture.get();
}
RetError AccessibleAbilityChannel::GetWindows(std::vector<AccessibilityWindowInfo> &windows, bool systemApi)
{
HILOG_DEBUG();
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
uint64_t displayId = Singleton<ExtendManagerServiceProxy>::GetInstance().GetDefaultDisplayId();
return GetWindows(displayId, windows, systemApi);
}
RetError AccessibleAbilityChannel::GetWindowsByDisplayId(const uint64_t displayId,
std::vector<AccessibilityWindowInfo> &windows, bool systemApi)
{
HILOG_DEBUG();
return GetWindows(displayId, windows, systemApi);
}
RetError AccessibleAbilityChannel::GetWindows(uint64_t displayId, std::vector<AccessibilityWindowInfo> &windows,
bool systemApi) const
{
if (systemApi && !Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
return RET_ERR_NO_PERMISSION;
}
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
auto tmpWindows = std::make_shared<std::vector<AccessibilityWindowInfo>>(windows);
int32_t accountId = accountId_;
std::string clientName = clientName_;
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, displayId, tmpWindows, syncPromise]() {
HILOG_DEBUG();
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
syncPromise->set_value(RET_ERR_NO_CONNECTION);
return;
}
if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
HILOG_ERROR("GetWindows failed: no capability");
syncPromise->set_value(RET_ERR_NO_CAPABILITY);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
syncPromise->set_value(RET_ERR_FAILED);
return;
}
std::vector<AccessibilityWindowInfo> windowInfos = accountData->GetWindowManager().GetAccessibilityWindows();
#ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
for (auto &window : windowInfos) {
if (window.GetDisplayId() == displayId) {
tmpWindows->emplace_back(window);
}
}
#else
for (auto &window : windowInfos) {
tmpWindows->emplace_back(window);
}
#endif
syncPromise->set_value(RET_OK);
}, "GetWindows");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait GetWindows result");
return RET_ERR_TIME_OUT;
}
windows = *tmpWindows;
return syncFuture.get();
}
void AccessibleAbilityChannel::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
{
HILOG_DEBUG();
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
eventHandler_->PostTask([this, accountId, clientName, handled, sequence]() {
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
return;
}
Singleton<ExtendManagerServiceProxy>::GetInstance().SetServiceOnKeyEventResult(
clientConnection->GetChannelId(), handled, sequence);
}, "SetOnKeyPressEventResult");
}
RetError AccessibleAbilityChannel::GetCursorPosition(const int32_t accessibilityWindowId, const int64_t elementId,
const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
{
HILOG_DEBUG("GetCursorPosition :channel GetCursorPosition elementId: %{public}" PRId64 " winId: %{public}d",
elementId, accessibilityWindowId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t treeId = Utils::GetTreeIdBySplitElementId(elementId);
HILOG_DEBUG("GetCursorPosition :channel GetCursorPosition treeId: %{public}d", treeId);
int32_t accountId = accountId_;
std::string clientName = clientName_;
eventHandler_->PostTask([this, accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId,
requestId, callback]() {
HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, clientName,
elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return;
}
int64_t realElementId =
accountData->GetWindowManager().GetSceneBoardElementId(accessibilityWindowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(accessibilityWindowId, treeId, requestId, callback);
elementOperator->GetCursorPosition(realElementId, requestId, callback);
syncPromise->set_value(RET_OK);
}, "GetCursorPosition");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait GetCursorPosition result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::SendSimulateGesture(
const std::shared_ptr<AccessibilityGestureInjectPath>& gesturePath)
{
HILOG_INFO();
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, gesturePath, syncPromise]() {
HILOG_DEBUG();
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
syncPromise->set_value(RET_ERR_NO_CONNECTION);
return;
}
if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_GESTURE)) {
HILOG_ERROR("AccessibleAbilityChannel::SendSimulateGesture failed: no capability");
syncPromise->set_value(RET_ERR_NO_CAPABILITY);
return;
}
if (Singleton<ExtendManagerServiceProxy>::GetInstance().LoadExtProxy()) {
RetError ret = Singleton<ExtendManagerServiceProxy>::GetInstance().InjectEvents(gesturePath);
if (ret != RET_OK) {
syncPromise->set_value(RET_ERR_NO_INJECTOR);
return;
}
}
syncPromise->set_value(RET_OK);
}, "SendSimulateGesture");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SendSimulateGesture result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
{
HILOG_DEBUG();
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_== nullptr) {
HILOG_ERROR("eventHandler_ is nullptr");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, targetBundleNames, syncPromise]() {
HILOG_DEBUG();
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
syncPromise->set_value(RET_ERR_NO_CONNECTION);
return;
}
clientConnection->SetAbilityInfoTargetBundleName(targetBundleNames);
syncPromise->set_value(RET_OK);
}, "SetTargetBundleName");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SetTargetBundleName result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
sptr<AccessibleAbilityConnection> AccessibleAbilityChannel::GetConnection(
int32_t accountId, const std::string &clientName) const
{
HILOG_DEBUG();
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return nullptr;
}
HILOG_DEBUG("accountId[%{public}d] clientName[%{public}s]", accountId, clientName.c_str());
return accountData->GetAccessibleAbilityConnection(clientName);
}
RetError AccessibleAbilityChannel::GetElementOperator(
int32_t accountId, int32_t windowId, int32_t focusType, const std::string &clientName,
sptr<IAccessibilityElementOperator> &elementOperator, const int32_t treeId)
{
HILOG_DEBUG();
elementOperator = nullptr;
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
if (!clientConnection) {
HILOG_ERROR("There is no client connection");
return RET_ERR_NO_CONNECTION;
}
if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
HILOG_ERROR("the client has no retieve capability");
return RET_ERR_NO_CAPABILITY;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return RET_ERR_NULLPTR;
}
auto [realId, displayId] = accountData->GetWindowManager().ConvertToRealWindowId(windowId, focusType);
sptr<AccessibilityWindowConnection> connection = accountData->GetAccessibilityWindowConnection(realId);
if (connection == nullptr) {
HILOG_ERROR("windowId[%{public}d] has no connection", realId);
return RET_ERR_NO_WINDOW_CONNECTION;
}
bool isAnco = connection->IsAnco();
bool useBroker = connection->GetUseBrokerFlag();
bool hasMultipleProxies = (connection->GetCardProxySize() > 1);
if (!useBroker && treeId > 0) {
elementOperator = connection->GetCardProxy(treeId);
} else if (isAnco && useBroker && treeId > 0
&& connection->GetCardProxy(treeId)) {
elementOperator = connection->GetCardProxy(treeId);
} else if (isAnco && useBroker && treeId == 0
&& hasMultipleProxies && connection->GetCardProxy(treeId)) {
elementOperator = connection->GetCardProxy(treeId);
} else {
elementOperator = connection->GetProxy(displayId);
}
if (!elementOperator) {
HILOG_ERROR("The proxy of window connection is nullptr");
return RET_ERR_NULLPTR;
}
return RET_OK;
}
bool AccessibleAbilityChannel::CheckWinFromAwm(const int32_t windowId, const int32_t getElementOperatorResult)
{
HILOG_DEBUG("CheckWinFromAwm window: %{public}d, ConnectResult: [%{public}d]", windowId, getElementOperatorResult);
if (windowId == SCENE_BOARD_WINDOW_ID && getElementOperatorResult == RET_OK) {
return true;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
return false;
}
std::vector<AccessibilityWindowInfo> windows = accountData->GetWindowManager().GetAccessibilityWindows();
if (!windows.empty()) {
for (const auto& window: windows) {
if (windowId == window.GetWindowId()) {
return true;
}
}
}
return false;
}
RetError AccessibleAbilityChannel::SetIsRegisterDisconnectCallback(bool isRegister)
{
HILOG_INFO();
if (!Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("SetIsRegisterDisconnectCallback permission denied.");
return RET_ERR_NO_PERMISSION;
}
sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId_, clientName_);
if (clientConnection == nullptr) {
HILOG_ERROR("GetConnection failed, clientName: %{public}s", clientName_.c_str());
return RET_ERR_NULLPTR;
}
clientConnection->SetIsRegisterDisconnectCallback(isRegister);
return RET_OK;
}
RetError AccessibleAbilityChannel::NotifyDisconnect()
{
HILOG_INFO();
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (accountData == nullptr) {
HILOG_ERROR("accountData is nullptr");
return RET_ERR_NULLPTR;
}
sptr<AccessibleAbilityConnection> clientConnection =
accountData_->GetAccessibleAbilityManager().GetWaitDisConnectAbility(clientName_);
if (clientConnection == nullptr) {
HILOG_ERROR("GetConnection failed, clientName: %{public}s", clientName_.c_str());
return RET_ERR_NULLPTR;
}
accountData_->GetAccessibleAbilityManager().RemoveWaitDisconnectAbility(clientName_);
clientConnection->NotifyDisconnect();
return RET_OK;
}
void AccessibleAbilityChannel::SearchElementInfoBySpecificProperty(const ElementBasicInfo elementBasicInfo,
const SpecificPropertyParam& param, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback)
{
int32_t treeId = elementBasicInfo.treeId;
int32_t windowId = elementBasicInfo.windowId;
int64_t elementId = elementBasicInfo.elementId;
HILOG_DEBUG("elementId:%{public}" PRId64 " winId: %{public}d treeId: %{public}d "
"propertyTarget:%{public}s propertyType:%{public}u",
elementId, windowId, treeId, param.propertyTarget.c_str(), static_cast<uint32_t>(param.propertyType));
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr || callback == nullptr) {
HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
callback != nullptr);
return;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, syncPromise, windowId, elementId, treeId, requestId,
callback, param]() {
HILOG_DEBUG("search element accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID, clientName,
elementOperator, treeId);
if (ret != RET_OK || !CheckWinFromAwm(windowId, ret)) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
std::list<AccessibilityElementInfo> infos = {};
std::list<AccessibilityElementInfo> treeInfos = {};
callback->SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
syncPromise->set_value(ret);
return;
}
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return;
}
if (windowId == SCENE_BOARD_WINDOW_ID && accountData->GetWindowManager().IsInnerWindowRootElement(elementId)) {
std::list<AccessibilityElementInfo> infos = {};
std::list<AccessibilityElementInfo> treeInfos = {};
callback->SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
HILOG_DEBUG("IsInnerWindowRootElement elementId: %{public}" PRId64 "", elementId);
} else {
int64_t realElementId = accountData->GetWindowManager().GetSceneBoardElementId(windowId, elementId);
accountData->GetElementOperatorManager().AddRequestId(windowId, treeId, requestId, callback);
elementOperator->SearchElementInfoBySpecificProperty(realElementId, param, requestId, callback);
HILOG_DEBUG("AccessibleAbilityChannel::SearchElementInfosBySpecificProperty successfully");
}
syncPromise->set_value(RET_OK);
}, "SearchElementInfosBySpecificProperty");
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return;
}
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
accountData->GetElementOperatorManager().RemoveRequestId(requestId);
HILOG_ERROR("Failed to wait SearchElementInfosBySpecificProperty result");
return;
}
}
RetError AccessibleAbilityChannel::ConfigureEvents(const std::vector<uint32_t> needEvents)
{
HILOG_INFO();
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
return RET_ERR_FAILED;
}
RetError ret = accountData->ConfigureEvents(needEvents);
if (ret != RET_OK) {
HILOG_ERROR("Configure Events failed!");
return RET_ERR_FAILED;
}
return RET_OK;
}
RetError AccessibleAbilityChannel::FocusMoveSearchWithCondition(const AccessibilityElementInfo &elementInfo,
const AccessibilityFocusMoveParam ¶m, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback, int32_t windowId)
{
HILOG_DEBUG("requestId: %{public}d, windowId: %{public}d", requestId, windowId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr || callback == nullptr) {
HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
callback != nullptr);
return RET_ERR_NULLPTR;
}
if (!Singleton<AccessibleAbilityManagerService>::GetInstance().CheckPermission(
OHOS_PERMISSION_ACCESSIBILITY_EXTENSION_ABILITY)) {
HILOG_WARN("SearchElementInfoByAccessibilityId permission denied.");
return RET_ERR_NO_PERMISSION;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
eventHandler_->PostTask([this, accountId, clientName, syncPromise, windowId, elementInfo,
requestId, callback, param]() {
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
int32_t treeId = elementInfo.GetBelongTreeId();
sptr<AccessibilityAccountData> accountData = accountData_.promote();
if (!accountData) {
HILOG_ERROR("accountData is nullptr");
return;
}
if (param.detectParent) {
int64_t parentId = -1;
accountData->GetElementOperatorManager().GetRootParentId(windowId, treeId, parentId);
const_cast<AccessibilityFocusMoveParam&>(param).SetParentId(parentId);
treeId = Utils::GetTreeIdBySplitElementId(parentId);
HILOG_DEBUG("requestId: %{public}d, treeId: %{public}d", requestId, treeId);
}
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, treeId);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! windowId[%{public}d]", windowId);
std::list<AccessibilityElementInfo> infos;
FocusMoveResult result;
callback->SetFocusMoveSearchWithConditionResult(infos, result, requestId);
syncPromise->set_value(ret);
return;
}
accountData->GetElementOperatorManager().AddRequestId(windowId, treeId, requestId, callback);
elementOperator->FocusMoveSearchWithCondition(elementInfo, param, requestId, callback);
syncPromise->set_value(RET_OK);
}, "FocusMoveSearchWithCondition");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait SearchElementInfosByText result, requestId: %{public}d", requestId);
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::UpdateCustomAccessibilityProperty(const int64_t elementId,
const int32_t windowId, const AccessibilityVirtualNode& accessibilityVirtualNode, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback)
{
HILOG_DEBUG("elementId[%{public}" PRId64 "], windowId[%{public}d], requestId[%{public}d]",
elementId, windowId, requestId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t tree = Utils::GetTreeIdBySplitElementId(elementId);
eventHandler_->PostTask([accountId, clientName, syncPromise, windowId, elementId, tree,
accessibilityVirtualNode, requestId, callback, this]() {
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, tree);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
if (callback != nullptr) {
callback->SetUpdateCustomAccessibilityPropertyResult(
OperateVirtualNodeResult::ACCESSIBILITY_ELEMENT_NOT_EXIST, requestId);
}
syncPromise->set_value(ret);
return;
}
auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
int64_t realElementId = awm.GetSceneBoardElementId(windowId, elementId);
elementOperator->UpdateCustomAccessibilityProperty(realElementId, accessibilityVirtualNode,
requestId, callback);
syncPromise->set_value(RET_OK);
}, "UpdateCustomAccessibilityProperty");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait UpdateCustomAccessibilityProperty result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::AddAccessibilityVirtualNode(const int64_t rootId,
const int32_t windowId, const std::vector<AccessibilityVirtualNode> &nodes, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback)
{
HILOG_DEBUG("rootId[%{public}" PRId64 "], windowId[%{public}d], requestId[%{public}d]",
rootId, windowId, requestId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t tree = Utils::GetTreeIdBySplitElementId(rootId);
eventHandler_->PostTask([accountId, clientName, syncPromise, windowId, rootId, tree,
nodes, requestId, callback, this]() {
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, tree);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
if (callback != nullptr) {
callback->SetAddAccessibilityVirtualNodeResult(
OperateVirtualNodeResult::ACCESSIBILITY_ELEMENT_NOT_EXIST, requestId);
}
syncPromise->set_value(ret);
return;
}
auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
int64_t realRootId = awm.GetSceneBoardElementId(windowId, rootId);
elementOperator->AddAccessibilityVirtualNode(realRootId, nodes, requestId, callback);
syncPromise->set_value(RET_OK);
}, "AddAccessibilityVirtualNode");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait AddAccessibilityVirtualNode result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
RetError AccessibleAbilityChannel::RemoveAccessibilityVirtualNode(const int64_t id,
const int32_t windowId, const int32_t requestId,
const sptr<IAccessibilityElementOperatorCallback> &callback)
{
HILOG_DEBUG("id[%{public}" PRId64 "], windowId[%{public}d], requestId[%{public}d]",
id, windowId, requestId);
Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
if (eventHandler_ == nullptr) {
HILOG_ERROR("eventHandler_ is nullptr.");
return RET_ERR_NULLPTR;
}
int32_t accountId = accountId_;
std::string clientName = clientName_;
std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
ffrt::future syncFuture = syncPromise->get_future();
int32_t tree = Utils::GetTreeIdBySplitElementId(id);
eventHandler_->PostTask([accountId, clientName, syncPromise, windowId, id, tree,
requestId, callback, this]() {
sptr<IAccessibilityElementOperator> elementOperator = nullptr;
RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID,
clientName, elementOperator, tree);
if (ret != RET_OK) {
HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
if (callback != nullptr) {
callback->SetRemoveAccessibilityVirtualNodeResult(
OperateVirtualNodeResult::ACCESSIBILITY_ELEMENT_NOT_EXIST, requestId);
}
syncPromise->set_value(ret);
return;
}
auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
int64_t realId = awm.GetSceneBoardElementId(windowId, id);
elementOperator->RemoveAccessibilityVirtualNode(realId, requestId, callback);
syncPromise->set_value(RET_OK);
}, "RemoveAccessibilityVirtualNode");
ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
if (wait != ffrt::future_status::ready) {
HILOG_ERROR("Failed to wait RemoveAccessibilityVirtualNode result");
return RET_ERR_TIME_OUT;
}
return syncFuture.get();
}
}
}