!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, bool SendTransactCmd(AccessibilityInterfaceCode code, MessageParcel &data,
MessageParcel &reply, MessageOption &option); MessageParcel &reply, MessageOption &option);
int32_t GetTransmitFlag(int32_t time, int32_t leftSize);
static inline BrokerDelegator<AccessibilityElementOperatorCallbackProxy> delegator; static inline BrokerDelegator<AccessibilityElementOperatorCallbackProxy> delegator;
}; };
} // namespace Accessibility } // namespace Accessibility

View File

@ -23,19 +23,6 @@
namespace OHOS { namespace OHOS {
namespace Accessibility { 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. * The class define the interface for UI to implement.
* It triggered by ABMS when AA to request the accessibility information. * 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, virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option) override; MessageOption &option) override;
static StoreElementData storeElementData;
private: private:
/** /**
* @brief Handle the IPC request for the function:SetSearchElementInfoByAccessibilityIdResult. * @brief Handle the IPC request for the function:SetSearchElementInfoByAccessibilityIdResult.

View File

@ -20,8 +20,7 @@
namespace OHOS { namespace OHOS {
namespace Accessibility { namespace Accessibility {
constexpr int32_t IPC_MEMORY_SIZE = 500 * 1024; // default size is 200 * 1024B, batch query need more memory constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
constexpr int32_t SINGLE_TRANSMIT = -2;
constexpr int32_t MULTI_TRANSMIT_FINISH = -1; constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
constexpr int32_t DATA_NUMBER_ONE_TIME = 400; constexpr int32_t DATA_NUMBER_ONE_TIME = 400;
@ -60,77 +59,57 @@ bool AccessibilityElementOperatorCallbackProxy::SendTransactCmd(AccessibilityInt
return true; 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( void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId) const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
{ {
HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId); HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
int32_t leftSize = static_cast<int32_t>(infos.size()); MessageParcel data;
int32_t time = 0; MessageParcel reply;
int32_t index = 0; MessageOption option(MessageOption::TF_ASYNC);
while (leftSize >= 0) { if (!WriteInterfaceToken(data)) {
MessageParcel data; HILOG_ERROR("connection write token failed");
MessageParcel reply; return;
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;
}
int32_t flag = GetTransmitFlag(time, leftSize); if (!data.WriteInt32(requestId)) {
if (!data.WriteInt32(flag)) { HILOG_ERROR("connection write request id failed");
return; return;
} }
int32_t writeSize = (leftSize <= DATA_NUMBER_ONE_TIME) ? leftSize : DATA_NUMBER_ONE_TIME; if (!data.WriteUint32(infos.size())) {
if (!data.WriteInt32(writeSize)) { HILOG_ERROR("write infos's size failed");
return; return;
} }
for (int32_t i = 0; i < writeSize; ++i) { MessageParcel tmpParcel;
AccessibilityElementInfoParcel infoParcel(infos[index]); tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
index++; // when set pracel's max capacity, it won't alloc memory immediately
if (!data.WriteParcelable(&infoParcel)) { // MessageParcel will expand memory dynamiclly
HILOG_ERROR("accessibility element info failed index %{public}d", index); for (const auto &info : infos) {
return; AccessibilityElementInfoParcel infoParcel(info);
} if (!tmpParcel.WriteParcelable(&infoParcel)) {
} HILOG_ERROR("write accessibilityElementInfoParcel failed");
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) {
return; 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( void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByTextResult(

View File

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

View File

@ -60,77 +60,57 @@ bool AccessibilityElementOperatorCallbackProxyTest::SendTransactCmd(Accessibilit
return true; return true;
} }
int32_t AccessibilityElementOperatorCallbackProxyTest::GetTransmitFlag(int32_t time, int32_t leftSize) void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
{
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(
const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId) const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
{ {
HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId); HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
int32_t leftSize = static_cast<int32_t>(infos.size()); MessageParcel data;
int32_t time = 0; MessageParcel reply;
int32_t index = 0; MessageOption option(MessageOption::TF_ASYNC);
while (leftSize >= 0) { if (!WriteInterfaceToken(data)) {
MessageParcel data; HILOG_ERROR("connection write token failed");
MessageParcel reply; return;
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;
}
int32_t flag = GetTransmitFlag(time, leftSize); if (!data.WriteInt32(requestId)) {
if (!data.WriteInt32(flag)) { HILOG_ERROR("connection write request id failed");
return; return;
} }
int32_t writeSize = (leftSize <= DATA_NUMBER_ONE_TIME) ? leftSize : DATA_NUMBER_ONE_TIME; if (!data.WriteInt32(infos.size())) {
if (!data.WriteInt32(writeSize)) { HILOG_ERROR("write infos's size failed");
return; return;
} }
for (int32_t i = 0; i < writeSize; ++i) { MessageParcel tmpParcel;
AccessibilityElementInfoParcel infoParcel(infos[index]); tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
index++; // when set pracel's max capacity, it won't alloc memory immediately
if (!data.WriteParcelable(&infoParcel)) { // MessageParcel will expand memory dynamiclly
HILOG_ERROR("accessibility element info failed index %{public}d", index); for (const auto &info : infos) {
return; AccessibilityElementInfoParcel infoParcel(info);
} if (!tmpParcel.WriteParcelable(&infoParcel)) {
} HILOG_ERROR("write accessibilityElementInfoParcel failed");
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) {
return; 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( void AccessibilityElementOperatorCallbackProxyTest::SetSearchElementInfoByTextResult(

View File

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