From 7fc15c137950298c3d1649cc0a6aa92f2ea22bd3 Mon Sep 17 00:00:00 2001 From: qianyong325 Date: Wed, 23 Jul 2025 17:11:43 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=89=93=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: qianyong325 --- .../include/input_data_channel_proxy_wrap.h | 14 ++- .../include/input_method_ability.h | 11 +-- .../src/input_data_channel_proxy_wrap.cpp | 76 ++++++++++----- .../src/input_method_ability.cpp | 92 ++----------------- .../cpp_test/src/ima_text_edit_test.cpp | 33 +++++-- 5 files changed, 99 insertions(+), 127 deletions(-) diff --git a/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h b/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h index 8c1794bbc..b60b8b73a 100644 --- a/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h +++ b/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h @@ -31,19 +31,24 @@ namespace MiscServices { using ChannelWork = std::function &channel)>; using SyncOutput = std::function; using AsyncIpcCallBack = std::function; +using namespace std::chrono; struct ResponseInfo { int32_t dealRet_{ ErrorCode::NO_ERROR }; ResponseData data_{ std::monostate{} }; }; struct ResponseHandler { static constexpr uint32_t SYNC_REPLY_TIMEOUT = 3000; // unit ms + int32_t eventCode_ = 0; uint64_t msgId_ = 0; + int64_t reportStartTime_ = + duration_cast(system_clock::now().time_since_epoch()).count(); AsyncIpcCallBack asyncCallback_ = nullptr; std::shared_ptr> syncBlockData_ = nullptr; - ResponseHandler(uint64_t msgId, bool isSync, const AsyncIpcCallBack &callback) + ResponseHandler(uint64_t msgId, bool isSync, const AsyncIpcCallBack &callback, int32_t eventCode) { msgId_ = msgId; asyncCallback_ = callback; + eventCode_ = eventCode; if (isSync) { syncBlockData_ = std::make_shared>(SYNC_REPLY_TIMEOUT); } @@ -76,12 +81,13 @@ public: std::shared_ptr GetDataChannel(); private: - std::shared_ptr AddRspHandler(const AsyncIpcCallBack &callback, bool isSync); + std::shared_ptr AddRspHandler(const AsyncIpcCallBack &callback, bool isSync, int32_t eventCode); int32_t WaitResponse(const std::shared_ptr &rspHandler, const SyncOutput &output); int32_t DeleteRspHandler(uint64_t msgId); uint64_t GenerateMsgId(); - int32_t Request( - const AsyncIpcCallBack &callback, const ChannelWork &work, bool isSync, const SyncOutput &output = nullptr); + int32_t Request(const AsyncIpcCallBack &callback, const ChannelWork &work, bool isSync, + int32_t eventCode, const SyncOutput &output = nullptr); + int32_t HandleMsg(uint64_t msgId, const ResponseInfo &rspInfo); private: uint64_t msgId_{ 0 }; diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index a94f600ae..1562d0791 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -127,6 +127,7 @@ public: void OnAttributeChange(InputAttribute attribute); int32_t OnStopInputService(bool isTerminateIme); + void ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime); private: std::mutex controlChannelLock_; std::shared_ptr controlChannel_ = nullptr; @@ -187,21 +188,11 @@ private: void ClearInputType(); std::shared_ptr GetMsgHandlerCallback(); int32_t StartInputInner(const InputClientInfo &clientInfo, bool isBindFromClient); - int32_t InsertTextInner(const std::string &text, const AsyncIpcCallBack &callback = nullptr); - int32_t SetPreviewTextInner( - const std::string &text, const Range &range, const AsyncIpcCallBack &callback = nullptr); - int32_t DeleteForwardInner(int32_t length, const AsyncIpcCallBack &callback = nullptr); - int32_t DeleteBackwardInner(int32_t length, const AsyncIpcCallBack &callback = nullptr); - int32_t FinishTextPreviewInner(const AsyncIpcCallBack &callback = nullptr); - int32_t GetTextBeforeCursorInner(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback = nullptr); - int32_t GetTextAfterCursorInner(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback = nullptr); - int32_t GetTextIndexAtCursorInner(int32_t &index, const AsyncIpcCallBack &callback = nullptr); bool NotifyInfoToWmsInStartInput(const TextTotalConfig &textConfig); void SetBindClientInfo(const InputClientInfo &clientInfo); HiSysEventClientInfo GetBindClientInfo(); void ClearBindClientInfo(); void ReportImeStartInput(int32_t eventCode, int32_t errCode, bool isShowKeyboard, int64_t consumeTime = -1); - void ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime); void ClearBindInfo(const sptr &channel); ConcurrentMap> panels_ {}; diff --git a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp index a5366fc14..616173abd 100644 --- a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp +++ b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp @@ -21,6 +21,7 @@ #include "input_method_tools.h" #include "string_ex.h" #include "variant_util.h" +#include "input_method_ability.h" namespace OHOS { namespace MiscServices { @@ -46,7 +47,8 @@ int32_t InputDataChannelProxyWrap::InsertText(const std::string &text, const Asy uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->InsertText(text, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_INSERT_TEXT)); } int32_t InputDataChannelProxyWrap::DeleteForward(int32_t length, const AsyncIpcCallBack &callback) @@ -55,7 +57,8 @@ int32_t InputDataChannelProxyWrap::DeleteForward(int32_t length, const AsyncIpcC uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->DeleteForward(length, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_DELETE_FORWARD)); } int32_t InputDataChannelProxyWrap::DeleteBackward(int32_t length, const AsyncIpcCallBack &callback) @@ -64,7 +67,8 @@ int32_t InputDataChannelProxyWrap::DeleteBackward(int32_t length, const AsyncIpc uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->DeleteBackward(length, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_DELETE_BACKWARD)); } int32_t InputDataChannelProxyWrap::GetTextBeforeCursor( @@ -78,7 +82,8 @@ int32_t InputDataChannelProxyWrap::GetTextBeforeCursor( if (callback == nullptr) { output = [&text](const ResponseData &data) -> void { VariantUtil::GetValue(data, text); }; } - return Request(callback, work, callback == nullptr, output); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_BEFORE_CURSOR), output); } int32_t InputDataChannelProxyWrap::GetTextAfterCursor( @@ -92,7 +97,8 @@ int32_t InputDataChannelProxyWrap::GetTextAfterCursor( if (callback == nullptr) { output = [&text](const ResponseData &data) -> void { VariantUtil::GetValue(data, text); }; } - return Request(callback, work, callback == nullptr, output); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_AFTER_CURSOR), output); } int32_t InputDataChannelProxyWrap::SendFunctionKey(int32_t funcKey, const AsyncIpcCallBack &callback) @@ -101,7 +107,8 @@ int32_t InputDataChannelProxyWrap::SendFunctionKey(int32_t funcKey, const AsyncI uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->SendFunctionKey(funcKey, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_SEND_FUNCTION_KEY)); } int32_t InputDataChannelProxyWrap::MoveCursor(int32_t keyCode, const AsyncIpcCallBack &callback) @@ -110,7 +117,8 @@ int32_t InputDataChannelProxyWrap::MoveCursor(int32_t keyCode, const AsyncIpcCal uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->MoveCursor(keyCode, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_MOVE_CURSOR)); } int32_t InputDataChannelProxyWrap::SelectByRange(int32_t start, int32_t end, const AsyncIpcCallBack &callback) @@ -119,7 +127,8 @@ int32_t InputDataChannelProxyWrap::SelectByRange(int32_t start, int32_t end, con uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->SelectByRange(start, end, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_SELECT_BY_RANGE)); } int32_t InputDataChannelProxyWrap::SelectByMovement( @@ -129,7 +138,8 @@ int32_t InputDataChannelProxyWrap::SelectByMovement( uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->SelectByMovement(direction, cursorMoveSkip, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_SELECT_BY_MOVEMENT)); } int32_t InputDataChannelProxyWrap::HandleExtendAction(int32_t action, const AsyncIpcCallBack &callback) @@ -138,7 +148,8 @@ int32_t InputDataChannelProxyWrap::HandleExtendAction(int32_t action, const Asyn uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->HandleExtendAction(action, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_HANDLE_EXTEND_ACTION)); } int32_t InputDataChannelProxyWrap::GetTextIndexAtCursor(int32_t &index, const AsyncIpcCallBack &callback) @@ -151,7 +162,8 @@ int32_t InputDataChannelProxyWrap::GetTextIndexAtCursor(int32_t &index, const As if (callback == nullptr) { output = [&index](const ResponseData &data) -> void { VariantUtil::GetValue(data, index); }; } - return Request(callback, work, callback == nullptr, output); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_INDEX_AT_CURSOR), output); } int32_t InputDataChannelProxyWrap::SetPreviewText( @@ -161,7 +173,8 @@ int32_t InputDataChannelProxyWrap::SetPreviewText( uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->SetPreviewText(text, range, msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_SET_PREVIEW_TEXT)); } int32_t InputDataChannelProxyWrap::FinishTextPreview(const AsyncIpcCallBack &callback) @@ -170,28 +183,32 @@ int32_t InputDataChannelProxyWrap::FinishTextPreview(const AsyncIpcCallBack &cal uint64_t msgId, const std::shared_ptr &channel) -> int32_t { return channel->FinishTextPreview(msgId, agentObject); }; - return Request(callback, work, callback == nullptr); + return Request(callback, work, callback == nullptr, + static_cast(IInputDataChannelIpcCode::COMMAND_FINISH_TEXT_PREVIEW)); } -int32_t InputDataChannelProxyWrap::Request( - const AsyncIpcCallBack &callback, const ChannelWork &work, bool isSync, const SyncOutput &output) +int32_t InputDataChannelProxyWrap::Request(const AsyncIpcCallBack &callback, const ChannelWork &work, + bool isSync, int32_t eventCode, const SyncOutput &output) { auto channel = GetDataChannel(); if (channel == nullptr) { IMSA_HILOGE("data channel is nullptr!"); return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR; } - auto handler = AddRspHandler(callback, isSync); + auto handler = AddRspHandler(callback, isSync, eventCode); if (handler == nullptr) { - IMSA_HILOGE("add rsp handler failed."); + IMSA_HILOGE("add rsp handler failed. sync: %{public}d event code: %{public}d", isSync, eventCode); return ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL; } auto ret = work(handler->msgId_, channel); if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("work error: %{public}d.", ret); + IMSA_HILOGE("work error id: %{public}" PRIu64 " sync: %{public}d event code: %{public}d ret: %{public}d.", + handler->msgId_, isSync, eventCode, ret); DeleteRspHandler(handler->msgId_); return ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL; } + IMSA_HILOGD("Request info id: %{public}" PRIu64 " sync: %{public}d event code: %{public}d ret: %{public}d.", + handler->msgId_, isSync, eventCode, ret); if (handler->syncBlockData_ != nullptr) { return WaitResponse(handler, output); } @@ -209,15 +226,19 @@ uint64_t InputDataChannelProxyWrap::GenerateMsgId() return ++msgId_ ? msgId_ : ++msgId_; } -std::shared_ptr InputDataChannelProxyWrap::AddRspHandler(const AsyncIpcCallBack &callback, bool isSync) +std::shared_ptr InputDataChannelProxyWrap::AddRspHandler(const AsyncIpcCallBack &callback, + bool isSync, int32_t eventCode) { std::lock_guard lock(rspMutex_); if (rspHandlers_.size() >= MESSAGE_UNANSWERED_MAX_NUMBER) { - IMSA_HILOGW("too many unanswered, data channel abnormal"); - return nullptr; + auto it = rspHandlers_.begin(); + IMSA_HILOGW("too many unanswered id: %{public}" PRIu64 " event code: %{public}d sync: %{public}d", + it->first, eventCode, isSync); + ResponseInfo rspInfo = { ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL, std::monostate{} }; + HandleMsg(it->first, rspInfo); } auto msgId = GenerateMsgId(); - auto handler = std::make_shared(msgId, isSync, callback); + auto handler = std::make_shared(msgId, isSync, callback, eventCode); rspHandlers_.insert({ msgId, handler }); return handler; } @@ -245,20 +266,31 @@ int32_t InputDataChannelProxyWrap::ClearRspHandlers() int32_t InputDataChannelProxyWrap::HandleResponse(uint64_t msgId, const ResponseInfo &rspInfo) { std::lock_guard lock(rspMutex_); + return HandleMsg(msgId, rspInfo); +} + +int32_t InputDataChannelProxyWrap::HandleMsg(uint64_t msgId, const ResponseInfo &rspInfo) +{ auto it = rspHandlers_.find(msgId); if (it == rspHandlers_.end()) { + IMSA_HILOGE("not found id: %{public}" PRIu64 "", msgId); return ErrorCode::NO_ERROR; } if (it->second == nullptr) { rspHandlers_.erase(it); return ErrorCode::NO_ERROR; } + IMSA_HILOGD("msg info id: %{public}" PRIu64 " event code: %{public}d sync: %{public}d code: %{public}d", + msgId, it->second->eventCode_, it->second->syncBlockData_ != nullptr, rspInfo.dealRet_); if (it->second->syncBlockData_ != nullptr) { it->second->syncBlockData_->SetValue(rspInfo); } if (it->second->asyncCallback_ != nullptr) { it->second->asyncCallback_(rspInfo.dealRet_, rspInfo.data_); } + int64_t now = duration_cast(system_clock::now().time_since_epoch()).count(); + InputMethodAbility::GetInstance().ReportBaseTextOperation(it->second->eventCode_, rspInfo.dealRet_, + now - it->second->reportStartTime_); rspHandlers_.erase(it); return ErrorCode::NO_ERROR; } diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 03339b1d0..a3669a51b 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -657,7 +657,7 @@ AttachOptions InputMethodAbility::GetAttachOptions() return attachOptions_; } -int32_t InputMethodAbility::InsertTextInner(const std::string &text, const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::InsertText(const std::string &text, const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_InsertText"); IMSA_HILOGD("InputMethodAbility start."); @@ -670,7 +670,7 @@ int32_t InputMethodAbility::InsertTextInner(const std::string &text, const Async return channel->InsertText(text, callback); } -int32_t InputMethodAbility::DeleteForwardInner(int32_t length, const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::DeleteForward(int32_t length, const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_DeleteForward"); IMSA_HILOGD("InputMethodAbility start, length: %{public}d.", length); @@ -682,7 +682,7 @@ int32_t InputMethodAbility::DeleteForwardInner(int32_t length, const AsyncIpcCal return channel->DeleteForward(length, callback); } -int32_t InputMethodAbility::DeleteBackwardInner(int32_t length, const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::DeleteBackward(int32_t length, const AsyncIpcCallBack &callback) { IMSA_HILOGD("InputMethodAbility start, length: %{public}d.", length); auto channel = GetInputDataChannelProxyWrap(); @@ -729,8 +729,7 @@ int32_t InputMethodAbility::SendExtendAction(int32_t action, const AsyncIpcCallB return channel->HandleExtendAction(action, callback); } -int32_t InputMethodAbility::GetTextBeforeCursorInner( - int32_t number, std::u16string &text, const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::GetTextBeforeCursor(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_GetForward"); IMSA_HILOGD("InputMethodAbility, number: %{public}d.", number); @@ -745,7 +744,7 @@ int32_t InputMethodAbility::GetTextBeforeCursorInner( return ret; } -int32_t InputMethodAbility::GetTextAfterCursorInner( +int32_t InputMethodAbility::GetTextAfterCursor( int32_t number, std::u16string &text, const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_GetTextAfterCursor"); @@ -820,7 +819,7 @@ int32_t InputMethodAbility::GetInputPattern(int32_t &inputPattern) return channel->GetInputPattern(inputPattern); } -int32_t InputMethodAbility::GetTextIndexAtCursorInner(int32_t &index, const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::GetTextIndexAtCursor(int32_t &index, const AsyncIpcCallBack &callback) { IMSA_HILOGD("InputMethodAbility start."); auto channel = GetInputDataChannelProxyWrap(); @@ -1505,7 +1504,7 @@ int32_t InputMethodAbility::ReceivePrivateCommand( return ErrorCode::NO_ERROR; } -int32_t InputMethodAbility::SetPreviewTextInner( +int32_t InputMethodAbility::SetPreviewText( const std::string &text, const Range &range, const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_SetPreviewText"); @@ -1518,7 +1517,7 @@ int32_t InputMethodAbility::SetPreviewTextInner( return dataChannel->SetPreviewText(text, rangeInner, callback); } -int32_t InputMethodAbility::FinishTextPreviewInner(const AsyncIpcCallBack &callback) +int32_t InputMethodAbility::FinishTextPreview(const AsyncIpcCallBack &callback) { InputMethodSyncTrace tracer("IMA_FinishTextPreview"); auto dataChannel = GetInputDataChannelProxyWrap(); @@ -1655,81 +1654,6 @@ int32_t InputMethodAbility::StartInput(const InputClientInfo &clientInfo, bool i return ret; } -int32_t InputMethodAbility::InsertText(const std::string &text, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = InsertTextInner(text, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation(static_cast(IInputDataChannelIpcCode::COMMAND_INSERT_TEXT), ret, end - start); - return ret; -} - -int32_t InputMethodAbility::DeleteForward(int32_t length, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = DeleteForwardInner(length, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation(static_cast(IInputDataChannelIpcCode::COMMAND_DELETE_FORWARD), ret, end - start); - return ret; -} - -int32_t InputMethodAbility::DeleteBackward(int32_t length, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = DeleteBackwardInner(length, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation(static_cast(IInputDataChannelIpcCode::COMMAND_DELETE_BACKWARD), ret, end - start); - return ret; -} - -int32_t InputMethodAbility::SetPreviewText( - const std::string &text, const Range &range, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = SetPreviewTextInner(text, range, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation(static_cast(IInputDataChannelIpcCode::COMMAND_SET_PREVIEW_TEXT), ret, end - start); - return ret; -} - -int32_t InputMethodAbility::FinishTextPreview(const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = FinishTextPreviewInner(callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation( - static_cast(IInputDataChannelIpcCode::COMMAND_FINISH_TEXT_PREVIEW), ret, end - start); - return ret; -} - -int32_t InputMethodAbility::GetTextBeforeCursor(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = GetTextBeforeCursorInner(number, text, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation( - static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_BEFORE_CURSOR), ret, end - start); - return ret; -} -int32_t InputMethodAbility::GetTextAfterCursor(int32_t number, std::u16string &text, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = GetTextAfterCursorInner(number, text, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation( - static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_AFTER_CURSOR), ret, end - start); - return ret; -} -int32_t InputMethodAbility::GetTextIndexAtCursor(int32_t &index, const AsyncIpcCallBack &callback) -{ - int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); - auto ret = GetTextIndexAtCursorInner(index, callback); - int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); - ReportBaseTextOperation( - static_cast(IInputDataChannelIpcCode::COMMAND_GET_TEXT_INDEX_AT_CURSOR), ret, end - start); - return ret; -} - void InputMethodAbility::SetBindClientInfo(const InputClientInfo &clientInfo) { std::lock_guard lock(bindClientInfoLock_); diff --git a/test/unittest/cpp_test/src/ima_text_edit_test.cpp b/test/unittest/cpp_test/src/ima_text_edit_test.cpp index 8dc8eca6a..16d505a1c 100644 --- a/test/unittest/cpp_test/src/ima_text_edit_test.cpp +++ b/test/unittest/cpp_test/src/ima_text_edit_test.cpp @@ -446,9 +446,9 @@ HWTEST_F(ImaTextEditTest, ImaTextEditTest_ClearRspHandlers, TestSize.Level0) std::thread delayThread(delayTask); delayThread.detach(); - channelWrap->AddRspHandler(GetForwardRsp, false); - channelWrap->AddRspHandler(GetForwardRsp, false); - auto handler = channelWrap->AddRspHandler(GetForwardRsp, true); + channelWrap->AddRspHandler(GetForwardRsp, false, 0); + channelWrap->AddRspHandler(GetForwardRsp, false, 0); + auto handler = channelWrap->AddRspHandler(GetForwardRsp, true, 0); auto ret = channelWrap->WaitResponse(handler, nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL); EXPECT_TRUE(WaitGetForwardRspAbnormal(2)); @@ -468,9 +468,9 @@ HWTEST_F(ImaTextEditTest, ImaTextEditTest_DeleteRspHandler, TestSize.Level0) std::shared_ptr firstHandler = nullptr; std::shared_ptr lastHandler = nullptr; - firstHandler = channelWrap->AddRspHandler(GetForwardRsp, false); + firstHandler = channelWrap->AddRspHandler(GetForwardRsp, false, 0); for (int i = 0; i < UNANSWERED_MAX_NUMBER; ++i) { - lastHandler = channelWrap->AddRspHandler(GetForwardRsp, false); + lastHandler = channelWrap->AddRspHandler(GetForwardRsp, false, 0); } ASSERT_NE(firstHandler, nullptr); ASSERT_EQ(lastHandler, nullptr); @@ -490,17 +490,36 @@ HWTEST_F(ImaTextEditTest, ImaTextEditTest_HandleResponse, TestSize.Level0) auto channelWrap = std::make_shared(channelProxy, nullptr); std::shared_ptr handler = nullptr; - handler = channelWrap->AddRspHandler(CommonRsp, false); + handler = channelWrap->AddRspHandler(CommonRsp, false, 0); ASSERT_NE(handler, nullptr); ResponseInfo rspInfo = { ErrorCode::NO_ERROR, std::monostate{} }; channelWrap->HandleResponse(handler->msgId_, rspInfo); EXPECT_TRUE(WaitCommonRsp()); std::shared_ptr handler1 = nullptr; - handler1 = channelWrap->AddRspHandler(nullptr, false); + handler1 = channelWrap->AddRspHandler(nullptr, false, 0); ASSERT_NE(handler1, nullptr); EXPECT_EQ(channelWrap->HandleResponse(handler1->msgId_ - 1, rspInfo), ErrorCode::NO_ERROR); EXPECT_EQ(channelWrap->HandleResponse(handler1->msgId_, rspInfo), ErrorCode::NO_ERROR); } + +/** + * @tc.name: ImaTextEditTest_HandleMsg + * @tc.desc: + * @tc.type: FUNC + */ +HWTEST_F(ImaTextEditTest, ImaTextEditTest_HandleMsg, TestSize.Level0) +{ + IMSA_HILOGI("ImeProxyTest::ImaTextEditTest_HandleResponse"); + auto channelProxy = std::make_shared(nullptr); + auto channelWrap = std::make_shared(channelProxy, nullptr); + + ResponseInfo rspInfo = { ErrorCode::NO_ERROR, std::monostate{} }; + std::shared_ptr handler = nullptr; + handler = channelWrap->AddRspHandler(nullptr, false, 0); + ASSERT_NE(handler, nullptr); + std::lock_guard lock(channelWrap->rspMutex_); + EXPECT_EQ(channelWrap->HandleMsg(handler->msgId_, rspInfo), ErrorCode::NO_ERROR); +} } // namespace MiscServices } // namespace OHOS -- Gitee From 2bfdf8da5fa9e0287750204e5df21e5dcb663331 Mon Sep 17 00:00:00 2001 From: qianyong325 Date: Mon, 4 Aug 2025 14:25:23 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E6=89=93=E7=82=B9?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: qianyong325 --- .../include/input_data_channel_proxy_wrap.h | 1 + .../include/input_method_ability.h | 3 +-- .../src/input_data_channel_proxy_wrap.cpp | 24 +++++++++++++++++-- .../src/input_method_ability.cpp | 20 ---------------- .../inputmethodability_fuzzer.cpp | 1 - .../cpp_test/src/ima_text_edit_test.cpp | 17 +++++++++++++ 6 files changed, 41 insertions(+), 25 deletions(-) diff --git a/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h b/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h index b60b8b73a..c0b54ca2a 100644 --- a/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h +++ b/frameworks/native/inputmethod_ability/include/input_data_channel_proxy_wrap.h @@ -81,6 +81,7 @@ public: std::shared_ptr GetDataChannel(); private: + void ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime); std::shared_ptr AddRspHandler(const AsyncIpcCallBack &callback, bool isSync, int32_t eventCode); int32_t WaitResponse(const std::shared_ptr &rspHandler, const SyncOutput &output); int32_t DeleteRspHandler(uint64_t msgId); diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index 1562d0791..70de8692b 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -127,7 +127,7 @@ public: void OnAttributeChange(InputAttribute attribute); int32_t OnStopInputService(bool isTerminateIme); - void ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime); + HiSysEventClientInfo GetBindClientInfo(); private: std::mutex controlChannelLock_; std::shared_ptr controlChannel_ = nullptr; @@ -190,7 +190,6 @@ private: int32_t StartInputInner(const InputClientInfo &clientInfo, bool isBindFromClient); bool NotifyInfoToWmsInStartInput(const TextTotalConfig &textConfig); void SetBindClientInfo(const InputClientInfo &clientInfo); - HiSysEventClientInfo GetBindClientInfo(); void ClearBindClientInfo(); void ReportImeStartInput(int32_t eventCode, int32_t errCode, bool isShowKeyboard, int64_t consumeTime = -1); void ClearBindInfo(const sptr &channel); diff --git a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp index 616173abd..04e8e442d 100644 --- a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp +++ b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp @@ -22,10 +22,12 @@ #include "string_ex.h" #include "variant_util.h" #include "input_method_ability.h" +#include "ima_hisysevent_reporter.h" namespace OHOS { namespace MiscServices { constexpr std::size_t MESSAGE_UNANSWERED_MAX_NUMBER = 1000; +constexpr uint32_t BASE_TEXT_OPERATION_TIMEOUT = 200; InputDataChannelProxyWrap::InputDataChannelProxyWrap( const std::shared_ptr &channel, const sptr &agentObject) { @@ -289,8 +291,7 @@ int32_t InputDataChannelProxyWrap::HandleMsg(uint64_t msgId, const ResponseInfo it->second->asyncCallback_(rspInfo.dealRet_, rspInfo.data_); } int64_t now = duration_cast(system_clock::now().time_since_epoch()).count(); - InputMethodAbility::GetInstance().ReportBaseTextOperation(it->second->eventCode_, rspInfo.dealRet_, - now - it->second->reportStartTime_); + ReportBaseTextOperation(it->second->eventCode_, rspInfo.dealRet_, now - it->second->reportStartTime_); rspHandlers_.erase(it); return ErrorCode::NO_ERROR; } @@ -321,5 +322,24 @@ int32_t InputDataChannelProxyWrap::DeleteRspHandler(uint64_t msgId) } return ErrorCode::NO_ERROR; } + +void InputDataChannelProxyWrap::ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime) +{ + IMSA_HILOGD("HiSysEvent report start:[%{public}d, %{public}d]!", eventCode, errCode); + auto clientInfo = InputMethodAbility::GetInstance().GetBindClientInfo(); + if (errCode == ErrorCode::NO_ERROR && consumeTime > BASE_TEXT_OPERATION_TIMEOUT) { + errCode = ErrorCode::ERROR_DEAL_TIMEOUT; + } + auto evenInfo = HiSysOriginalInfo::Builder() + .SetPeerName(clientInfo.name) + .SetPeerPid(clientInfo.pid) + .SetClientType(clientInfo.type) + .SetEventCode(eventCode) + .SetErrCode(errCode) + .SetBaseTextOperatorTime(consumeTime) + .Build(); + ImaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::BASE_TEXT_OPERATOR, *evenInfo); + IMSA_HILOGD("HiSysEvent report end:[%{public}d, %{public}d]!", eventCode, errCode); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index a3669a51b..d09b60c9f 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -49,7 +49,6 @@ constexpr uint32_t FIND_PANEL_RETRY_INTERVAL = 10; constexpr uint32_t MAX_RETRY_TIMES = 100; constexpr uint32_t START_INPUT_CALLBACK_TIMEOUT_MS = 1000; constexpr uint32_t INVALID_SECURITY_MODE = -1; -constexpr uint32_t BASE_TEXT_OPERATION_TIMEOUT = 200; InputMethodAbility::InputMethodAbility() { @@ -1689,25 +1688,6 @@ void InputMethodAbility::ReportImeStartInput( IMSA_HILOGD("HiSysEvent report end:[%{public}d, %{public}d]!", eventCode, errCode); } -void InputMethodAbility::ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime) -{ - IMSA_HILOGD("HiSysEvent report start:[%{public}d, %{public}d]!", eventCode, errCode); - auto clientInfo = GetBindClientInfo(); - if (errCode == ErrorCode::NO_ERROR && consumeTime > BASE_TEXT_OPERATION_TIMEOUT) { - errCode = ErrorCode::ERROR_DEAL_TIMEOUT; - } - auto evenInfo = HiSysOriginalInfo::Builder() - .SetPeerName(clientInfo.name) - .SetPeerPid(clientInfo.pid) - .SetClientType(clientInfo.type) - .SetEventCode(eventCode) - .SetErrCode(errCode) - .SetBaseTextOperatorTime(consumeTime) - .Build(); - ImaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::BASE_TEXT_OPERATOR, *evenInfo); - IMSA_HILOGD("HiSysEvent report end:[%{public}d, %{public}d]!", eventCode, errCode); -} - int32_t InputMethodAbility::OnCallingDisplayIdChanged(uint64_t displayId) { IMSA_HILOGD("InputMethodAbility calling display: %{public}" PRIu64 ".", displayId); diff --git a/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp b/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp index 33e703491..e6b822bfa 100644 --- a/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp +++ b/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp @@ -190,7 +190,6 @@ void TestInterfaceCoverage(int32_t dataInt32, bool dataBool, std::u16string &tex InputMethodAbility::GetInstance().GetSecurityMode(dataInt32); InputMethodAbility::GetInstance().FinishTextPreview(); InputMethodAbility::GetInstance().GetTextBeforeCursor(dataInt32, text); - InputMethodAbility::GetInstance().ReportBaseTextOperation(dataInt32, dataInt32, consumeTime); } } // namespace OHOS diff --git a/test/unittest/cpp_test/src/ima_text_edit_test.cpp b/test/unittest/cpp_test/src/ima_text_edit_test.cpp index 16d505a1c..49c2112fd 100644 --- a/test/unittest/cpp_test/src/ima_text_edit_test.cpp +++ b/test/unittest/cpp_test/src/ima_text_edit_test.cpp @@ -521,5 +521,22 @@ HWTEST_F(ImaTextEditTest, ImaTextEditTest_HandleMsg, TestSize.Level0) std::lock_guard lock(channelWrap->rspMutex_); EXPECT_EQ(channelWrap->HandleMsg(handler->msgId_, rspInfo), ErrorCode::NO_ERROR); } + +/** + * @tc.name: ImaTextEditTest_Report + * @tc.desc: + * @tc.type: FUNC + */ +HWTEST_F(ImaTextEditTest, ImaTextEditTest_Report, TestSize.Level0) +{ + const int64_t timeout = 200 + 1; + IMSA_HILOGI("ImeProxyTest::ImaTextEditTest_Report"); + auto channelProxy = std::make_shared(nullptr); + auto channelWrap = std::make_shared(channelProxy, nullptr); + + channelWrap->ReportBaseTextOperation(1, ErrorCode::NO_ERROR, 1); + channelWrap->ReportBaseTextOperation(1, ErrorCode::ERROR_NULL_POINTER, 1); + channelWrap->ReportBaseTextOperation(1, ErrorCode::NO_ERROR, timeout); +} } // namespace MiscServices } // namespace OHOS -- Gitee From 4f0d9fd80869935a083e50e5e32ac7fc5ee5c21b Mon Sep 17 00:00:00 2001 From: qianyong325 Date: Mon, 4 Aug 2025 16:28:07 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=A4=E7=A9=BA?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: qianyong325 --- .../inputmethod_ability/src/input_data_channel_proxy_wrap.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp index 04e8e442d..6b2569697 100644 --- a/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp +++ b/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp @@ -192,6 +192,10 @@ int32_t InputDataChannelProxyWrap::FinishTextPreview(const AsyncIpcCallBack &cal int32_t InputDataChannelProxyWrap::Request(const AsyncIpcCallBack &callback, const ChannelWork &work, bool isSync, int32_t eventCode, const SyncOutput &output) { + if (work == nullptr) { + IMSA_HILOGE("work is nullptr. sync: %{public}d event code: %{public}d", isSync, eventCode); + return ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL; + } auto channel = GetDataChannel(); if (channel == nullptr) { IMSA_HILOGE("data channel is nullptr!"); -- Gitee