* Copyright (c) 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 "cj_accessibility_utils.h"
#include <cstdint>
#include "cj_common_ffi.h"
#include "cj_accessibility_ffi.h"
#include "accessibility_system_ability_client.h"
#include "accessibility_def.h"
#include "accessibility_utils.h"
#include "securec.h"
#include "native/ffi_remote_data.h"
namespace OHOS {
namespace Accessibility {
namespace Utils {
char *MallocCString(const std::string &origin, RetError &errCode)
{
if (origin.empty() || errCode == RET_ERR_FAILED) {
return nullptr;
}
auto len = origin.length() + 1;
char *res = static_cast<char *>(malloc(sizeof(char) * len));
if (res == nullptr) {
HILOG_ERROR("MallocCString malloc failed");
errCode = RET_ERR_FAILED;
return nullptr;
}
return std::char_traits<char>::copy(res, origin.c_str(), len);
}
CArrString VectorToCArrString(std::vector<std::string> &vec, RetError &errCode)
{
if (vec.size() == 0 || errCode == RET_ERR_FAILED) {
return { nullptr, 0 };
}
char **result = new char *[vec.size()];
if (result == nullptr) {
HILOG_ERROR("VectorToCArrString malloc failed");
errCode = RET_ERR_NULLPTR;
return { nullptr, 0 };
}
size_t temp = 0;
for (size_t i = 0; i < vec.size(); i++) {
result[i] = new char[vec[i].length() + 1];
if (result[i] == nullptr) {
break;
}
auto res = strcpy_s(result[i], vec[i].length() + 1, vec[i].c_str());
if (res != EOK) {
errCode = RET_ERR_FAILED;
HILOG_ERROR("failed to strcpy_s.");
}
temp++;
}
if (temp != vec.size()) {
for (size_t j = temp; j > 0; j--) {
delete[] result[j - 1];
result[j - 1] = nullptr;
}
delete[] result;
errCode = RET_ERR_FAILED;
return { nullptr, 0 };
}
return { result, vec.size() };
}
std::vector<std::string> CArrStringToVector(CArrString cArrStr)
{
std::vector<std::string> vec;
if (cArrStr.head == nullptr || cArrStr.size <= 0) {
return vec;
}
for (size_t i = 0; i < static_cast<size_t>(cArrStr.size); i++) {
if (cArrStr.head[i] != nullptr) {
vec.emplace_back(cArrStr.head[i]);
}
}
return vec;
}
CArrString GetAbilityTypesStr(uint32_t abilityTypes, RetError &errCode)
{
std::vector<std::string> abilityTypesStr;
for (auto [key, val] : abilityTypeMap) {
if (abilityTypes & key) {
abilityTypesStr.push_back(val);
}
}
return VectorToCArrString(abilityTypesStr, errCode);
}
CArrString GetCapabilityStr(uint32_t capabilities, RetError &errCode)
{
std::vector<std::string> capabilityStr;
for (auto [key, val] : capabilityMap) {
if (capabilities & key) {
capabilityStr.push_back(val);
}
}
return VectorToCArrString(capabilityStr, errCode);
}
CArrString GetEventTypeStr(uint32_t eventType, RetError &errCode)
{
std::vector<std::string> eventTypeStr;
if ((eventType < EventType::TYPE_VIEW_CLICKED_EVENT) ||
((eventType >= EventType::TYPE_MAX_NUM) && (eventType != EventType::TYPES_ALL_MASK))) {
errCode = RET_ERR_FAILED;
return VectorToCArrString(eventTypeStr, errCode);
}
for (auto [key, val] : eventTypeMap) {
if (eventType & key) {
eventTypeStr.push_back(val);
}
}
return VectorToCArrString(eventTypeStr, errCode);
}
CAccessibilityAbilityInfo ConvertAccAbilityInfo2C(AccessibilityAbilityInfo &abilityInfo, RetError &errCode)
{
CAccessibilityAbilityInfo cAbility;
cAbility.id_ = MallocCString(abilityInfo.GetId(), errCode);
cAbility.name_ = MallocCString(abilityInfo.GetName(), errCode);
cAbility.bundleName_ = MallocCString(abilityInfo.GetPackageName(), errCode);
std::vector<std::string> bundleNames(abilityInfo.GetFilterBundleNames());
cAbility.targetBundleNames_ = VectorToCArrString(bundleNames, errCode);
cAbility.abilityTypes_ = GetAbilityTypesStr(abilityInfo.GetAccessibilityAbilityType(), errCode);
cAbility.capabilities_ = GetCapabilityStr(abilityInfo.GetCapabilityValues(), errCode);
cAbility.description_ = MallocCString(abilityInfo.GetDescription(), errCode);
cAbility.eventTypes_ = GetEventTypeStr(abilityInfo.GetEventTypes(), errCode);
cAbility.needHide_ = abilityInfo.NeedHide();
cAbility.label_ = MallocCString(abilityInfo.GetLabel(), errCode);
return cAbility;
}
void FreecAbility(CAccessibilityAbilityInfo *cAbility)
{
free(cAbility->id_);
cAbility->id_ = nullptr;
free(cAbility->name_);
cAbility->name_ = nullptr;
free(cAbility->bundleName_);
cAbility->bundleName_ = nullptr;
free(cAbility->description_);
cAbility->description_ = nullptr;
free(cAbility->label_);
cAbility->label_ = nullptr;
for (auto i = 0; i < cAbility->targetBundleNames_.size; i++) {
free(cAbility->targetBundleNames_.head[i]);
}
free(cAbility->targetBundleNames_.head);
cAbility->targetBundleNames_.head = nullptr;
for (auto i = 0; i < cAbility->abilityTypes_.size; i++) {
free(cAbility->abilityTypes_.head[i]);
}
free(cAbility->abilityTypes_.head);
cAbility->abilityTypes_.head = nullptr;
for (auto i = 0; i < cAbility->capabilities_.size; i++) {
free(cAbility->capabilities_.head[i]);
}
free(cAbility->capabilities_.head);
cAbility->capabilities_.head = nullptr;
for (auto i = 0; i < cAbility->eventTypes_.size; i++) {
free(cAbility->eventTypes_.head[i]);
}
free(cAbility->eventTypes_.head);
cAbility->eventTypes_.head = nullptr;
}
CArrAccessibilityAbilityInfo ConvertArrAccAbilityInfo2CArr(std::vector<AccessibilityAbilityInfo> &abilityList,
RetError &errCode)
{
CArrAccessibilityAbilityInfo cArrAbility;
cArrAbility.size = static_cast<int64_t>(abilityList.size());
if (cArrAbility.size == 0) {
return cArrAbility;
}
int64_t mallocSize = static_cast<int64_t>(sizeof(CAccessibilityAbilityInfo)) * cArrAbility.size;
CAccessibilityAbilityInfo *cAbility = static_cast<CAccessibilityAbilityInfo *>(malloc(mallocSize));
if (cAbility == nullptr) {
errCode = RET_ERR_NULLPTR;
return cArrAbility;
}
memset_s(cAbility, mallocSize, 0, mallocSize);
for (auto i = 0; i < cArrAbility.size; ++i) {
cAbility[i] = ConvertAccAbilityInfo2C(abilityList[i], errCode);
if (errCode != RET_OK) {
for (auto j = 0; j < i; j++) {
FreecAbility(&cAbility[j]);
}
free(cAbility);
cAbility = nullptr;
HILOG_ERROR("ConvertAccAbilityInfo2C failed.");
return cArrAbility;
}
}
cArrAbility.head = cAbility;
return cArrAbility;
}
CEventInfo ConvertEventInfo2C(const AccessibilityEventInfo &eventInfo, RetError &errCode)
{
CEventInfo cEventInfo;
auto eventTypeStr = GetStrFromVal(Utils::eventTypeMap, eventInfo.GetEventType(), errCode, "accessibilityFocus");
cEventInfo.type_ = MallocCString(eventTypeStr, errCode);
auto windowTypeStr = GetStrFromVal(Utils::windowUpdateTypeMap, eventInfo.GetWindowChangeTypes(), errCode, "add");
cEventInfo.windowUpdateType_ = MallocCString(windowTypeStr, errCode);
cEventInfo.bundleName_ = MallocCString(eventInfo.GetBundleName(), errCode);
cEventInfo.componentType_ = MallocCString(eventInfo.GetComponentType(), errCode);
cEventInfo.pageId_ = eventInfo.GetPageId();
cEventInfo.description_ = MallocCString(eventInfo.GetDescription(), errCode);
auto actionStr = GetStrFromVal(Utils::actionMap, eventInfo.GetTriggerAction(), errCode, "click");
cEventInfo.triggerAction_ = MallocCString(actionStr, errCode);
auto textMoveStr = GetStrFromVal(Utils::textMoveUnitMap, eventInfo.GetTextMovementStep(), errCode, "char");
cEventInfo.textMoveUnit_ = MallocCString(textMoveStr, errCode);
auto contVec = eventInfo.GetContentList();
cEventInfo.contents_ = VectorToCArrString(contVec, errCode);
cEventInfo.lastContent_ = MallocCString(eventInfo.GetLatestContent(), errCode);
cEventInfo.beginIndex_ = eventInfo.GetBeginIndex();
cEventInfo.currentIndex_ = eventInfo.GetCurrentIndex();
cEventInfo.endIndex_ = eventInfo.GetEndIndex();
cEventInfo.itemCount_ = eventInfo.GetItemCounts();
cEventInfo.elementId_ = eventInfo.GetAccessibilityId();
cEventInfo.textAnnouncedForAccessibility_ = MallocCString(eventInfo.GetTextAnnouncedForAccessibility(), errCode);
cEventInfo.customId_ = MallocCString(eventInfo.GetInspectorKey(), errCode);
return cEventInfo;
}
AccessibilityEventInfo ConvertEventInfo(const CEventInfo &cEventInfo, RetError &errCode)
{
AccessibilityEventInfo eventInfo;
std::string typeStr(cEventInfo.type_);
eventInfo.SetEventType(Utils::GetValueFromStr(rEventTypeMap, typeStr, errCode, TYPE_VIEW_INVALID));
std::string windowTypeStr(cEventInfo.windowUpdateType_);
eventInfo.SetWindowChangeTypes(
Utils::GetValueFromStr(rWindowUpdateTypeMap, windowTypeStr, errCode, WINDOW_UPDATE_ADDED));
std::string bundleStr(cEventInfo.bundleName_);
eventInfo.SetBundleName(bundleStr);
std::string compTypeStr(cEventInfo.componentType_);
eventInfo.SetComponentType(compTypeStr);
eventInfo.SetPageId(cEventInfo.pageId_);
std::string descStr(cEventInfo.description_);
eventInfo.SetDescription(descStr);
std::string actStr(cEventInfo.triggerAction_);
eventInfo.SetTriggerAction(Utils::GetValueFromStr(rActionMap, actStr, errCode, ACCESSIBILITY_ACTION_CLICK));
std::string textStr(cEventInfo.textMoveUnit_);
eventInfo.SetTextMovementStep(Utils::GetValueFromStr(rTextMoveUnitMap, textStr, errCode, STEP_CHARACTER));
std::vector<std::string> contStr = CArrStringToVector(cEventInfo.contents_);
for (const auto &cont : contStr) {
eventInfo.AddContent(cont);
}
std::string lastStr(cEventInfo.lastContent_);
eventInfo.SetLatestContent(lastStr);
eventInfo.SetBeginIndex(cEventInfo.beginIndex_);
eventInfo.SetCurrentIndex(cEventInfo.currentIndex_);
eventInfo.SetEndIndex(cEventInfo.endIndex_);
eventInfo.SetItemCounts(cEventInfo.itemCount_);
eventInfo.SetSource(cEventInfo.elementId_);
std::string textForStr(cEventInfo.textAnnouncedForAccessibility_);
eventInfo.SetTextAnnouncedForAccessibility(textForStr);
std::string custStr(cEventInfo.customId_);
eventInfo.SetInspectorKey(custStr);
return eventInfo;
}
}
}
}