diff --git a/common/interface/include/accessibility_element_operator_callback_proxy.h b/common/interface/include/accessibility_element_operator_callback_proxy.h index 9ea2da97..7dbcc5d8 100644 --- a/common/interface/include/accessibility_element_operator_callback_proxy.h +++ b/common/interface/include/accessibility_element_operator_callback_proxy.h @@ -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 delegator; }; } // namespace Accessibility diff --git a/common/interface/include/accessibility_element_operator_callback_stub.h b/common/interface/include/accessibility_element_operator_callback_stub.h index 4c1b5541..c22467fc 100644 --- a/common/interface/include/accessibility_element_operator_callback_stub.h +++ b/common/interface/include/accessibility_element_operator_callback_stub.h @@ -23,19 +23,6 @@ namespace OHOS { namespace Accessibility { - -class StoreElementData { -public: - StoreElementData() = default; - ~StoreElementData() = default; - void WriteData(std::vector &infos); - std::vector ReadData(); - size_t Size(); - void Clear(); - std::vector 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. diff --git a/common/interface/src/accessibility_element_operator_callback_proxy.cpp b/common/interface/src/accessibility_element_operator_callback_proxy.cpp index 66832953..ab1b86f0 100644 --- a/common/interface/src/accessibility_element_operator_callback_proxy.cpp +++ b/common/interface/src/accessibility_element_operator_callback_proxy.cpp @@ -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 &infos, const int32_t requestId) { HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId); - int32_t leftSize = static_cast(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(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(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(reply.ReadInt32() != RET_OK)) { + HILOG_ERROR("read reply code failed"); + } + return; } void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByTextResult( diff --git a/common/interface/src/accessibility_element_operator_callback_stub.cpp b/common/interface/src/accessibility_element_operator_callback_stub.cpp index b42cfeeb..037e4e0d 100644 --- a/common/interface/src/accessibility_element_operator_callback_stub.cpp +++ b/common/interface/src/accessibility_element_operator_callback_stub.cpp @@ -18,6 +18,7 @@ #include "accessibility_ipc_interface_code.h" #include "hilog_wrapper.h" #include "parcel_util.h" +#include #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 &infos) +static bool GetData(size_t size, const void *data, void *&buffer) { - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - storeData_.insert(storeData_.end(), infos.begin(), infos.end()); -} - -void StoreElementData::Clear() -{ - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - storeData_.clear(); -} - -std::vector StoreElementData::ReadData() -{ - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - return storeData_; -} - -size_t StoreElementData::Size() -{ - HILOG_DEBUG(); - std::lock_guard 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 tmpData; - bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, tmpData.max_size()); - if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) { + std::vector 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 accessibilityInfo = - data.ReadStrongParcelable(); - if (accessibilityInfo == nullptr) { - HILOG_ERROR("ReadStrongParcelable failed"); - storeElementData.Clear(); + + if (!tmpParcel.ParseFrom(reinterpret_cast(buffer), rawDataSize)) { + reply.WriteInt32(RET_ERR_FAILED); + return TRANSACTION_ERR; + } + + for (size_t i = 0; i < infoSize; i++) { + sptr info = tmpParcel.ReadStrongParcelable(); + 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; } diff --git a/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_proxy.cpp b/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_proxy.cpp index 7a5fe5b6..ad425dc8 100644 --- a/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_proxy.cpp +++ b/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_proxy.cpp @@ -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 &infos, const int32_t requestId) { HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId); - int32_t leftSize = static_cast(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(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(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(reply.ReadInt32() != RET_OK)) { + HILOG_ERROR("read reply code failed"); + } + return; } void AccessibilityElementOperatorCallbackProxyTest::SetSearchElementInfoByTextResult( diff --git a/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_stub.cpp b/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_stub.cpp index f9d5578c..1e2b4734 100644 --- a/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_stub.cpp +++ b/common/interface/test/unittest/mock/mock_accessibility_element_operator_callback_stub.cpp @@ -18,6 +18,7 @@ #include "accessibility_ipc_interface_code.h" #include "hilog_wrapper.h" #include "parcel_util.h" +#include #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 &infos) +static bool GetData(size_t size, const void *data, void *&buffer) { - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - storeData_.insert(storeData_.end(), infos.begin(), infos.end()); -} - -void StoreElementData::Clear() -{ - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - storeData_.clear(); -} - -std::vector StoreElementData::ReadData() -{ - HILOG_DEBUG(); - std::lock_guard lock(mutex_); - return storeData_; -} - -size_t StoreElementData::Size() -{ - HILOG_DEBUG(); - std::lock_guard 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 tmpData; - bool verifyResult = ContainerSecurityVerify(data, accessibilityInfosize, tmpData.max_size()); - if (!verifyResult || accessibilityInfosize < 0 || accessibilityInfosize > INT32_MAX) { + std::vector 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 accessibilityInfo = - data.ReadStrongParcelable(); - if (accessibilityInfo == nullptr) { - HILOG_ERROR("ReadStrongParcelable failed"); - storeElementData.Clear(); + + if (!tmpParcel.ParseFrom(reinterpret_cast(buffer), rawDataSize)) { + reply.WriteInt32(RET_ERR_FAILED); + return TRANSACTION_ERR; + } + + for (size_t i = 0; i < infoSize; i++) { + sptr info = tmpParcel.ReadStrongParcelable(); + 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; }