!1533 SetSearchElementInfoByAccessibilityReult接口改为使用RawData传递数据

Merge pull request !1533 from taojuncun/bug_1113_01
This commit is contained in:
openharmony_ci 2024-11-14 04:00:50 +00:00 committed by Gitee
commit 51bcd80a70
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 162 additions and 249 deletions

View File

@ -100,8 +100,6 @@ private:
bool SendTransactCmd(AccessibilityInterfaceCode code, MessageParcel &data,
MessageParcel &reply, MessageOption &option);
int32_t GetTransmitFlag(int32_t time, int32_t leftSize);
static inline BrokerDelegator<AccessibilityElementOperatorCallbackProxy> delegator;
};
} // namespace Accessibility

View File

@ -23,19 +23,6 @@
namespace OHOS {
namespace Accessibility {
class StoreElementData {
public:
StoreElementData() = default;
~StoreElementData() = default;
void WriteData(std::vector<AccessibilityElementInfo> &infos);
std::vector<AccessibilityElementInfo> ReadData();
size_t Size();
void Clear();
std::vector<AccessibilityElementInfo> storeData_ = {};
ffrt::mutex mutex_;
};
/*
* The class define the interface for UI to implement.
* It triggered by ABMS when AA to request the accessibility information.
@ -63,7 +50,6 @@ public:
virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option) override;
static StoreElementData storeElementData;
private:
/**
* @brief Handle the IPC request for the function:SetSearchElementInfoByAccessibilityIdResult.

View File

@ -20,8 +20,7 @@
namespace OHOS {
namespace Accessibility {
constexpr int32_t IPC_MEMORY_SIZE = 500 * 1024; // default size is 200 * 1024B, batch query need more memory
constexpr int32_t SINGLE_TRANSMIT = -2;
constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
constexpr int32_t DATA_NUMBER_ONE_TIME = 400;
@ -60,77 +59,57 @@ bool AccessibilityElementOperatorCallbackProxy::SendTransactCmd(AccessibilityInt
return true;
}
int32_t AccessibilityElementOperatorCallbackProxy::GetTransmitFlag(int32_t time, int32_t leftSize)
{
int32_t flag = time;
if (time == 0 && leftSize <= DATA_NUMBER_ONE_TIME) {
flag = SINGLE_TRANSMIT;
} else if (leftSize <= DATA_NUMBER_ONE_TIME) {
flag = MULTI_TRANSMIT_FINISH;
}
return flag;
}
void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
{
HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
int32_t leftSize = static_cast<int32_t>(infos.size());
int32_t time = 0;
int32_t index = 0;
while (leftSize >= 0) {
MessageParcel data;
MessageParcel reply;
MessageOption type = MessageOption::TF_SYNC;
if (leftSize <= DATA_NUMBER_ONE_TIME) {
type = MessageOption::TF_ASYNC;
}
MessageOption option(type);
data.SetMaxCapacity(IPC_MEMORY_SIZE);
// when infos size is a multi of 800, do not send the last empty reply
if (leftSize == 0 && time > 0) {
return;
}
if (!WriteInterfaceToken(data)) {
return;
}
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("connection write token failed");
return;
}
int32_t flag = GetTransmitFlag(time, leftSize);
if (!data.WriteInt32(flag)) {
return;
}
if (!data.WriteInt32(requestId)) {
HILOG_ERROR("connection write request id failed");
return;
}
int32_t writeSize = (leftSize <= DATA_NUMBER_ONE_TIME) ? leftSize : DATA_NUMBER_ONE_TIME;
if (!data.WriteInt32(writeSize)) {
return;
}
if (!data.WriteUint32(infos.size())) {
HILOG_ERROR("write infos's size failed");
return;
}
for (int32_t i = 0; i < writeSize; ++i) {
AccessibilityElementInfoParcel infoParcel(infos[index]);
index++;
if (!data.WriteParcelable(&infoParcel)) {
HILOG_ERROR("accessibility element info failed index %{public}d", index);
return;
}
}
if (!data.WriteInt32(requestId)) {
return;
}
if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
HILOG_ERROR("set search element info by accessibility id result failed");
return;
}
leftSize -= DATA_NUMBER_ONE_TIME;
time++;
if (static_cast<RetError>(reply.ReadInt32()) != RET_OK) {
MessageParcel tmpParcel;
tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
// when set pracel's max capacity, it won't alloc memory immediately
// MessageParcel will expand memory dynamiclly
for (const auto &info : infos) {
AccessibilityElementInfoParcel infoParcel(info);
if (!tmpParcel.WriteParcelable(&infoParcel)) {
HILOG_ERROR("write accessibilityElementInfoParcel failed");
return;
}
}
size_t tmpParcelSize = tmpParcel.GetDataSize();
if (!data.WriteUint32(tmpParcelSize)) {
HILOG_ERROR("write rawData size failed");
return;
}
if (!data.WriteRawData(reinterpret_cast<uint8_t *>(tmpParcel.GetData()), tmpParcelSize)) {
HILOG_ERROR("write rawData failed");
return;
}
if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
HILOG_ERROR("setSearchElementInfoByAccessibilityIdResult failed");
return;
}
if (static_cast<RetError>(reply.ReadInt32() != RET_OK)) {
HILOG_ERROR("read reply code failed");
}
return;
}
void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByTextResult(

View File

@ -18,6 +18,7 @@
#include "accessibility_ipc_interface_code.h"
#include "hilog_wrapper.h"
#include "parcel_util.h"
#include <securec.h>
#define SWITCH_BEGIN(code) switch (code) {
#define SWITCH_CASE(case_code, func) \
@ -49,41 +50,31 @@ namespace Accessibility {
constexpr int32_t SINGLE_TRANSMIT = -2;
constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
constexpr int32_t ERR_CODE_DEFAULT = -1000;
constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
void StoreElementData::WriteData(std::vector<AccessibilityElementInfo> &infos)
static bool GetData(size_t size, const void *data, void *&buffer)
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
storeData_.insert(storeData_.end(), infos.begin(), infos.end());
}
void StoreElementData::Clear()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
storeData_.clear();
}
std::vector<AccessibilityElementInfo> StoreElementData::ReadData()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
return storeData_;
}
size_t StoreElementData::Size()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
return storeData_.size();
if (data == nullptr || size == 0) {
return false;
}
if (size > MAX_RAWDATA_SIZE) {
return false;
}
buffer = malloc(size);
if (buffer == nullptr) {
return false;
}
if (memcpy_s(buffer, size, data, size) != EOK) {
free(buffer);
return false;
}
return true;
}
AccessibilityElementOperatorCallbackStub::AccessibilityElementOperatorCallbackStub()
{
}
StoreElementData AccessibilityElementOperatorCallbackStub::storeElementData;
AccessibilityElementOperatorCallbackStub::~AccessibilityElementOperatorCallbackStub()
{
}
@ -116,39 +107,33 @@ ErrCode AccessibilityElementOperatorCallbackStub::HandleSetSearchElementInfoByAc
MessageParcel &data, MessageParcel &reply)
{
HILOG_DEBUG();
int32_t flag = data.ReadInt32();
if (flag == SINGLE_TRANSMIT || flag == 0) {
storeElementData.Clear();
}
int32_t accessibilityInfosize = data.ReadInt32();
std::vector<AccessibilityElementInfo> tmpData;
bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, tmpData.max_size());
if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) {
std::vector<AccessibilityElementInfo> storeData;
int32_t requestId = data.ReadInt32();
size_t infoSize = data.ReadUint32();
size_t rawDataSize = data.ReadUint32();
MessageParcel tmpParcel;
void *buffer = nullptr;
// memory alloced in GetData will be released when tmpParcel destruct
if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
for (int32_t i = 0; i < accessibilityInfosize; i++) {
sptr<AccessibilityElementInfoParcel> accessibilityInfo =
data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
if (accessibilityInfo == nullptr) {
HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
storeElementData.Clear();
if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
for (size_t i = 0; i < infoSize; i++) {
sptr<AccessibilityElementInfoParcel> info = tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
if (info == nullptr) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
tmpData.push_back(*accessibilityInfo);
storeData.emplace_back(*info);
}
storeElementData.WriteData(tmpData); // get all data and push once
int32_t requestId = data.ReadInt32();
if (flag == SINGLE_TRANSMIT || flag == MULTI_TRANSMIT_FINISH) {
reply.WriteInt32(0);
HILOG_DEBUG("infos size %{public}zu, requestId %{public}d", storeElementData.Size(), requestId);
SetSearchElementInfoByAccessibilityIdResult(storeElementData.ReadData(), requestId);
return NO_ERROR;
}
reply.WriteInt32(0);
reply.WriteInt32(RET_OK);
SetSearchElementInfoByAccessibilityIdResult(storeData, requestId);
return NO_ERROR;
}

View File

@ -60,77 +60,57 @@ bool AccessibilityElementOperatorCallbackProxyTest::SendTransactCmd(Accessibilit
return true;
}
int32_t AccessibilityElementOperatorCallbackProxyTest::GetTransmitFlag(int32_t time, int32_t leftSize)
{
int32_t flag = time;
if (time == 0 && leftSize <= DATA_NUMBER_ONE_TIME) {
flag = SINGLE_TRANSMIT;
} else if (leftSize <= DATA_NUMBER_ONE_TIME) {
flag = MULTI_TRANSMIT_FINISH;
}
return flag;
}
void AccessibilityElementOperatorCallbackProxyTest::SetSearchElementInfoByAccessibilityIdResult(
void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
{
HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
int32_t leftSize = static_cast<int32_t>(infos.size());
int32_t time = 0;
int32_t index = 0;
while (leftSize >= 0) {
MessageParcel data;
MessageParcel reply;
MessageOption type = MessageOption::TF_SYNC;
if (leftSize <= DATA_NUMBER_ONE_TIME) {
type = MessageOption::TF_ASYNC;
}
MessageOption option(type);
data.SetMaxCapacity(IPC_MEMORY_SIZE);
// when infos size is a multi of 800, do not send the last empty reply
if (leftSize == 0 && time > 0) {
return;
}
if (!WriteInterfaceToken(data)) {
return;
}
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("connection write token failed");
return;
}
int32_t flag = GetTransmitFlag(time, leftSize);
if (!data.WriteInt32(flag)) {
return;
}
if (!data.WriteInt32(requestId)) {
HILOG_ERROR("connection write request id failed");
return;
}
int32_t writeSize = (leftSize <= DATA_NUMBER_ONE_TIME) ? leftSize : DATA_NUMBER_ONE_TIME;
if (!data.WriteInt32(writeSize)) {
return;
}
if (!data.WriteInt32(infos.size())) {
HILOG_ERROR("write infos's size failed");
return;
}
for (int32_t i = 0; i < writeSize; ++i) {
AccessibilityElementInfoParcel infoParcel(infos[index]);
index++;
if (!data.WriteParcelable(&infoParcel)) {
HILOG_ERROR("accessibility element info failed index %{public}d", index);
return;
}
}
if (!data.WriteInt32(requestId)) {
return;
}
if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
HILOG_ERROR("set search element info by accessibility id result failed");
return;
}
leftSize -= DATA_NUMBER_ONE_TIME;
time++;
if (static_cast<RetError>(reply.ReadInt32()) != RET_OK) {
MessageParcel tmpParcel;
tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
// when set pracel's max capacity, it won't alloc memory immediately
// MessageParcel will expand memory dynamiclly
for (const auto &info : infos) {
AccessibilityElementInfoParcel infoParcel(info);
if (!tmpParcel.WriteParcelable(&infoParcel)) {
HILOG_ERROR("write accessibilityElementInfoParcel failed");
return;
}
}
size_t tmpParcelSize = tmpParcel.GetDataSize();
if (!data.WriteUint32(tmpParcelSize)) {
HILOG_ERROR("write rawData size failed");
return;
}
if (!data.WriteRawData(reinterpret_cast<uint8_t *>(tmpParcel.GetData()), tmpParcelSize)) {
HILOG_ERROR("write rawData failed");
return;
}
if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
HILOG_ERROR("setSearchElementInfoByAccessibilityIdResult failed");
return;
}
if (static_cast<RetError>(reply.ReadInt32() != RET_OK)) {
HILOG_ERROR("read reply code failed");
}
return;
}
void AccessibilityElementOperatorCallbackProxyTest::SetSearchElementInfoByTextResult(

View File

@ -18,6 +18,7 @@
#include "accessibility_ipc_interface_code.h"
#include "hilog_wrapper.h"
#include "parcel_util.h"
#include <securec.h>
#define SWITCH_BEGIN(code) switch (code) {
#define SWITCH_CASE(case_code, func) case case_code:\
@ -49,41 +50,31 @@ namespace Accessibility {
constexpr int32_t SINGLE_TRANSMIT = -2;
constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
constexpr int32_t ERR_CODE_DEFAULT = -1000;
constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
void StoreElementData::WriteData(std::vector<AccessibilityElementInfo> &infos)
static bool GetData(size_t size, const void *data, void *&buffer)
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
storeData_.insert(storeData_.end(), infos.begin(), infos.end());
}
void StoreElementData::Clear()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
storeData_.clear();
}
std::vector<AccessibilityElementInfo> StoreElementData::ReadData()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
return storeData_;
}
size_t StoreElementData::Size()
{
HILOG_DEBUG();
std::lock_guard<ffrt::mutex> lock(mutex_);
return storeData_.size();
if (data == nullptr || size == 0) {
return false;
}
if (size > MAX_RAWDATA_SIZE) {
return false;
}
buffer = malloc(size);
if (buffer == nullptr) {
return false;
}
if (memcpy_s(buffer, size, data, size) != EOK) {
free(buffer);
return false;
}
return true;
}
AccessibilityElementOperatorCallbackStubTest::AccessibilityElementOperatorCallbackStubTest()
{
}
StoreElementData AccessibilityElementOperatorCallbackStubTest::storeElementData;
AccessibilityElementOperatorCallbackStubTest::~AccessibilityElementOperatorCallbackStubTest()
{
}
@ -116,39 +107,33 @@ ErrCode AccessibilityElementOperatorCallbackStubTest::HandleSetSearchElementInfo
MessageParcel &data, MessageParcel &reply)
{
HILOG_DEBUG();
int32_t flag = data.ReadInt32();
if (flag == SINGLE_TRANSMIT || flag == 0) {
storeElementData.Clear();
}
int32_t accessibilityInfosize = data.ReadInt32();
std::vector<AccessibilityElementInfo> tmpData;
bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, tmpData.max_size());
if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) {
std::vector<AccessibilityElementInfo> storeData;
int32_t requestId = data.ReadInt32();
size_t infoSize = data.ReadUint32();
size_t rawDataSize = data.ReadUint32();
MessageParcel tmpParcel;
void *buffer = nullptr;
// memory alloced in GetData will be released when tmpParcel destruct
if (!GetData(rawDataSize, data.ReadRawData(rawDataSize), buffer)) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
for (int32_t i = 0; i < accessibilityInfosize; i++) {
sptr<AccessibilityElementInfoParcel> accessibilityInfo =
data.ReadStrongParcelable<AccessibilityElementInfoParcel>();
if (accessibilityInfo == nullptr) {
HILOG_ERROR("ReadStrongParcelable<accessibilityInfo> failed");
storeElementData.Clear();
if (!tmpParcel.ParseFrom(reinterpret_cast<uintptr_t>(buffer), rawDataSize)) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
for (size_t i = 0; i < infoSize; i++) {
sptr<AccessibilityElementInfoParcel> info = tmpParcel.ReadStrongParcelable<AccessibilityElementInfoParcel>();
if (info == nullptr) {
reply.WriteInt32(RET_ERR_FAILED);
return TRANSACTION_ERR;
}
tmpData.push_back(*accessibilityInfo);
storeData.emplace_back(*info);
}
storeElementData.WriteData(tmpData); // get all data and push once
int32_t requestId = data.ReadInt32();
if (flag == SINGLE_TRANSMIT || flag == MULTI_TRANSMIT_FINISH) {
reply.WriteInt32(0);
HILOG_DEBUG("infos size %{public}zu, requestId %{public}d", storeElementData.Size(), requestId);
SetSearchElementInfoByAccessibilityIdResult(storeElementData.ReadData(), requestId);
return NO_ERROR;
}
reply.WriteInt32(0);
reply.WriteInt32(RET_OK);
SetSearchElementInfoByAccessibilityIdResult(storeData, requestId);
return NO_ERROR;
}