diff --git a/frameworks/js/napi/inputmethodability/BUILD.gn b/frameworks/js/napi/inputmethodability/BUILD.gn index 327373c54c11e33a1b141d50050eef98ac856952..21e7ea5096976ac5a0e06f50f90d502d1d0acd54 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 2fca254af033d8dff8c2115f2ea89e3374c9a89e..8c63fb061a0fc00a1d12bab206e1002bdfb8a9b9 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 80393213c3a64aee5d8f57ac33578ca52cb4c0b9..8edbce2903b6d22580891da0b823df53fc895a80 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 ba57b80a1113e580c3a72f2dec8b8b4b9529bb1a..88f7ca0393e56b02bd97a1a240bfd651e02344f5 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 11c7516c95031633b2f16f86589fccb689dc0c7b..298296e40db4afa55350849f971f64d2ccb247ba 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 900126b4203849372686acd2b6b2dff1d4ff3322..dda07ef7a592d3582bd75ba32ffd801c35e55891 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 6cab1e19f1618f29a97f9a1f0e50defaa778aea9..89407d87a9688f149c4216d2613c730877cb190b 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 3d3ada81bbb17147f4ce7c02c6aa67929ba01b12..2a51704124cb0f5c9d13ab0f65e1957fdde20c08 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 30d03f5f0697708323c860c398da74204cd476c3..c7a95ed1ad9432c39ef07057cd7c6c2584391e85 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 14f2547da01eeec484c108e9994cd83fee6cce76..82e11979369e49f64fde049d754f9afebb5f05a1 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 d031102bce30dee71d434aa841059b327f91c925..872971f1e2800eb8fdce645bca0026bd667ad4ea 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 5bcbe10c468097e7c61771582a3c15f75b1531bc..88c7202b4913da6e7acbf0212d42697eced6f00a 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;