From dd34b82e2cf3c10774120ad6f6264fd8920576f8 Mon Sep 17 00:00:00 2001 From: huangzhuozhen Date: Sat, 12 Apr 2025 18:21:46 +0800 Subject: [PATCH] add attachOptionsChanged with requestKeyboardReason test Signed-off-by: huangzhuozhen --- .../js/napi/inputmethodability/BUILD.gn | 2 + .../js_text_input_client_engine.cpp | 48 +++++++++++++++++++ .../js_text_input_client_engine.h | 2 + .../inputmethod_ability/IInputMethodCore.idl | 2 +- .../include/input_method_ability.h | 4 +- .../include/input_method_core_service_impl.h | 2 +- .../include/tasks/task_imsa.h | 6 +-- .../src/input_method_ability.cpp | 17 ++++--- .../src/input_method_core_service_impl.cpp | 4 +- services/src/peruser_session.cpp | 8 +++- .../input_method_ability_exception_test.cpp | 8 ++-- .../src/input_method_ability_test.cpp | 6 +-- 12 files changed, 84 insertions(+), 25 deletions(-) diff --git a/frameworks/js/napi/inputmethodability/BUILD.gn b/frameworks/js/napi/inputmethodability/BUILD.gn index 327373c54..21e7ea509 100644 --- a/frameworks/js/napi/inputmethodability/BUILD.gn +++ b/frameworks/js/napi/inputmethodability/BUILD.gn @@ -94,6 +94,8 @@ ohos_shared_library("inputmethodengine") { "ipc:ipc_single", "napi:ace_napi", "window_manager:libwm_lite", + "resource_management:global_resmgr", + "ability_runtime:app_context", ] public_configs = [ ":inputmethodengine_native_public_config" ] diff --git a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp index 2fca254af..8c63fb061 100644 --- a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp +++ b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp @@ -25,6 +25,8 @@ #include "napi/native_node_api.h" #include "string_ex.h" #include "wm_common.h" +#include "res_config.h" +#include "resource_manager.h" namespace OHOS { namespace MiscServices { @@ -32,6 +34,7 @@ namespace MiscServices { using namespace std::chrono; thread_local napi_ref JsTextInputClientEngine::TICRef_ = nullptr; const std::string JsTextInputClientEngine::TIC_CLASS_NAME = "TextInputClient"; +constexpr int32_t DEVICE_TYPE_2IN1 = 7; constexpr int32_t MAX_WAIT_TIME = 5000; constexpr int32_t MAX_WAIT_TIME_PRIVATE_COMMAND = 2000; constexpr int32_t MAX_WAIT_TIME_MESSAGE_HANDLER = 2000; @@ -45,6 +48,7 @@ std::shared_ptr JsTextInputClientEngine::textInputClien std::mutex JsTextInputClientEngine::eventHandlerMutex_; std::shared_ptr JsTextInputClientEngine::handler_{ nullptr }; uint32_t JsTextInputClientEngine::traceId_{ 0 }; +int32_t JsTextInputClientEngine::deviceTypeCache_{ -1 }; napi_value JsTextInputClientEngine::Init(napi_env env, napi_value info) { IMSA_HILOGD("JsTextInputClientEngine init"); @@ -87,6 +91,34 @@ napi_value JsTextInputClientEngine::Init(napi_env env, napi_value info) return info; } +bool JsTextInputClientEngine::IsTargetDeviceType(int32_t resDeviceType) +{ + if (deviceTypeCache_ != -1) { + if (deviceTypeCache_ == resDeviceType) { + return true; + } + return false; + } + std::shared_ptr context = + AbilityRuntime::ApplicationContext::GetApplicationContext(); + if (context == nullptr) { + return false; + } + auto resourceManager = context->GetResourceManager(); + auto resConfig = std::unique_ptr(Global::Resource::CreateResConfig()); + if (resourceManager == nullptr || resConfig == nullptr) { + return false; + } + resourceManager->GetResConfig(*resConfig); + + Global::Resource::DeviceType deviceType = resConfig->GetDeviceType(); + deviceTypeCache_ = static_cast(deviceType); + if (static_cast(deviceType) == resDeviceType) { + return true; + } + return false; +} + napi_value JsTextInputClientEngine::MoveCursor(napi_env env, napi_callback_info info) { auto ctxt = std::make_shared(); @@ -1179,6 +1211,7 @@ napi_value JsTextInputClientEngine::RecvMessage(napi_env env, napi_callback_info void JsTextInputClientEngine::OnAttachOptionsChanged(const AttachOptions &attachOptions) { + IMSA_HILOGD("OnAttachOptionsChanged requestKeyboardReason:%{public}d.", attachOptions.requestKeyboardReason); std::string type = "attachOptionsDidChange"; auto entry = GetEntry(type, [&attachOptions](UvEntry &entry) { entry.attachOptions.requestKeyboardReason = attachOptions.requestKeyboardReason; @@ -1209,6 +1242,13 @@ void JsTextInputClientEngine::OnAttachOptionsChanged(const AttachOptions &attach napi_value JsTextInputClientEngine::GetAttachOptions(napi_env env, napi_callback_info info) { + IMSA_HILOGD("GetAttachOptions requestKeyboardReason:%{public}d.", + InputMethodAbility::GetInstance()->GetRequestKeyboardReason()); + bool flag = IsTargetDeviceType(DEVICE_TYPE_2IN1); + if (!flag) { + JsUtils::ThrowException( + env, JsUtils::Convert(IMFErrorCode::EXCEPTION_UNSUPPORTED), "only 2in1 supported!", TYPE_NONE); + } AttachOptions attachOptions; attachOptions.requestKeyboardReason = InputMethodAbility::GetInstance()->GetRequestKeyboardReason(); return JsAttachOptions::Write(env, attachOptions); @@ -1229,6 +1269,10 @@ napi_value JsTextInputClientEngine::Subscribe(napi_env env, napi_callback_info i IMSA_HILOGE("subscribe failed, type: %{public}s.", type.c_str()); return nullptr; } + if (type == "attachOptionsDidChange" && !IsTargetDeviceType(DEVICE_TYPE_2IN1)) { + JsUtils::ThrowException( + env, JsUtils::Convert(IMFErrorCode::EXCEPTION_UNSUPPORTED), "only 2in1 supported!", TYPE_NONE); + } IMSA_HILOGD("subscribe type:%{public}s.", type.c_str()); auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); if (engine == nullptr) { @@ -1258,6 +1302,10 @@ napi_value JsTextInputClientEngine::UnSubscribe(napi_env env, napi_callback_info IMSA_HILOGE("unsubscribe failed, type: %{public}s!", type.c_str()); return nullptr; } + if (type == "attachOptionsDidChange" && !IsTargetDeviceType(DEVICE_TYPE_2IN1)) { + JsUtils::ThrowException( + env, JsUtils::Convert(IMFErrorCode::EXCEPTION_UNSUPPORTED), "only 2in1 supported!", TYPE_NONE); + } // if the second param is not napi_function/napi_null/napi_undefined, return auto paramType = JsUtil::GetType(env, argv[1]); if (paramType != napi_function && paramType != napi_null && paramType != napi_undefined) { diff --git a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.h b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.h index 80393213c..8edbce290 100644 --- a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.h +++ b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.h @@ -436,6 +436,7 @@ private: static napi_value HandleParamCheckFailure(napi_env env); static napi_status GetPreviewTextParam(napi_env env, size_t argc, napi_value *argv, std::string &text, Range &range); + static bool IsTargetDeviceType(int32_t resDeviceType); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); @@ -470,6 +471,7 @@ private: static std::shared_ptr textInputClientEngine_; static std::mutex eventHandlerMutex_; static std::shared_ptr handler_; + static int32_t deviceTypeCache_; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_ability/IInputMethodCore.idl b/frameworks/native/inputmethod_ability/IInputMethodCore.idl index ba57b80a1..88f7ca039 100644 --- a/frameworks/native/inputmethod_ability/IInputMethodCore.idl +++ b/frameworks/native/inputmethod_ability/IInputMethodCore.idl @@ -22,7 +22,7 @@ interface OHOS.MiscServices.IInputControlChannel; interface OHOS.MiscServices.IInputMethodCore { void StartInput([in] InputClientInfoInner clientInfoInner, [in] boolean isBindFromClient); void StopInput([in] IRemoteObject channel, [in] unsigned int sessionId); - void ShowKeyboard(); + void ShowKeyboard([in] int requestKeyboardReason); void HideKeyboard(); void InitInputControlChannel([in] IInputControlChannel inputControlChannel); void StopInputService([in] boolean isTerminateIme); diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index 11c7516c9..298296e40 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -112,7 +112,7 @@ public: /* called from TaskManager worker thread */ int32_t StartInput(const InputClientInfo &clientInfo, bool isBindFromClient); int32_t StopInput(sptr channelObj, uint32_t sessionId); - int32_t ShowKeyboard(); + int32_t ShowKeyboard(int32_t requestKeyboardReason); int32_t HideKeyboard(); void OnInitInputControlChannel(sptr channelObj); @@ -159,7 +159,7 @@ private: void Initialize(); int32_t InvokeStartInputCallback(bool isNotifyInputStart); int32_t InvokeStartInputCallback(const TextTotalConfig &textConfig, bool isNotifyInputStart); - bool IsInputClientAttachOptionsChanged(const TextTotalConfig &textConfig); + bool IsInputClientAttachOptionsChanged(RequestKeyboardReason requestKeyboardReason); int32_t HideKeyboard(Trigger trigger, uint32_t sessionId); std::shared_ptr GetSoftKeyboardPanel(); /* param flag: ShowPanel is async, show/hide softkeyboard in alphabet keyboard attached, diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h b/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h index 900126b42..dda07ef7a 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h @@ -34,7 +34,7 @@ public: ~InputMethodCoreServiceImpl(); ErrCode StartInput(const InputClientInfoInner &clientInfoInner, bool isBindFromClient) override; ErrCode StopInput(const sptr &channel, uint32_t sessionId) override; - ErrCode ShowKeyboard() override; + ErrCode ShowKeyboard(int32_t requestKeyboardReason) override; ErrCode HideKeyboard() override; ErrCode InitInputControlChannel(const sptr &inputControlChannel) override; ErrCode StopInputService(bool isTerminateIme) override; diff --git a/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h b/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h index 6cab1e19f..89407d87a 100644 --- a/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h +++ b/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h @@ -53,10 +53,10 @@ public: class TaskImsaShowKeyboard : public Task { public: - TaskImsaShowKeyboard() : Task(TASK_TYPE_IMSA_SHOW_KEYBOARD) + TaskImsaShowKeyboard(int32_t requestKeyboardReason = 0) : Task(TASK_TYPE_IMSA_SHOW_KEYBOARD) { - auto func = []() { - InputMethodAbility::GetInstance()->ShowKeyboard(); + auto func = [requestKeyboardReason]() { + InputMethodAbility::GetInstance()->ShowKeyboard(requestKeyboardReason); }; actions_.emplace_back(std::make_unique(func)); } diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 3d3ada81b..2a5170412 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -463,10 +463,11 @@ int32_t InputMethodAbility::HideKeyboardImplWithoutLock(int32_t cmdId, uint32_t return HideKeyboard(Trigger::IMF, sessionId); } -int32_t InputMethodAbility::ShowKeyboard() +int32_t InputMethodAbility::ShowKeyboard(int32_t requestKeyboardReason) { std::lock_guard lock(keyboardCmdLock_); int32_t cmdCount = ++cmdId_; + IsInputClientAttachOptionsChanged(static_cast(requestKeyboardReason)); return ShowKeyboardImplWithoutLock(cmdCount); } @@ -560,7 +561,7 @@ int32_t InputMethodAbility::InvokeStartInputCallback(const TextTotalConfig &text if (kdListener_ != nullptr) { kdListener_->OnEditorAttributeChange(textConfig.inputAttribute); } - IsInputClientAttachOptionsChanged(textConfig); + IsInputClientAttachOptionsChanged(textConfig.requestKeyboardReason); if (isNotifyInputStart) { imeListener_->OnInputStart(); } @@ -588,15 +589,16 @@ int32_t InputMethodAbility::InvokeStartInputCallback(const TextTotalConfig &text return ErrorCode::NO_ERROR; } -bool InputMethodAbility::IsInputClientAttachOptionsChanged(const TextTotalConfig &textConfig) +bool InputMethodAbility::IsInputClientAttachOptionsChanged(RequestKeyboardReason requestKeyboardReason) { - if (textInputClientListener_ != nullptr) { - RequestKeyboardReason requestKeyboardReason = textConfig.requestKeyboardReason; - if (requestKeyboardReason != GetRequestKeyboardReason()) { + IMSA_HILOGD("AttachOptionsChanged newReason:%{public}d, oldReason:%{public}d", requestKeyboardReason, + GetRequestKeyboardReason()); + if (requestKeyboardReason != GetRequestKeyboardReason()) { + SetRequestKeyboardReason(requestKeyboardReason); + if (textInputClientListener_ != nullptr) { AttachOptions attachOptions; attachOptions.requestKeyboardReason = requestKeyboardReason; textInputClientListener_->OnAttachOptionsChanged(attachOptions); - SetRequestKeyboardReason(requestKeyboardReason); return true; } } @@ -1347,6 +1349,7 @@ void InputMethodAbility::OnClientInactive(const sptr &channel) return false; }); ClearDataChannel(channel); + ClearRequestKeyboardReason(); } void InputMethodAbility::NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag) diff --git a/frameworks/native/inputmethod_ability/src/input_method_core_service_impl.cpp b/frameworks/native/inputmethod_ability/src/input_method_core_service_impl.cpp index 30d03f5f0..c7a95ed1a 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_core_service_impl.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_core_service_impl.cpp @@ -42,9 +42,9 @@ ErrCode InputMethodCoreServiceImpl::InitInputControlChannel(const sptr(); + auto task = std::make_shared(requestKeyboardReason); TaskManager::GetInstance().PostTask(task); return ERR_OK; } diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 14f2547da..82e119793 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -137,7 +137,9 @@ int32_t PerUserSession::ShowKeyboard(const sptr ¤tClient, IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType); return ErrorCode::ERROR_IME_NOT_STARTED; } - auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); }); + auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data, requestKeyboardReason] { + return data->core->ShowKeyboard(requestKeyboardReason); + }); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret); return ErrorCode::ERROR_KBD_SHOW_FAILED; @@ -350,7 +352,9 @@ int32_t PerUserSession::OnRequestShowInput(uint64_t displayId) IMSA_HILOGE("ime: %{public}d doesn't exist!", type); return ErrorCode::ERROR_IME_NOT_STARTED; } - auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); }); + auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { + return data->core->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); + }); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret); return ErrorCode::ERROR_KBD_SHOW_FAILED; 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 d031102bc..872971f1e 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 @@ -248,7 +248,7 @@ HWTEST_F(InputMethodAbilityExceptionTest, testShowKeyboard_001, TestSize.Level1) { IMSA_HILOGI("InputMethodAbilityExceptionTest testShowKeyboard_001 START"); // channelObject == nullptr - auto ret = inputMethodAbility_->ShowKeyboard(); + auto ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::ERROR_IME); ResetMemberVar(); @@ -265,7 +265,7 @@ HWTEST_F(InputMethodAbilityExceptionTest, testShowKeyboard_002, TestSize.Level1) { IMSA_HILOGI("InputMethodAbilityExceptionTest testShowKeyboard_002 START"); // imeListener_ == nullptr - auto ret = inputMethodAbility_->ShowKeyboard(); + auto ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::ERROR_IME); auto imeListener = std::make_shared(); @@ -277,11 +277,11 @@ HWTEST_F(InputMethodAbilityExceptionTest, testShowKeyboard_002, TestSize.Level1) panel->panelFlag_ = FLG_CANDIDATE_COLUMN; panel->windowId_ = 2; inputMethodAbility_->panels_.Insert(SOFT_KEYBOARD, panel); - ret = inputMethodAbility_->ShowKeyboard(); + ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); // panel not exist inputMethodAbility_->panels_.Clear(); - ret = inputMethodAbility_->ShowKeyboard(); + ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ResetMemberVar(); diff --git a/test/unittest/cpp_test/src/input_method_ability_test.cpp b/test/unittest/cpp_test/src/input_method_ability_test.cpp index 5bcbe10c4..88c7202b4 100644 --- a/test/unittest/cpp_test/src/input_method_ability_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_test.cpp @@ -326,7 +326,7 @@ HWTEST_F(InputMethodAbilityTest, testShowKeyboardInputMethodCoreProxy, TestSize. sptr coreProxy = new InputMethodCoreProxy(coreObject); sptr channelProxy = new InputDataChannelProxy(channelObject); - auto ret = coreProxy->ShowKeyboard(); + auto ret = coreProxy->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ret = coreProxy->InitInputControlChannel(nullptr); @@ -345,7 +345,7 @@ HWTEST_F(InputMethodAbilityTest, testShowKeyboardInputMethodCoreProxy, TestSize. HWTEST_F(InputMethodAbilityTest, testShowKeyboardWithoutImeListener, TestSize.Level0) { IMSA_HILOGI("InputMethodAbilityTest testShowKeyboardWithoutImeListener start."); - auto ret = inputMethodAbility_->ShowKeyboard(); + auto ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } @@ -937,7 +937,7 @@ HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_001, TestSize.Level0) EXPECT_EQ(ret, ErrorCode::NO_ERROR); TextListener::ResetParam(); - ret = inputMethodAbility_->ShowKeyboard(); + ret = inputMethodAbility_->ShowKeyboard(static_cast(RequestKeyboardReason::NONE)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW)); PanelStatusInfo statusInfo; -- Gitee