diff --git a/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.cpp b/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.cpp index 7130042046f77eb8f1b808796873281538d27c28..c8ee56ef1826e1f236a0570ea81ae1a39a50451e 100644 --- a/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.cpp +++ b/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.cpp @@ -295,8 +295,8 @@ napi_value JsKeyboardDelegateSetting::GetResultOnKeyEvent(napi_env env, int32_t return KeyboardDelegate; } -bool JsKeyboardDelegateSetting::OnDealKeyEvent(const std::shared_ptr &keyEvent, - sptr &consumer) +bool JsKeyboardDelegateSetting::OnDealKeyEvent( + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) { if (keyEvent == nullptr) { IMSA_HILOGE("keyEvent is nullptr"); @@ -318,16 +318,16 @@ bool JsKeyboardDelegateSetting::OnDealKeyEvent(const std::shared_ptrPostTask(task, "OnDealKeyEvent", 0, AppExecFwk::EventQueue::Priority::VIP); return true; } void JsKeyboardDelegateSetting::DealKeyEvent(const std::shared_ptr &keyEvent, - const std::shared_ptr &keyEventEntry, const std::shared_ptr &keyCodeEntry, - const sptr &consumer) + const std::shared_ptr &keyEventEntry, const std::shared_ptr &keyCodeEntry, uint64_t cbId, + const sptr &channelObject) { bool isKeyEventConsumed = false; bool isKeyCodeConsumed = false; @@ -368,15 +368,15 @@ void JsKeyboardDelegateSetting::DealKeyEvent(const std::shared_ptrvecCopy, { 1, getKeyEventProperty }, isKeyCodeConsumed); } bool consumeResult = isKeyEventConsumed || isKeyCodeConsumed; - if (consumer != nullptr) { - if (!consumeResult) { - if (keyEvent != nullptr && keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) { - IMSA_HILOGW("keyEvent is not consumed by ime"); - } - consumeResult = InputMethodAbility::GetInstance().HandleUnconsumedKey(keyEvent); + if (!consumeResult) { + if (keyEvent != nullptr && keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) { + IMSA_HILOGW("keyEvent is not consumed by ime"); } - IMSA_HILOGD("final consumed result: %{public}d.", consumeResult); - consumer->OnKeyEventResult(consumeResult); + consumeResult = InputMethodAbility::GetInstance().HandleUnconsumedKey(keyEvent); + } + auto ret = InputMethodAbility::GetInstance().HandleKeyEventResult(cbId, consumeResult, channelObject); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("handle keyEvent failed:%{public}d", ret); } } diff --git a/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.h b/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.h index 7c39991a625f9c0bf19ca883642394da0b57d0cd..59301fe4b0157762559640905505295b726ef64b 100644 --- a/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.h +++ b/frameworks/js/napi/inputmethodability/js_keyboard_delegate_setting.h @@ -46,7 +46,8 @@ public: void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override; void OnTextChange(const std::string &text) override; void OnEditorAttributeChange(const InputAttribute &inputAttribute) override; - bool OnDealKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) override; + bool OnDealKeyEvent(const std::shared_ptr &keyEvent, uint64_t cbId, + const sptr &channelObject) override; void OnKeyEventConsumeResult(bool isConsumed, sptr consumer); void OnKeyCodeConsumeResult(bool isConsumed, sptr consumer); @@ -97,8 +98,8 @@ private: static std::shared_ptr GetEventHandler(); std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); static void DealKeyEvent(const std::shared_ptr &keyEvent, - const std::shared_ptr &keyEventEntry, const std::shared_ptr &keyCodeEntry, - const sptr &consumer); + const std::shared_ptr &keyEventEntry, const std::shared_ptr &keyCodeEntry, uint64_t cbId, + const sptr &channelObject); std::recursive_mutex mutex_; std::map>> jsCbMap_; static std::mutex keyboardMutex_; diff --git a/frameworks/native/inputmethod_ability/IInputMethodAgent.idl b/frameworks/native/inputmethod_ability/IInputMethodAgent.idl index 66b5c61fe45c200ee1371a0a2fdd16154aeff815..16d7eb7ed27168e2d1f012b60bae760217672cbc 100644 --- a/frameworks/native/inputmethod_ability/IInputMethodAgent.idl +++ b/frameworks/native/inputmethod_ability/IInputMethodAgent.idl @@ -18,9 +18,9 @@ sequenceable input_method_utils..OHOS.MiscServices.Value; sequenceable input_method_utils..OHOS.MiscServices.KeyEventValue; sequenceable input_method_utils..OHOS.MiscServices.ArrayBuffer; sequenceable input_method_utils..OHOS.MiscServices.ResponseDataInner; -interface OHOS.MiscServices.IKeyEventConsumer; +sequenceable OHOS.IRemoteObject; interface OHOS.MiscServices.IInputMethodAgent { - [ipccode 0] void DispatchKeyEvent([in] KeyEventValue keyEvent, [in] IKeyEventConsumer consumer); + [ipccode 0] void DispatchKeyEvent([in] KeyEventValue keyEvent, [in] unsigned long cbId, [in] IRemoteObject channelObject); void OnCursorUpdate([in] int positionX, [in] int positionY, [in] int height); void OnSelectionChange([in] String text, [in] int oldBegin, [in] int oldEnd, [in] int newBegin, [in] int newEnd); void SetCallingWindow([in] unsigned int windowId); diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index e69116c88e4f18480f6297d78522cee86d204666..8637a814dd4c712667f97bfc80b9e5314c41fbe0 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -72,7 +72,8 @@ public: int32_t MoveCursor(int32_t keyCode, const AsyncIpcCallBack &callback = nullptr); int32_t SelectByRange(int32_t start, int32_t end, const AsyncIpcCallBack &callback = nullptr); int32_t SelectByMovement(int32_t direction, const AsyncIpcCallBack &callback = nullptr); - int32_t DispatchKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer); + int32_t DispatchKeyEvent( + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject); void SetCallingWindow(uint32_t windowId); int32_t GetEnterKeyType(int32_t &keyType); int32_t GetInputPattern(int32_t &inputPattern); @@ -114,6 +115,7 @@ public: int32_t OnResponse(uint64_t msgId, int32_t code, const ResponseData &data); int32_t IsCapacitySupport(int32_t capacity, bool &isSupport); AttachOptions GetAttachOptions(); + int32_t HandleKeyEventResult(uint64_t cbId, bool consumeResult, const sptr &channelObject); public: /* called from TaskManager worker thread */ diff --git a/frameworks/native/inputmethod_ability/include/input_method_agent_service_impl.h b/frameworks/native/inputmethod_ability/include/input_method_agent_service_impl.h index b77a72e71ed91e5eb67775d0938c199a80f52bc1..93a15e47a670a71cd4087dc6ace1bec38a3c4e2f 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_agent_service_impl.h +++ b/frameworks/native/inputmethod_ability/include/input_method_agent_service_impl.h @@ -30,7 +30,7 @@ public: InputMethodAgentServiceImpl(); ~InputMethodAgentServiceImpl(); ErrCode DispatchKeyEvent( - const MiscServices::KeyEventValue &keyEvent, const sptr &consumer) override; + const MiscServices::KeyEventValue &keyEvent, uint64_t cbId, const sptr &channelObject) override; ErrCode OnCursorUpdate(int32_t positionX, int32_t positionY, int height) override; ErrCode OnSelectionChange( const std::string& text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override; diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 3b364924eb02d82ef6d3081027fbb20cce8bc42e..416af08abf0b61166130c51263f7d3747f974989 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -433,7 +433,7 @@ void InputMethodAbility::ClearBindInfo(const sptr &channel) } int32_t InputMethodAbility::DispatchKeyEvent( - const std::shared_ptr &keyEvent, sptr &consumer) + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) { if (keyEvent == nullptr) { IMSA_HILOGE("keyEvent is nullptr!"); @@ -445,7 +445,7 @@ int32_t InputMethodAbility::DispatchKeyEvent( } IMSA_HILOGD("InputMethodAbility, start."); - if (!kdListener_->OnDealKeyEvent(keyEvent, consumer)) { + if (!kdListener_->OnDealKeyEvent(keyEvent, cbId, channelObject)) { IMSA_HILOGE("keyEvent not deal!"); return ErrorCode::ERROR_DISPATCH_KEY_EVENT; } @@ -1240,9 +1240,7 @@ int32_t InputMethodAbility::HidePanel( info.sessionId = sessionId; NotifyPanelStatusInfo(info); if (trigger == Trigger::IMF && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD) { - AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) { - ; - }; + AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) {}; FinishTextPreview(callback); } return ErrorCode::NO_ERROR; @@ -1505,9 +1503,7 @@ void InputMethodAbility::OnClientInactive(const sptr &channel) NotifyPanelStatusInfo(info, channelProxy); // finish previewing text when soft keyboard hides if (panel->GetPanelType() == PanelType::SOFT_KEYBOARD) { - AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) { - ; - }; + AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) {}; FinishTextPreview(callback); } return false; @@ -1912,9 +1908,7 @@ bool InputMethodAbility::HandleUnconsumedKey(const std::shared_ptrGetKeyCode(); std::string inputNumber; - AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) { - ; - }; + AsyncIpcCallBack callback = [](int32_t code, const ResponseData &data) {}; if (MMI::KeyEvent::KEYCODE_0 <= keyCode && keyCode <= MMI::KeyEvent::KEYCODE_9) { IMSA_HILOGI("auto input a number"); channel->InsertText(std::to_string(keyCode - MMI::KeyEvent::KEYCODE_0), callback); @@ -1966,5 +1960,17 @@ int32_t InputMethodAbility::OnNotifyPreemption() imeListener->NotifyPreemption(); return ErrorCode::NO_ERROR; } + +int32_t InputMethodAbility::HandleKeyEventResult( + uint64_t cbId, bool consumeResult, const sptr &channelObject) +{ + IMSA_HILOGD("run in:%{public}" PRIu64 "/%{public}d.", cbId, consumeResult); + if (channelObject == nullptr) { + IMSA_HILOGE("channelObject is nullptr:%{public}" PRIu64 ".", cbId); + return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR; + } + auto channel = std::make_shared(channelObject); + return channel->HandleKeyEventResult(cbId, consumeResult); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/src/input_method_agent_service_impl.cpp b/frameworks/native/inputmethod_ability/src/input_method_agent_service_impl.cpp index 76f92e2fadffc9ca8654b62e1435600b403bd018..e4fad002428c36c508db2962a081b5ed1876d108 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_agent_service_impl.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_agent_service_impl.cpp @@ -31,10 +31,9 @@ InputMethodAgentServiceImpl::InputMethodAgentServiceImpl() {} InputMethodAgentServiceImpl::~InputMethodAgentServiceImpl() {} ErrCode InputMethodAgentServiceImpl::DispatchKeyEvent( - const MiscServices::KeyEventValue &keyEvent, const sptr &consumer) + const MiscServices::KeyEventValue &keyEvent, uint64_t cbId, const sptr &channelObject) { - sptr proxyConsumer = new (std::nothrow) KeyEventConsumerProxy(consumer->AsObject()); - return InputMethodAbility::GetInstance().DispatchKeyEvent(keyEvent.event, proxyConsumer); + return InputMethodAbility::GetInstance().DispatchKeyEvent(keyEvent.event, cbId, channelObject); } ErrCode InputMethodAgentServiceImpl::SetCallingWindow(uint32_t windowId) diff --git a/frameworks/native/inputmethod_controller/IInputDataChannel.idl b/frameworks/native/inputmethod_controller/IInputDataChannel.idl index 011eebb14c1c8b7982482b4d28a75787ba471aca..19940a67df789c864b40482a627e1787daab5259 100644 --- a/frameworks/native/inputmethod_controller/IInputDataChannel.idl +++ b/frameworks/native/inputmethod_controller/IInputDataChannel.idl @@ -43,4 +43,5 @@ interface OHOS.MiscServices.IInputDataChannel { [oneway] void SetPreviewText([in] String text, [in] RangeInner rangeInner, [in] unsigned long msgId, [in] IRemoteObject agent); [oneway] void FinishTextPreview([in] unsigned long msgId, [in] IRemoteObject agent); void SendMessage([in] ArrayBuffer arraybuffer); + [oneway] void HandleKeyEventResult([in] unsigned long cbId, [in] boolean consumeResult); } diff --git a/frameworks/native/inputmethod_controller/include/input_data_channel_service_impl.h b/frameworks/native/inputmethod_controller/include/input_data_channel_service_impl.h index 4b0124877a03ce751ddf1d2e9aec9d82a87aa9c9..5faf86e60f73673bc781c0eb98e43a8a69c5c90a 100644 --- a/frameworks/native/inputmethod_controller/include/input_data_channel_service_impl.h +++ b/frameworks/native/inputmethod_controller/include/input_data_channel_service_impl.h @@ -54,6 +54,7 @@ public: const sptr &agent) override; ErrCode FinishTextPreview(uint64_t msgId, const sptr &agent) override; ErrCode SendMessage(const ArrayBuffer &arraybuffer) override; + ErrCode HandleKeyEventResult(uint64_t cbId, bool consumeResult) override; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_controller/include/key_event_result_handler.h b/frameworks/native/inputmethod_controller/include/key_event_result_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..a6eb46c40a9e43e14ccbbbe8b5f223df600358d8 --- /dev/null +++ b/frameworks/native/inputmethod_controller/include/key_event_result_handler.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025 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. + */ +#ifndef FRAMEWORKS_INPUTMETHOD_KEY_EVENT_RESULT_HANDLER_H +#define FRAMEWORKS_INPUTMETHOD_KEY_EVENT_RESULT_HANDLER_H +#include +#include + +#include "key_event.h" +namespace OHOS { +namespace MiscServices { +using KeyEventCallback = std::function &keyEvent, bool isConsumed)>; +struct KeyEventCbInfo { + std::shared_ptr keyEvent{ nullptr }; + KeyEventCallback callback{ nullptr }; +}; +class KeyEventResultHandler { +public: + uint64_t AddKeyEventCbInfo(const KeyEventCbInfo &cbInfo); + void RemoveKeyEventCbInfo(uint64_t cbId); + void HandleKeyEventResult(uint64_t cbId, bool consumeResult); + void ClearKeyEventCbInfo(); + +private: + int32_t GetKeyEventCbInfo(uint64_t cbId, KeyEventCbInfo &info); + uint64_t GenerateKeyEventCbId(); + std::mutex keyEventCbHandlersMutex_; + std::map keyEventCbHandlers_; + std::atomic maxCbId_{1}; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // FRAMEWORKS_INPUTMETHOD_KEY_EVENT_RESULT_HANDLER_H \ No newline at end of file diff --git a/frameworks/native/inputmethod_controller/src/input_data_channel_service_impl.cpp b/frameworks/native/inputmethod_controller/src/input_data_channel_service_impl.cpp index 7a0d4e2ca3135265f2483b5fe321339080a3bbf5..3fe14bf3535cf1b7bb7cfc34e8662b91972e8214 100644 --- a/frameworks/native/inputmethod_controller/src/input_data_channel_service_impl.cpp +++ b/frameworks/native/inputmethod_controller/src/input_data_channel_service_impl.cpp @@ -301,5 +301,16 @@ ErrCode InputDataChannelServiceImpl::SendMessage(const ArrayBuffer &arraybuffer) } return instance->RecvMessage(arraybuffer); } + +ErrCode InputDataChannelServiceImpl::HandleKeyEventResult(uint64_t cbId, bool consumeResult) +{ + auto instance = InputMethodController::GetInstance(); + if (instance == nullptr) { + IMSA_HILOGE("failed to get InputMethodController instance!"); + return ErrorCode::ERROR_EX_NULL_POINTER; + } + instance->HandleKeyEventResult(cbId, consumeResult); + return ERR_OK; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index d8408fcbeaa0bcf3ffe27d147e490ada0ab8c83e..de27767ffb8ca9fcf2f7839b216267b43946788c 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -981,22 +981,33 @@ int32_t InputMethodController::DispatchKeyEvent(std::shared_ptr k return ErrorCode::ERROR_IME_NOT_STARTED; } IMSA_HILOGD("start."); - sptr consumer = new (std::nothrow) KeyEventConsumerServiceImpl(callback, keyEvent); - if (consumer == nullptr) { - IMSA_HILOGE("consumer is nullptr!"); + sptr channelObject = nullptr; + { + std::lock_guard lock(clientInfoLock_); + channelObject = clientInfo_.channel; + } + if (channelObject == nullptr) { + IMSA_HILOGE("channelObject is nullptr!"); keyEventQueue_.Pop(); return ErrorCode::ERROR_EX_NULL_POINTER; } + auto cbId = keyEventRetHandler_.AddKeyEventCbInfo({ keyEvent, callback }); KeyEventValue keyEventValue; keyEventValue.event = keyEvent; - auto ret = agent->DispatchKeyEvent(keyEventValue, consumer); + auto ret = agent->DispatchKeyEvent(keyEventValue, cbId, channelObject); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to DispatchKeyEvent: %{public}d", ret); + keyEventRetHandler_.RemoveKeyEventCbInfo(cbId); } keyEventQueue_.Pop(); return ret; } +void InputMethodController::HandleKeyEventResult(uint64_t cbId, bool consumeResult) +{ + keyEventRetHandler_.HandleKeyEventResult(cbId, consumeResult); +} + int32_t InputMethodController::GetEnterKeyType(int32_t &keyType) { IMSA_HILOGD("InputMethodController::GetEnterKeyType start."); @@ -1212,6 +1223,7 @@ void InputMethodController::OnInputStop(bool isStopInactiveClient, sptr lock(editorContentLock_); textString_ = Str8ToStr16(""); diff --git a/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp b/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2faaf423e11620f678e6530845968b19ec13fc6b --- /dev/null +++ b/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 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 "key_event_result_handler.h" + +#include + +#include "global.h" +namespace OHOS { +namespace MiscServices { +uint64_t KeyEventResultHandler::AddKeyEventCbInfo(const KeyEventCbInfo &cbInfo) +{ + std::lock_guard lock(keyEventCbHandlersMutex_); + auto cbId = GenerateKeyEventCbId(); + IMSA_HILOGD("%{public}" PRIu64 "add.", cbId); + keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + return cbId; +} + +void KeyEventResultHandler::HandleKeyEventResult(uint64_t cbId, bool consumeResult) +{ + IMSA_HILOGD("result:%{public}" PRIu64 "/%{public}d.", cbId, consumeResult); + KeyEventCbInfo info; + auto ret = GetKeyEventCbInfo(cbId, info); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("%{public}" PRIu64 "not be found.", cbId); + return; + } + if (info.callback == nullptr) { + IMSA_HILOGE("%{public}" PRIu64 "callback is nullptr.", cbId); + } else { + info.callback(info.keyEvent, consumeResult); + } + RemoveKeyEventCbInfo(cbId); +} + +void KeyEventResultHandler::ClearKeyEventCbInfo() +{ + std::lock_guard lock(keyEventCbHandlersMutex_); + keyEventCbHandlers_.clear(); +} + +void KeyEventResultHandler::RemoveKeyEventCbInfo(uint64_t cbId) +{ + std::lock_guard lock(keyEventCbHandlersMutex_); + auto iter = keyEventCbHandlers_.find(cbId); + if (iter == keyEventCbHandlers_.end()) { + return; + } + keyEventCbHandlers_.erase(cbId); +} + +int32_t KeyEventResultHandler::GetKeyEventCbInfo(uint64_t cbId, KeyEventCbInfo &info) +{ + std::lock_guard lock(keyEventCbHandlersMutex_); + auto iter = keyEventCbHandlers_.find(cbId); + if (iter != keyEventCbHandlers_.end()) { + info = iter->second; + return ErrorCode::NO_ERROR; + } + return ErrorCode::ERROR_BAD_PARAMETERS; +} + +uint64_t KeyEventResultHandler::GenerateKeyEventCbId() +{ + return maxCbId_.fetch_add(1); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/inputmethod_ability/include/keyboard_listener.h b/interfaces/inner_api/inputmethod_ability/include/keyboard_listener.h index d1ab39894b6c8a139305026bab591a7e0d142eed..85cce5d1b6da686d9a5b84b52c37480799cb6181 100644 --- a/interfaces/inner_api/inputmethod_ability/include/keyboard_listener.h +++ b/interfaces/inner_api/inputmethod_ability/include/keyboard_listener.h @@ -24,8 +24,8 @@ namespace MiscServices { class KeyboardListener { public: virtual ~KeyboardListener() = default; - virtual bool OnDealKeyEvent(const std::shared_ptr &keyEvent, - sptr &consumer) = 0; + virtual bool OnDealKeyEvent( + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) = 0; virtual bool OnKeyEvent(int32_t keyCode, int32_t keyStatus, sptr &consumer) = 0; virtual bool OnKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) = 0; virtual void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) = 0; diff --git a/interfaces/inner_api/inputmethod_controller/BUILD.gn b/interfaces/inner_api/inputmethod_controller/BUILD.gn index 87a05c06541bbe86dd855b97ff3d73a8113bb1e3..b18b0bde25518c17f7be63b807e6dc799d081661 100644 --- a/interfaces/inner_api/inputmethod_controller/BUILD.gn +++ b/interfaces/inner_api/inputmethod_controller/BUILD.gn @@ -281,6 +281,7 @@ ohos_shared_library("inputmethod_client") { "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_tools.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_utils.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_service_impl.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_service_impl.cpp", ] @@ -385,6 +386,7 @@ ohos_static_library("inputmethod_client_static") { "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_tools.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_utils.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_service_impl.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_service_impl.cpp", ] @@ -464,6 +466,7 @@ ohos_static_library("inputmethod_client_fuzz_static") { "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_tools.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_utils.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_service_impl.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/key_event_result_handler.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_service_impl.cpp", ] diff --git a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h index faf71602b171a1ff7059e566e3a6c8830fe850fc..b1946334a7405f16403e89a991ec6e1fb5642162 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -18,8 +18,8 @@ #include #include -#include #include +#include #include #include #include @@ -36,11 +36,12 @@ #include "input_method_property.h" #include "input_method_status.h" #include "input_method_utils.h" +#include "inputmethod_message_handler.h" #include "ipc_skeleton.h" #include "iremote_object.h" #include "key_event.h" +#include "key_event_result_handler.h" #include "msg_handler_callback_interface.h" -#include "inputmethod_message_handler.h" #include "panel_info.h" #include "private_command_interface.h" #include "visibility.h" @@ -979,6 +980,9 @@ public: * @since 18 */ IMF_API int32_t RegisterWindowScaleCallbackHandler(WindowScaleCallback&& callback); + + void HandleKeyEventResult(uint64_t cbId, bool consumeResult); + #ifdef OHOS_IMF_TEST void SetImsaProxyForTest(sptr proxy); #endif // OHOS_IMF_TEST @@ -1097,6 +1101,7 @@ private: std::mutex windowScaleCallbackMutex_; WindowScaleCallback windowScaleCallback_ = nullptr; + KeyEventResultHandler keyEventRetHandler_; }; } // namespace MiscServices } // namespace OHOS diff --git a/test/common/include/keyboard_listener_test_impl.h b/test/common/include/keyboard_listener_test_impl.h index e0ec354f718a4a0bd82ca6cb3fde081eeecd89ee..cbd212208042fecdbf3f3f9f32dad9b2c90d33ae 100644 --- a/test/common/include/keyboard_listener_test_impl.h +++ b/test/common/include/keyboard_listener_test_impl.h @@ -32,7 +32,8 @@ public: { return false; } - bool OnDealKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) override; + bool OnDealKeyEvent(const std::shared_ptr &keyEvent, uint64_t cbId, + const sptr &channelObject) override; void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override; void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override; void OnTextChange(const std::string &text) override; diff --git a/test/common/src/keyboard_listener_test_impl.cpp b/test/common/src/keyboard_listener_test_impl.cpp index b1896dd22b4b44e91895b0661a1ce7b94e303739..19768c19af52d72d21d1b24ef36f3c185e4a33d6 100644 --- a/test/common/src/keyboard_listener_test_impl.cpp +++ b/test/common/src/keyboard_listener_test_impl.cpp @@ -34,13 +34,11 @@ bool KeyboardListenerTestImpl::OnKeyEvent(int32_t keyCode, int32_t keyStatus, sp } bool KeyboardListenerTestImpl::OnDealKeyEvent( - const std::shared_ptr &keyEvent, sptr &consumer) + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) { - bool isKeyCodeConsume = OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer); - bool isKeyEventConsume = OnKeyEvent(keyEvent, consumer); - if (consumer != nullptr) { - consumer->OnKeyEventResult(isKeyEventConsume || isKeyCodeConsume); - } + sptr consumer = new (std::nothrow) KeyEventConsumerProxy(nullptr); + OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer); + OnKeyEvent(keyEvent, consumer); return true; } diff --git a/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp b/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp index 1da238790f220939f5e193fd99ef99fb0fa9c5b3..5b19960ed0f08148d50ccd656d2bcce4ab07ab05 100644 --- a/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp +++ b/test/fuzztest/inputmethodability_fuzzer/inputmethodability_fuzzer.cpp @@ -39,7 +39,8 @@ class KeyboardListenerImpl : public KeyboardListener { { return true; } - bool OnDealKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) + bool OnDealKeyEvent( + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) { return true; } @@ -128,8 +129,7 @@ void TestDispatchKeyEvent(int32_t fuzzedInt32) std::shared_ptr keyEvent = MMI::KeyEvent::Create(); keyEvent->SetKeyCode(fuzzedInt32); keyEvent->SetKeyAction(fuzzedInt32); - sptr consumer = new (std::nothrow) KeyEventConsumerProxy(nullptr); - InputMethodAbility::GetInstance().DispatchKeyEvent(keyEvent, consumer); + InputMethodAbility::GetInstance().DispatchKeyEvent(keyEvent, fuzzedInt32, nullptr); } void TestSetCallingWindow(int32_t fuzzedInt32) diff --git a/test/unittest/cpp_test/src/ime_mirror_demo.cpp b/test/unittest/cpp_test/src/ime_mirror_demo.cpp index e56c0009db22377bf94882861bf4a5b041069c0b..a456c73f1ed378c68e14a32b790ef0a9d194ba42 100644 --- a/test/unittest/cpp_test/src/ime_mirror_demo.cpp +++ b/test/unittest/cpp_test/src/ime_mirror_demo.cpp @@ -18,6 +18,7 @@ #include "sys_cfg_parser.h" using namespace std; +using namespace OHOS; using namespace OHOS::MiscServices; class InputMethodEngineListenerImpl : public InputMethodEngineListener { public: @@ -66,8 +67,8 @@ class KeyboardListenerImpl : public KeyboardListener { public: KeyboardListenerImpl() = default; ~KeyboardListenerImpl() = default; - bool OnDealKeyEvent( - const std::shared_ptr &keyEvent, OHOS::sptr &consumer) override + bool OnDealKeyEvent(const std::shared_ptr &keyEvent, uint64_t cbId, + const sptr &channelObject) override { return false; } diff --git a/test/unittest/cpp_test/src/input_method_ability_exception_test.cpp b/test/unittest/cpp_test/src/input_method_ability_exception_test.cpp index 8e69bdf4c8b3093b61d8eb5f6695c7a6858dfbfe..d52c66caf6627455bee9746104879d0b083c6562 100644 --- a/test/unittest/cpp_test/src/input_method_ability_exception_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_exception_test.cpp @@ -229,13 +229,13 @@ HWTEST_F(InputMethodAbilityExceptionTest, testDispatchKeyEventException, TestSiz IMSA_HILOGI("InputMethodAbilityExceptionTest DispatchKeyEvent START"); // keyEvent == nullptr; std::shared_ptr keyEvent = nullptr; - sptr consumer = new (std::nothrow) KeyEventConsumerProxy(nullptr); - auto ret = inputMethodAbility_.DispatchKeyEvent(keyEvent, consumer); + uint64_t cbId = 12; + auto ret = inputMethodAbility_.DispatchKeyEvent(keyEvent, cbId, nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); // kdListener_ == nullptr keyEvent = KeyEventUtil::CreateKeyEvent(MMI::KeyEvent::KEYCODE_A, MMI::KeyEvent::KEY_ACTION_DOWN); - ret = inputMethodAbility_.DispatchKeyEvent(keyEvent, consumer); + ret = inputMethodAbility_.DispatchKeyEvent(keyEvent, cbId, nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); } @@ -391,5 +391,21 @@ HWTEST_F(InputMethodAbilityExceptionTest, OnClientInactive_001, TestSize.Level1) inputMethodAbility_.OnClientInactive(inputMethodAbility_.dataChannelObject_); EXPECT_EQ(inputMethodAbility_.dataChannelObject_, nullptr); } + +/** + * @tc.name: HandleKeyEventResult_001 + * @tc.desc: HandleKeyEventResult Exception + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(InputMethodAbilityExceptionTest, HandleKeyEventResult_001, TestSize.Level1) +{ + IMSA_HILOGI("InputMethodAbilityExceptionTest HandleKeyEventResult_001 START"); + uint64_t cbId = 9; + bool consumeResult = true; + auto ret = inputMethodAbility_.HandleKeyEventResult(cbId, consumeResult, nullptr); + EXPECT_EQ(ret, ErrorCode::ERROR_IMA_CHANNEL_NULLPTR); +} } // namespace MiscServices } // namespace OHOS diff --git a/test/unittest/cpp_test/src/input_method_controller_test.cpp b/test/unittest/cpp_test/src/input_method_controller_test.cpp index d54d1b50e834bdb954646236267d1c1949ae5784..bbb3a70a61a3c42de178c1dc23c79590e8647375 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -21,6 +21,7 @@ #include "input_data_channel_stub.h" #include "input_method_ability.h" #include "input_method_system_ability.h" +#include "key_event_result_handler.h" #include "task_manager.h" #undef private @@ -201,15 +202,15 @@ public: blockFullKeyEvent_.SetValue(fullKey); return true; } - bool OnDealKeyEvent( - const std::shared_ptr &keyEvent, sptr &consumer) override + bool OnDealKeyEvent(const std::shared_ptr &keyEvent, uint64_t cbId, + const sptr &channelObject) override { IMSA_HILOGI("KeyboardListenerImpl run in"); + sptr consumer = new (std::nothrow) KeyEventConsumerProxy(nullptr); bool isKeyCodeConsume = OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer); bool isKeyEventConsume = OnKeyEvent(keyEvent, consumer); - if (consumer != nullptr) { - consumer->OnKeyEventResult(isKeyEventConsume | isKeyCodeConsume); - } + InputMethodAbility::GetInstance().HandleKeyEventResult( + cbId, isKeyEventConsume | isKeyCodeConsume, channelObject); return true; } void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override @@ -2183,5 +2184,107 @@ HWTEST_F(InputMethodControllerTest, TestEventCallback, TestSize.Level0) EXPECT_EQ(keyevent, nullptr); eventcallback->OnInputEvent(keyEvent_); } + +/** + * @tc.name: TestGetKeyEventCbInfo + * @tc.desc: Test GetKeyEventCbInfo + * @tc.type: FUNC + */ +HWTEST_F(InputMethodControllerTest, TestGetKeyEventCbInfo, TestSize.Level0) +{ + IMSA_HILOGI("TestGetKeyEventCbInfo START"); + KeyEventResultHandler keyEventRetHandler; + keyEventRetHandler.keyEventCbHandlers_.clear(); + uint64_t cbId = 13; + KeyEventCbInfo info; + auto ret = keyEventRetHandler.GetKeyEventCbInfo(cbId, info); + EXPECT_NE(ret, ErrorCode::NO_ERROR); + + KeyEventCbInfo cbInfo; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + ret = keyEventRetHandler.GetKeyEventCbInfo(cbId, info); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(info.callback, nullptr); + + auto cb = [](std::shared_ptr &keyEvent, bool isConsumed) {}; + cbInfo.callback = cb; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + ret = keyEventRetHandler.GetKeyEventCbInfo(cbId, info); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_NE(info.callback, nullptr); +} + +/** + * @tc.name: TestRemoveKeyEventCbInfo + * @tc.desc: Test RemoveKeyEventCbInfo + * @tc.type: FUNC + */ +HWTEST_F(InputMethodControllerTest, TestRemoveKeyEventCbInfo, TestSize.Level0) +{ + IMSA_HILOGI("TestRemoveKeyEventCbInfo START"); + KeyEventResultHandler keyEventRetHandler; + keyEventRetHandler.keyEventCbHandlers_.clear(); + uint64_t cbId = 13; + auto cb = [](std::shared_ptr &keyEvent, bool isConsumed) {}; + KeyEventCbInfo cbInfo{ nullptr, cb }; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + EXPECT_EQ(keyEventRetHandler.keyEventCbHandlers_.size(), 1); + + uint64_t cbId1 = 14; + keyEventRetHandler.RemoveKeyEventCbInfo(cbId1); + EXPECT_EQ(keyEventRetHandler.keyEventCbHandlers_.size(), 1); + + keyEventRetHandler.RemoveKeyEventCbInfo(cbId); + EXPECT_TRUE(keyEventRetHandler.keyEventCbHandlers_.empty()); +} + +/** + * @tc.name: TestHandleKeyEventResult + * @tc.desc: Test HandleKeyEventResult + * @tc.type: FUNC + */ +HWTEST_F(InputMethodControllerTest, TestHandleKeyEventResult, TestSize.Level0) +{ + IMSA_HILOGI("TestHandleKeyEventResult START"); + KeyEventResultHandler keyEventRetHandler; + keyEventRetHandler.keyEventCbHandlers_.clear(); + uint64_t cbId = 13; + KeyEventCbInfo cbInfo; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + + uint64_t cbId1 = 15; + keyEventRetHandler.HandleKeyEventResult(cbId1, true); + EXPECT_EQ(keyEventRetHandler.keyEventCbHandlers_.size(), 1); + + keyEventRetHandler.HandleKeyEventResult(cbId, true); + EXPECT_TRUE(keyEventRetHandler.keyEventCbHandlers_.empty()); + + auto cb = [](std::shared_ptr &keyEvent, bool isConsumed) {}; + cbInfo.callback = cb; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + keyEventRetHandler.HandleKeyEventResult(cbId, true); + EXPECT_TRUE(keyEventRetHandler.keyEventCbHandlers_.empty()); +} + +/** + * @tc.name: TestClearKeyEventCbInfo + * @tc.desc: Test ClearKeyEventCbInfo + * @tc.type: FUNC + */ +HWTEST_F(InputMethodControllerTest, TestClearKeyEventCbInfo, TestSize.Level0) +{ + IMSA_HILOGI("TestClearKeyEventCbInfo START"); + KeyEventResultHandler keyEventRetHandler; + keyEventRetHandler.keyEventCbHandlers_.clear(); + uint64_t cbId = 13; + KeyEventCbInfo cbInfo; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId, cbInfo); + uint64_t cbId1 = 15; + auto cb = [](std::shared_ptr &keyEvent, bool isConsumed) {}; + cbInfo.callback = cb; + keyEventRetHandler.keyEventCbHandlers_.insert_or_assign(cbId1, cbInfo); + keyEventRetHandler.ClearKeyEventCbInfo(); + EXPECT_TRUE(keyEventRetHandler.keyEventCbHandlers_.empty()); +} } // namespace MiscServices } // namespace OHOS diff --git a/test/unittest/cpp_test/src/input_method_editor_test.cpp b/test/unittest/cpp_test/src/input_method_editor_test.cpp index ac118722ccabbb8cac8acedab95961b5daabfb10..a7362ab4dc1845859a83ee2af769d27783babb71 100644 --- a/test/unittest/cpp_test/src/input_method_editor_test.cpp +++ b/test/unittest/cpp_test/src/input_method_editor_test.cpp @@ -58,7 +58,8 @@ public: static int32_t keyCode_; static int32_t keyStatus_; static CursorInfo cursorInfo_; - bool OnDealKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) override; + bool OnDealKeyEvent(const std::shared_ptr &keyEvent, uint64_t cbId, + const sptr &channelObject) override; bool OnKeyEvent(int32_t keyCode, int32_t keyStatus, sptr &consumer) override; bool OnKeyEvent(const std::shared_ptr &keyEvent, sptr &consumer) override; void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override; @@ -82,13 +83,12 @@ bool KeyboardListenerImpl::OnKeyEvent( return true; } bool KeyboardListenerImpl::OnDealKeyEvent( - const std::shared_ptr &keyEvent, sptr &consumer) + const std::shared_ptr &keyEvent, uint64_t cbId, const sptr &channelObject) { + sptr consumer = new (std::nothrow) KeyEventConsumerProxy(nullptr); bool isKeyCodeConsume = OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer); bool isKeyEventConsume = OnKeyEvent(keyEvent, consumer); - if (consumer != nullptr) { - consumer->OnKeyEventResult(isKeyEventConsume | isKeyCodeConsume); - } + InputMethodAbility::GetInstance().HandleKeyEventResult(cbId, isKeyEventConsume | isKeyCodeConsume, channelObject); return true; } void KeyboardListenerImpl::OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height)