diff --git a/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.cpp b/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.cpp index adcc9094ae1c433d87a599376e123f7cbed98a93..1ed03f4c0c9e21be84eaee72b0eaa2fcdb3977b0 100644 --- a/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.cpp +++ b/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.cpp @@ -456,36 +456,68 @@ napi_value JsGetInputMethodController::HandleSoftKeyboard( return asyncCall.Call(env, exec, "handleSoftKeyboard"); } -napi_status JsGetInputMethodController::ParseAttachInput( - napi_env env, size_t argc, napi_value *argv, const std::shared_ptr &ctxt) +bool JsGetInputMethodController::GetValue(napi_env env, napi_value in, SelectionRange &out) { - // 0 means the first parameter: showkeyboard - napi_status status = JsUtils::GetValue(env, argv[0], ctxt->showKeyboard); - if (status != napi_ok) { - return status; - } + auto ret = JsUtil::Object::ReadProperty(env, in, "start", out.start); + return ret && JsUtil::Object::ReadProperty(env, in, "end", out.end); +} - // 1 means the second parameter: textConfig +/** + * let textConfig: TextConfig = { + * inputAttribute: InputAttribute = { + * textInputType: TextInputType = TextInputType.TEXT, + * enterKeyType: EnterKeyType = EnterKeyType.NONE + * }, + * cursorInfo?: CursorInfo = { + * left: number, + * top: number, + * width: number, + * height: number, + * }, + * selection?: Range = { + * start: number, + * end: number + * }, + * windowId?: number + * } + */ +bool JsGetInputMethodController::GetValue(napi_env env, napi_value in, TextConfig &out) +{ napi_value attributeResult = nullptr; - status = JsUtils::GetValue(env, argv[1], "inputAttribute", attributeResult); - if (status != napi_ok) { - return status; - } - napi_value textResult = nullptr; - status = JsUtils::GetValue(env, attributeResult, "textInputType", textResult); - if (status != napi_ok) { - return status; - } - status = JsUtils::GetValue(env, textResult, ctxt->attribute.inputPattern); - if (status != napi_ok) { - return status; + napi_status status = JsUtils::GetValue(env, in, "inputAttribute", attributeResult); + CHECK_RETURN(status == napi_ok, "get inputAttribute", false); + bool ret = JsGetInputMethodController::GetValue(env, attributeResult, out.inputAttribute); + CHECK_RETURN(ret, "get inputAttribute of TextConfig", ret); + + napi_value cursorInfoResult = nullptr; + status = JsUtils::GetValue(env, in, "cursorInfo", cursorInfoResult); + bool result = false; + if (status == napi_ok) { + result = JsGetInputMethodController::GetValue(env, cursorInfoResult, out.cursorInfo); + IMSA_HILOGE("get cursorInfo end, ret = %{public}d", result); } - napi_value enterResult = nullptr; - status = JsUtils::GetValue(env, attributeResult, "enterKeyType", enterResult); - if (status != napi_ok) { - return status; + + napi_value rangeResult = nullptr; + status = JsUtils::GetValue(env, in, "selection", rangeResult); + if (status == napi_ok) { + result = JsGetInputMethodController::GetValue(env, rangeResult, out.range); + IMSA_HILOGE("get selectionRange end, ret = %{public}d", result); } - return JsUtils::GetValue(env, enterResult, ctxt->attribute.enterKeyType); + + result = JsUtil::Object::ReadProperty(env, in, "windowId", out.windowId); + IMSA_HILOGE("get windowId end, ret = %{public}d", result); + return ret; +} + +bool JsGetInputMethodController::ParseAttachInput( + napi_env env, size_t argc, napi_value *argv, const std::shared_ptr &ctxt) +{ + // 0 means the first parameter: showkeyboard + bool ret = JsUtil::GetValue(env, argv[0], ctxt->showKeyboard); + IMSA_HILOGE("get showKeyboard end, ret = %{public}d", ret); + + // 1 means the second parameter: textConfig + return ret && JsGetInputMethodController::GetValue(env, argv[1], ctxt->textConfig); } napi_value JsGetInputMethodController::Attach(napi_env env, napi_callback_info info) @@ -493,14 +525,14 @@ napi_value JsGetInputMethodController::Attach(napi_env env, napi_callback_info i auto ctxt = std::make_shared(); auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { PARAM_CHECK_RETURN(env, argc > 1, "should 2 or 3 parameters!", TYPE_NONE, napi_generic_failure); - napi_status status = ParseAttachInput(env, argc, argv, ctxt); - PARAM_CHECK_RETURN(env, status == napi_ok, "paramters of attach is error. ", TYPE_NONE, status); - return status; + bool ret = ParseAttachInput(env, argc, argv, ctxt); + PARAM_CHECK_RETURN(env, ret, "paramters of attach is error. ", TYPE_NONE, napi_generic_failure); + return napi_ok; }; auto exec = [ctxt, env](AsyncCall::Context *ctx) { ctxt->textListener = JsGetInputMethodTextChangedListener::GetInstance(); auto status = - InputMethodController::GetInstance()->Attach(ctxt->textListener, ctxt->showKeyboard, ctxt->attribute); + InputMethodController::GetInstance()->Attach(ctxt->textListener, ctxt->showKeyboard, ctxt->textConfig); ctxt->SetErrorCode(status); CHECK_RETURN_VOID(status == ErrorCode::NO_ERROR, "attach return error!"); ctxt->SetState(napi_ok); diff --git a/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.h b/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.h index 74aae69f0f5ccabcacef137c00874dcdd94686bb..8e4a17f20a3db47fdb4feeb936411c6dd5fa4f79 100644 --- a/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.h +++ b/frameworks/js/napi/inputmethodclient/js_get_input_method_controller.h @@ -48,6 +48,7 @@ struct AttachContext : public AsyncCall::Context { sptr textListener; InputAttribute attribute; bool showKeyboard = false; + TextConfig textConfig; AttachContext() : Context(nullptr, nullptr) {}; AttachContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {}; @@ -193,10 +194,12 @@ private: static napi_value CreateSendFunctionKey(napi_env env, int32_t functionKey); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); - static napi_status ParseAttachInput( + static bool ParseAttachInput( napi_env env, size_t argc, napi_value *argv, const std::shared_ptr &ctxt); static bool GetValue(napi_env env, napi_value in, CursorInfo &out); static bool GetValue(napi_env env, napi_value in, InputAttribute &out); + static bool GetValue(napi_env env, napi_value in, TextConfig &out); + static bool GetValue(napi_env env, napi_value in, SelectionRange &out); static napi_value GetJsKeyboardStatusProperty(napi_env env); static napi_value GetJsEnterKeyTypeProperty(napi_env env); static napi_value GetJsTextInputTypeProperty(napi_env env); diff --git a/frameworks/js/napi/inputmethodclient/js_utils.cpp b/frameworks/js/napi/inputmethodclient/js_utils.cpp index cda7acad8716fdc6f94fd251bc099867685b7203..77b84c97dd5cc75a5c74b7c100ebc3a1f231ed64 100644 --- a/frameworks/js/napi/inputmethodclient/js_utils.cpp +++ b/frameworks/js/napi/inputmethodclient/js_utils.cpp @@ -272,12 +272,6 @@ napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) return status; } -bool JsUtils::GetValue(napi_env env, napi_value in, SelectionRange &out) -{ - auto ret = JsUtil::Object::ReadProperty(env, in, "start", out.start); - return ret && JsUtil::Object::ReadProperty(env, in, "end", out.end); -} - napi_value JsUtils::GetValue(napi_env env, const std::vector &in) { napi_value array = nullptr; diff --git a/frameworks/js/napi/inputmethodclient/js_utils.h b/frameworks/js/napi/inputmethodclient/js_utils.h index a06c33cf4062b093bb39f26abc0998f02f598f15..918cbc53fc1ad6ae3c548381fd6106a4f287b608 100644 --- a/frameworks/js/napi/inputmethodclient/js_utils.h +++ b/frameworks/js/napi/inputmethodclient/js_utils.h @@ -106,7 +106,6 @@ public: static napi_status GetValue(napi_env env, napi_value in, std::string &out); static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); - static bool GetValue(napi_env env, napi_value in, SelectionRange &out); static napi_value GetValue(napi_env env, const std::vector &in); static napi_value GetValue(napi_env env, const InputWindowInfo &in); static napi_value GetValue(napi_env env, const InputAttribute &attribute); diff --git a/frameworks/native/inputmethod_ability/include/i_input_method_core.h b/frameworks/native/inputmethod_ability/include/i_input_method_core.h index 0d6ab905ffbd915e8d88f28fe313cbf0757e08d0..ae3016011a2f483d6f75e7e838d3a0ac5e130bbb 100644 --- a/frameworks/native/inputmethod_ability/include/i_input_method_core.h +++ b/frameworks/native/inputmethod_ability/include/i_input_method_core.h @@ -44,7 +44,8 @@ public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodCore"); - virtual int32_t ShowKeyboard(const sptr &inputDataChannel, bool isShowKeyboard) = 0; + virtual int32_t ShowKeyboard( + const sptr &inputDataChannel, bool isShowKeyboard, bool attachFlag) = 0; virtual bool HideKeyboard(int32_t flags) = 0; virtual int32_t InitInputControlChannel( sptr &inputControlChannel, const std::string &imeId) = 0; diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index 833cdccecddb1d01447f7f357dd8089232c719d9..bf64d9334494101629d66f1db222adb8f5d3419e 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -68,6 +68,7 @@ public: int32_t GetEnterKeyType(int32_t &keyType); int32_t GetInputPattern(int32_t &inputPattern); int32_t GetTextIndexAtCursor(int32_t &index); + int32_t GetTextConfig(TextTotalConfig &textConfig); void OnImeReady(); int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &inputMethodPanel); @@ -122,6 +123,7 @@ private: void OnConfigurationChange(Message *msg); void ShowInputWindow(bool isShowKeyboard); void DismissInputWindow(); + void OnTextConfigChange(const TextTotalConfig &textConfig); bool isImeReady_{ false }; InputStartNotifier notifier_; ConcurrentMap> panels_{}; diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h b/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h index 8d0965a428bace14f7c9bf4b52bfe75b35ccc228..5408ded1867836f715e2431aec8e026a2f04daa8 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_proxy.h @@ -35,7 +35,8 @@ public: DISALLOW_COPY_AND_MOVE(InputMethodCoreProxy); - int32_t ShowKeyboard(const sptr &inputDataChannel, bool isShowKeyboard) override; + int32_t ShowKeyboard( + const sptr &inputDataChannel, bool isShowKeyboard, bool attachFlag) override; bool HideKeyboard(int32_t flags) override; int32_t InitInputControlChannel(sptr &inputControlChannel, const std::string &imeId) override; void StopInputService(std::string imeId) override; diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_stub.h b/frameworks/native/inputmethod_ability/include/input_method_core_stub.h index 6804d3771c220b9e9c53f35a0fcd2a70bae40e2d..85a860c8f7d596016fa81f9d3b6f56e7b73664fa 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_stub.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_stub.h @@ -39,7 +39,8 @@ public: explicit InputMethodCoreStub(int userId); virtual ~InputMethodCoreStub(); int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - int32_t ShowKeyboard(const sptr &inputDataChannel, bool isShowKeyboard) override; + int32_t ShowKeyboard( + const sptr &inputDataChannel, bool isShowKeyboard, bool attachFlag) override; bool HideKeyboard(int32_t flags) override; int32_t InitInputControlChannel(sptr &inputControlChannel, const std::string &imeId) override; void StopInputService(std::string imeId) override; diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index f3e73a61299495d33004cb53ec1a826c21a9cebe..334cc2f3bc4dbfd0223ffc42fa972dae139c5ae3 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -37,6 +37,8 @@ class MessageHandler; using namespace MessageID; sptr InputMethodAbility::instance_; std::mutex InputMethodAbility::instanceLock_; +constexpr double INVALID_CURSOR_VALUE = -1.0; +constexpr int32_t INVALID_SELECTION_VALUE = -1; InputMethodAbility::InputMethodAbility() : stop_(false) { writeInputChannel = nullptr; @@ -149,6 +151,10 @@ void InputMethodAbility::OnImeReady() return; } IMSA_HILOGI("InputMethodAbility::Ime Ready, notify InputStart"); + TextTotalConfig textConfig{}; + int32_t ret = GetTextConfig(textConfig); + IMSA_HILOGI("InputMethodAbility, get text config failed, ret is %{public}d", ret); + OnTextConfigChange(textConfig); ShowInputWindow(notifier_.isShowKeyboard); } @@ -238,15 +244,25 @@ void InputMethodAbility::OnShowKeyboard(Message *msg) MessageParcel *data = msg->msgContent_; sptr channelObject = nullptr; bool isShowKeyboard = false; - if (!ITypesUtil::Unmarshal(*data, channelObject, isShowKeyboard)) { + bool attachFlag = false; + if (!ITypesUtil::Unmarshal(*data, channelObject, isShowKeyboard, attachFlag)) { IMSA_HILOGE("InputMethodAbility::OnShowKeyboard read message parcel failed"); return; } if (channelObject == nullptr) { - IMSA_HILOGI("InputMethodAbility::OnShowKeyboard channelObject is nullptr"); + IMSA_HILOGE("InputMethodAbility::OnShowKeyboard channelObject is nullptr"); return; } SetInputDataChannel(channelObject); + if (attachFlag) { + TextTotalConfig textConfig = {}; + int32_t ret = GetTextConfig(textConfig); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("InputMethodAbility, get text config failed, ret is %{public}d", ret); + return; + } + OnTextConfigChange(textConfig); + } ShowInputWindow(isShowKeyboard); } @@ -396,15 +412,48 @@ void InputMethodAbility::ShowInputWindow(bool isShowKeyboard) } channel->SendKeyboardStatus(KEYBOARD_SHOW); auto result = panels_.Find(SOFT_KEYBOARD); - if (!result.first) { - IMSA_HILOGE("Not find SOFT_KEYBOARD panel."); + if (result.first) { + IMSA_HILOGI("find SOFT_KEYBOARD panel."); + auto ret = result.second->ShowPanel(); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Show panel failed, ret = %{public}d.", ret); + } return; } - auto ret = result.second->ShowPanel(); - if (ret != NO_ERROR) { - IMSA_HILOGE("Show panel failed, ret = %{public}d.", ret); +} + +void InputMethodAbility::OnTextConfigChange(const TextTotalConfig &textConfig) +{ + IMSA_HILOGI("InputMethodAbility run in."); + if (kdListener_ == nullptr) { + IMSA_HILOGE("kdListener_ is nullptr."); + } else { + IMSA_HILOGI("send on('editorAttributeChanged') callback."); + kdListener_->OnEditorAttributeChange(textConfig.inputAttribute); + if (textConfig.cursorInfo.left != INVALID_CURSOR_VALUE) { + IMSA_HILOGI("send on('cursorUpdate') callback."); + kdListener_->OnCursorUpdate( + textConfig.cursorInfo.left, textConfig.cursorInfo.top, textConfig.cursorInfo.height); + } + if (textConfig.textSelection.newBegin != INVALID_SELECTION_VALUE) { + IMSA_HILOGI("send on('selectionChange') callback."); + kdListener_->OnSelectionChange(textConfig.textSelection.oldBegin, textConfig.textSelection.oldEnd, + textConfig.textSelection.newBegin, textConfig.textSelection.newEnd); + } + } + if (textConfig.windowId == INVALID_WINDOW_ID) { return; } + panels_.ForEach([&textConfig](const PanelType &panelType, const std::shared_ptr &panel) { + panel->SetCallingWindow(textConfig.windowId); + return false; + }); + if (imeListener_ == nullptr) { + IMSA_HILOGE("imeListener_ is nullptr, do not need to send callback of setCallingWindow."); + return; + } + imeListener_->OnSetCallingWindow(textConfig.windowId); + IMSA_HILOGD("setCallingWindow end."); } void InputMethodAbility::DismissInputWindow() @@ -585,6 +634,17 @@ int32_t InputMethodAbility::GetTextIndexAtCursor(int32_t &index) return channel->GetTextIndexAtCursor(index); } +int32_t InputMethodAbility::GetTextConfig(TextTotalConfig &textConfig) +{ + IMSA_HILOGD("InputMethodAbility, run in."); + auto channel = GetInputDataChannelProxy(); + if (channel == nullptr) { + IMSA_HILOGE("InputMethodAbility::channel is nullptr"); + return ErrorCode::ERROR_CLIENT_NULL_POINTER; + } + return channel->GetTextConfig(textConfig); +} + void InputMethodAbility::SetInputDataChannel(sptr &object) { IMSA_HILOGD("run in SetInputDataChannel"); diff --git a/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp b/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp index af3ee924b364a0920d02f9345c7e14ace390914a..310e9a9fa7f9a44e6f12e8932b42c2d159bf80e0 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_core_proxy.cpp @@ -39,11 +39,12 @@ int32_t InputMethodCoreProxy::InitInputControlChannel( }); } -int32_t InputMethodCoreProxy::ShowKeyboard(const sptr &inputDataChannel, bool isShowKeyboard) +int32_t InputMethodCoreProxy::ShowKeyboard( + const sptr &inputDataChannel, bool isShowKeyboard, bool attachFlag) { IMSA_HILOGD("InputMethodCoreProxy::showKeyboard"); - return SendRequest(SHOW_KEYBOARD, [&inputDataChannel, &isShowKeyboard](MessageParcel &data) { - return ITypesUtil::Marshal(data, inputDataChannel->AsObject(), isShowKeyboard); + return SendRequest(SHOW_KEYBOARD, [&inputDataChannel, isShowKeyboard, attachFlag](MessageParcel &data) { + return ITypesUtil::Marshal(data, inputDataChannel->AsObject(), isShowKeyboard, attachFlag); }); } diff --git a/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp b/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp index 22c425987cdf211541027faed2c87fbaa9dd74dd..5d9b7791a1363c092824f7006d7f548ddb5317df 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_core_stub.cpp @@ -157,10 +157,11 @@ void InputMethodCoreStub::ShowKeyboardOnRemote(MessageParcel &data, MessageParce IMSA_HILOGD("InputMethodCoreStub::ShowKeyboardOnRemote"); sptr channel; bool isShowKeyboard = false; - int32_t ret = - SendMessage(MessageID::MSG_ID_SHOW_KEYBOARD, [&data, &channel, &isShowKeyboard](MessageParcel &parcel) { - return ITypesUtil::Unmarshal(data, channel, isShowKeyboard) - && ITypesUtil::Marshal(parcel, channel, isShowKeyboard); + bool attachFlag = false; + int32_t ret = SendMessage( + MessageID::MSG_ID_SHOW_KEYBOARD, [&data, &channel, &isShowKeyboard, &attachFlag](MessageParcel &parcel) { + return ITypesUtil::Unmarshal(data, channel, isShowKeyboard, attachFlag) && + ITypesUtil::Marshal(parcel, channel, isShowKeyboard, attachFlag); }); reply.WriteInt32(ret); } @@ -185,7 +186,7 @@ void InputMethodCoreStub::ClearDataChannelOnRemote(MessageParcel &data, MessageP } int32_t InputMethodCoreStub::ShowKeyboard( - const sptr &inputDataChannel, bool isShowKeyboard) + const sptr &inputDataChannel, bool isShowKeyboard, bool attachFlag) { return ErrorCode::NO_ERROR; } diff --git a/frameworks/native/inputmethod_ability/src/input_method_panel.cpp b/frameworks/native/inputmethod_ability/src/input_method_panel.cpp index 07611aeaa49342c0a30ee6096f21c8c2a31ea353..5464690c52106590d1ab8f74e254c054cff9eda5 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_panel.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_panel.cpp @@ -275,6 +275,9 @@ void InputMethodPanel::SetPanelStatusListener( return; } panelStatusListener_ = std::move(statusListener); + if (window_ != nullptr && IsShowing()) { + panelStatusListener_->OnPanelStatus(windowId_, true); + } } void InputMethodPanel::ClearPanelListener(const std::string &type) diff --git a/frameworks/native/inputmethod_controller/include/i_input_data_channel.h b/frameworks/native/inputmethod_controller/include/i_input_data_channel.h index 5aceaf9e6a7b11dfd6a3df6420811ad0e4b97f24..a8981c6327726def1fa3b2a3c1858b216a1cfc9a 100644 --- a/frameworks/native/inputmethod_controller/include/i_input_data_channel.h +++ b/frameworks/native/inputmethod_controller/include/i_input_data_channel.h @@ -44,6 +44,7 @@ public: SELECT_BY_MOVEMENT, HANDLE_EXTEND_ACTION, GET_TEXT_INDEX_AT_CURSOR, + GET_TEXT_CONFIG, }; DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputDataChannel"); @@ -53,6 +54,7 @@ public: virtual int32_t DeleteBackward(int32_t length) = 0; virtual int32_t GetTextBeforeCursor(int32_t number, std::u16string &text) = 0; virtual int32_t GetTextAfterCursor(int32_t number, std::u16string &text) = 0; + virtual int32_t GetTextConfig(TextTotalConfig &textConfig) = 0; virtual void SendKeyboardStatus(int32_t status) = 0; virtual int32_t SendFunctionKey(int32_t funcKey) = 0; virtual int32_t MoveCursor(int32_t keyCode) = 0; diff --git a/frameworks/native/inputmethod_controller/include/input_data_channel_proxy.h b/frameworks/native/inputmethod_controller/include/input_data_channel_proxy.h index f2ef0f7477ef71d26a48dfd4ed208e14c66ced6f..000e5c9668a26ddb744b5bb889a23fbb88429180 100644 --- a/frameworks/native/inputmethod_controller/include/input_data_channel_proxy.h +++ b/frameworks/native/inputmethod_controller/include/input_data_channel_proxy.h @@ -49,6 +49,7 @@ public: int32_t SelectByMovement(int32_t direction, int32_t cursorMoveSkip) override; int32_t HandleExtendAction(int32_t action) override; int32_t GetTextIndexAtCursor(int32_t &index) override; + int32_t GetTextConfig(TextTotalConfig &textConfig) override; private: static inline BrokerDelegator delegator_; diff --git a/frameworks/native/inputmethod_controller/include/input_data_channel_stub.h b/frameworks/native/inputmethod_controller/include/input_data_channel_stub.h index 4049826c17bfc97ecc4576faff56777a0b593853..68a986bed912656c52b0815bd749b99fba94ab32 100644 --- a/frameworks/native/inputmethod_controller/include/input_data_channel_stub.h +++ b/frameworks/native/inputmethod_controller/include/input_data_channel_stub.h @@ -52,6 +52,7 @@ public: int32_t SelectByRange(int32_t start, int32_t end) override; int32_t SelectByMovement(int32_t direction, int32_t cursorMoveSkip) override; int32_t HandleExtendAction(int32_t action) override; + int32_t GetTextConfig(TextTotalConfig &textConfig) override; private: MessageHandler *msgHandler; diff --git a/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h b/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h index 6e457ede503d182380ba56da3afb7b83fccb5cc6..46059839f52878fe52164e7511bfc3fed6c11d47 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h +++ b/frameworks/native/inputmethod_controller/include/input_method_system_ability_proxy.h @@ -45,7 +45,7 @@ public: DISALLOW_COPY_AND_MOVE(InputMethodSystemAbilityProxy); int32_t PrepareInput(InputClientInfo &inputClientInfo) override; - int32_t StartInput(sptr client, bool isShowKeyboard) override; + int32_t StartInput(sptr client, bool isShowKeyboard, bool attachFlag) override; int32_t ShowCurrentInput() override; int32_t HideCurrentInput() override; int32_t StopInputSession() override; diff --git a/frameworks/native/inputmethod_controller/include/input_method_utils.h b/frameworks/native/inputmethod_controller/include/input_method_utils.h index 61b17e189baaac02f4b0303d6a7a312694cf13b7..3f158817e750835ca5f9d9f8c7844b78a8ea97f0 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_utils.h +++ b/frameworks/native/inputmethod_controller/include/input_method_utils.h @@ -22,6 +22,9 @@ namespace OHOS { namespace MiscServices { +constexpr uint32_t INIT_WINDOW_ID = 0; +constexpr uint32_t INVALID_WINDOW_ID = INIT_WINDOW_ID - 1; +constexpr int32_t INVALID_VALUE = -1; enum class EnterKeyType { UNSPECIFIED = 0, NONE, GO, SEARCH, SEND, NEXT, DONE, PREVIOUS }; enum class TextInputType { @@ -79,10 +82,10 @@ private: }; struct CursorInfo { - double left = 0.0; - double top = 0.0; - double width = 0.0; - double height = 0.0; + double left = -1.0; + double top = -1.0; + double width = -1.0; + double height = -1.0; bool operator==(const CursorInfo &info) const { return (left == info.left && top == info.top && width == info.width && height == info.height); @@ -111,15 +114,30 @@ private: }; struct SelectionRange { - int32_t start = -1; - int32_t end = -1; + int32_t start = INVALID_VALUE; + int32_t end = INVALID_VALUE; }; struct TextSelection { - int32_t oldBegin = -1; - int32_t oldEnd = -1; - int32_t newBegin = -1; - int32_t newEnd = -1; + int32_t oldBegin = INVALID_VALUE; + int32_t oldEnd = INVALID_VALUE; + int32_t newBegin = INVALID_VALUE; + int32_t newEnd = INVALID_VALUE; +}; + +class TextTotalConfig { +public: + InputAttribute inputAttribute = {}; + CursorInfo cursorInfo = {}; + TextSelection textSelection = {}; + uint32_t windowId = INVALID_WINDOW_ID; +}; + +struct TextConfig { + InputAttribute inputAttribute = {}; + CursorInfo cursorInfo = {}; + SelectionRange range = {}; + uint32_t windowId = INVALID_WINDOW_ID; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_controller/include/itypes_util.h b/frameworks/native/inputmethod_controller/include/itypes_util.h index 710105ce3347cafb6497ca13a73d680c1edf6c5e..16c0cc4178af1b41ec6ecd7ef1ed0b6f0fb6978c 100644 --- a/frameworks/native/inputmethod_controller/include/itypes_util.h +++ b/frameworks/native/inputmethod_controller/include/itypes_util.h @@ -45,6 +45,9 @@ public: static bool Marshalling(uint64_t input, MessageParcel &data); static bool Unmarshalling(uint64_t &output, MessageParcel &data); + static bool Marshalling(double input, MessageParcel &data); + static bool Unmarshalling(double &output, MessageParcel &data); + static bool Marshalling(const std::u16string &input, MessageParcel &data); static bool Unmarshalling(std::u16string &output, MessageParcel &data); @@ -72,6 +75,9 @@ public: static bool Marshalling(const InputWindowInfo &input, MessageParcel &data); static bool Unmarshalling(InputWindowInfo &output, MessageParcel &data); + static bool Marshalling(const TextTotalConfig &input, MessageParcel &data); + static bool Unmarshalling(TextTotalConfig &output, MessageParcel &data); + static bool Marshalling(EventType input, MessageParcel &data); static bool Unmarshalling(EventType &output, MessageParcel &data); diff --git a/frameworks/native/inputmethod_controller/src/input_data_channel_proxy.cpp b/frameworks/native/inputmethod_controller/src/input_data_channel_proxy.cpp index 858d907683cefeb3a2d929d39fbb0b07f145c327..2b613ba5f278a42804c8e013a2e500280cb8aa32 100644 --- a/frameworks/native/inputmethod_controller/src/input_data_channel_proxy.cpp +++ b/frameworks/native/inputmethod_controller/src/input_data_channel_proxy.cpp @@ -111,6 +111,14 @@ int32_t InputDataChannelProxy::GetTextIndexAtCursor(int32_t &index) [&index](MessageParcel &parcel) { return ITypesUtil::Unmarshal(parcel, index);}); } +int32_t InputDataChannelProxy::GetTextConfig(TextTotalConfig &textConfig) +{ + IMSA_HILOGD("InputDataChannelProxy run in"); + return SendRequest(GET_TEXT_CONFIG, nullptr, [&textConfig](MessageParcel &parcel) { + return ITypesUtil::Unmarshal(parcel, textConfig); + }); +} + int32_t InputDataChannelProxy::SelectByRange(int32_t start, int32_t end) { IMSA_HILOGD("InputDataChannelProxy run in"); diff --git a/frameworks/native/inputmethod_controller/src/input_data_channel_stub.cpp b/frameworks/native/inputmethod_controller/src/input_data_channel_stub.cpp index 3889992b0eac8f71a79e08394c82c882f432ae09..ce3724509755de963a434c61ba25a7c4d40e36f9 100644 --- a/frameworks/native/inputmethod_controller/src/input_data_channel_stub.cpp +++ b/frameworks/native/inputmethod_controller/src/input_data_channel_stub.cpp @@ -103,6 +103,12 @@ int32_t InputDataChannelStub::OnRemoteRequest( SelectByMovementOnRemote(data, reply); break; } + case GET_TEXT_CONFIG: { + TextTotalConfig textConfig = {}; + reply.WriteInt32(GetTextConfig(textConfig)); + ITypesUtil::Marshal(reply, textConfig); + break; + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } @@ -266,6 +272,12 @@ int32_t InputDataChannelStub::GetInputPattern(int32_t &inputPattern) return InputMethodController::GetInstance()->GetInputPattern(inputPattern); } +int32_t InputDataChannelStub::GetTextConfig(TextTotalConfig &textConfig) +{ + IMSA_HILOGI("InputDataChannelStub run in."); + return InputMethodController::GetInstance()->GetTextConfig(textConfig); +} + void InputDataChannelStub::SendKeyboardStatus(int32_t status) { IMSA_HILOGI("InputDataChannelStub::SendKeyboardStatus"); diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index 40ed5705a50753933616940ca826b310ab0eee8e..b167081b0f938586d43ac03e66b99e3ed77e526e 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -375,6 +375,13 @@ void InputMethodController::OnPanelStatusChange( settingListener_->OnPanelStatusChange(status, windowInfo); } +void InputMethodController::SaveTextConfig(const TextConfig &textConfig) +{ + IMSA_HILOGI("InputMethodController in, save text config."); + std::lock_guard lock(textConfigLock_); + textConfig_ = textConfig; +} + int32_t InputMethodController::Attach(sptr &listener) { return Attach(listener, true); @@ -392,19 +399,29 @@ int32_t InputMethodController::Attach( { IMSA_HILOGI("InputMethodController::Attach isShowKeyboard %{public}s", isShowKeyboard ? "true" : "false"); InputmethodTrace tracer("InputMethodController Attach trace."); + TextConfig textConfig; + textConfig.inputAttribute = attribute; + return Attach(listener, isShowKeyboard, textConfig); +} + +int32_t InputMethodController::Attach( + sptr &listener, bool isShowKeyboard, const TextConfig &textConfig) +{ + IMSA_HILOGI("isShowKeyboard %{public}d", isShowKeyboard); + InputmethodTrace tracer("InputMethodController Attach with textConfig trace."); { std::lock_guard lock(textListenerLock_); textListener_ = listener; } clientInfo_.isShowKeyboard = isShowKeyboard; - clientInfo_.attribute = attribute; + SaveTextConfig(textConfig); int32_t ret = PrepareInput(clientInfo_); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to prepare, ret: %{public}d", ret); return ret; } - ret = StartInput(clientInfo_.client, isShowKeyboard); + ret = StartInput(clientInfo_.client, isShowKeyboard, true); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to start input, ret:%{public}d", ret); return ret; @@ -428,7 +445,7 @@ int32_t InputMethodController::ShowTextInput() } clientInfo_.isShowKeyboard = true; InputMethodSysEvent::OperateSoftkeyboardBehaviour(IME_SHOW_ENEDITABLE); - int32_t ret = StartInput(clientInfo_.client, true); + int32_t ret = StartInput(clientInfo_.client, true, false); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to start input, ret: %{public}d", ret); return ret; @@ -588,7 +605,7 @@ std::shared_ptr InputMethodController::GetCurrentInputMethodSubtype return property; } -int32_t InputMethodController::StartInput(sptr &client, bool isShowKeyboard) +int32_t InputMethodController::StartInput(sptr &client, bool isShowKeyboard, bool attachFlag) { IMSA_HILOGI("InputMethodController::StartInput"); auto proxy = GetSystemAbilityProxy(); @@ -596,7 +613,7 @@ int32_t InputMethodController::StartInput(sptr &client, bool isSho IMSA_HILOGE("proxy is nullptr"); return ErrorCode::ERROR_SERVICE_START_FAILED; } - return proxy->StartInput(client, isShowKeyboard); + return proxy->StartInput(client, isShowKeyboard, attachFlag); } int32_t InputMethodController::ReleaseInput(sptr &client) @@ -667,15 +684,17 @@ void InputMethodController::RestoreAttachInfoInSaDied() return; } auto attach = [=]() -> bool { - auto errCode = Attach(textListener_, clientInfo_.isShowKeyboard, clientInfo_.attribute); - if (errCode == ErrorCode::NO_ERROR) { - isDiedAttached_.store(true); - OnCursorUpdate(cursorInfo_); - OnSelectionChange(textString_, selectNewBegin_, selectNewEnd_); - IMSA_HILOGI("attach success."); - return true; + TextConfig tempConfig{}; + { + std::lock_guard lock(textConfigLock_); + tempConfig = textConfig_; + tempConfig.cursorInfo = cursorInfo_; + tempConfig.range.start = selectNewBegin_; + tempConfig.range.end = selectNewEnd_; } - return false; + auto errCode = Attach(textListener_, clientInfo_.isShowKeyboard, tempConfig); + IMSA_HILOGI("attach end, errCode = %{public}d", errCode); + return errCode == ErrorCode::NO_ERROR; }; if (attach()) { return; @@ -752,13 +771,19 @@ int32_t InputMethodController::OnSelectionChange(std::u16string text, int start, int32_t InputMethodController::OnConfigurationChange(Configuration info) { IMSA_HILOGI("InputMethodController::OnConfigurationChange"); - std::lock_guard lock(configurationMutex_); - enterKeyType_ = static_cast(info.GetEnterKeyType()); - inputPattern_ = static_cast(info.GetTextInputType()); + if (!isBound_.load()) { + IMSA_HILOGE("not bound yet"); + return ErrorCode::ERROR_CLIENT_NOT_BOUND; + } + { + std::lock_guard lock(textConfigLock_); + textConfig_.inputAttribute.enterKeyType = static_cast(info.GetEnterKeyType()); + textConfig_.inputAttribute.inputPattern = static_cast(info.GetTextInputType()); + } std::lock_guard agentLock(agentLock_); if (agent_ == nullptr) { IMSA_HILOGE("agent is nullptr"); - return ErrorCode::NO_ERROR; + return ErrorCode::ERROR_SERVICE_START_FAILED; } agent_->OnConfigurationChange(info); return ErrorCode::NO_ERROR; @@ -823,16 +848,39 @@ bool InputMethodController::DispatchKeyEvent(std::shared_ptr keyE int32_t InputMethodController::GetEnterKeyType(int32_t &keyType) { IMSA_HILOGI("InputMethodController::GetEnterKeyType"); - std::lock_guard lock(configurationMutex_); - keyType = enterKeyType_; + std::lock_guard lock(textConfigLock_); + keyType = textConfig_.inputAttribute.enterKeyType; return ErrorCode::NO_ERROR; } int32_t InputMethodController::GetInputPattern(int32_t &inputpattern) { IMSA_HILOGI("InputMethodController::GetInputPattern"); - std::lock_guard lock(configurationMutex_); - inputpattern = inputPattern_; + std::lock_guard lock(textConfigLock_); + inputpattern = textConfig_.inputAttribute.inputPattern; + return ErrorCode::NO_ERROR; +} + +int32_t InputMethodController::GetTextConfig(TextTotalConfig &config) +{ + IMSA_HILOGI("InputMethodController run in."); + std::lock_guard lock(textConfigLock_); + config.inputAttribute = textConfig_.inputAttribute; + config.cursorInfo = textConfig_.cursorInfo; + config.windowId = textConfig_.windowId; + + if (textConfig_.range.start == INVALID_VALUE) { + IMSA_HILOGI("no valid SelectionRange param."); + return ErrorCode::NO_ERROR; + } + { + std::lock_guard editorLock(editorContentLock_); + config.textSelection.oldBegin = selectOldBegin_; + config.textSelection.oldEnd = selectOldEnd_; + } + config.textSelection.newBegin = textConfig_.range.start; + config.textSelection.newEnd = textConfig_.range.end; + return ErrorCode::NO_ERROR; } @@ -977,6 +1025,10 @@ void InputMethodController::ClearEditorCache() selectNewBegin_ = 0; selectNewEnd_ = 0; } + { + std::lock_guard lock(textConfigLock_); + textConfig_ = {}; + } std::lock_guard lock(cursorInfoMutex_); cursorInfo_ = {}; } diff --git a/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp b/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp index 877425ef47c475715168687c648e19e99c5c409d..24557273a7fbf0ffe3fa3ec9812f6624adaa44ad 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp @@ -37,12 +37,13 @@ int32_t InputMethodSystemAbilityProxy::PrepareInput(InputClientInfo &inputClient }); } -int32_t InputMethodSystemAbilityProxy::StartInput(sptr client, bool isShowKeyboard) +int32_t InputMethodSystemAbilityProxy::StartInput(sptr client, bool isShowKeyboard, bool attachFlag) { IMSA_HILOGD("%{public}s in", __func__); - return SendRequest( - static_cast(InputMethodInterfaceCode::START_INPUT), [isShowKeyboard, client](MessageParcel &data) { - return data.WriteRemoteObject(client->AsObject()) && data.WriteBool(isShowKeyboard); + return SendRequest(static_cast(InputMethodInterfaceCode::START_INPUT), + [isShowKeyboard, client, attachFlag](MessageParcel &data) { + return data.WriteRemoteObject(client->AsObject()) && data.WriteBool(isShowKeyboard) && + data.WriteBool(attachFlag); }); } diff --git a/frameworks/native/inputmethod_controller/src/itypes_util.cpp b/frameworks/native/inputmethod_controller/src/itypes_util.cpp index 2fb8e0cb198480f7d4aadf93eb80f6d6badb126d..46238430a14a01a73fc05d9732fcaf1650357b9d 100644 --- a/frameworks/native/inputmethod_controller/src/itypes_util.cpp +++ b/frameworks/native/inputmethod_controller/src/itypes_util.cpp @@ -72,6 +72,16 @@ bool ITypesUtil::Unmarshalling(uint64_t &output, MessageParcel &data) return data.ReadUint64(output); } +bool ITypesUtil::Marshalling(double input, MessageParcel &data) +{ + return data.WriteDouble(input); +} + +bool ITypesUtil::Unmarshalling(double &output, MessageParcel &data) +{ + return data.ReadDouble(output); +} + bool ITypesUtil::Marshalling(const std::string &input, MessageParcel &data) { return data.WriteString(input); @@ -143,7 +153,7 @@ bool ITypesUtil::Marshalling(const SubProperty &input, MessageParcel &data) bool ITypesUtil::Unmarshalling(SubProperty &output, MessageParcel &data) { if (!Unmarshal(data, output.label, output.labelId, output.name, output.id, output.mode, output.locale, - output.language, output.icon, output.iconId)) { + output.language, output.icon, output.iconId)) { IMSA_HILOGE("ITypesUtil::read SubProperty from message parcel failed"); return false; } @@ -168,6 +178,52 @@ bool ITypesUtil::Unmarshalling(InputAttribute &output, MessageParcel &data) return true; } +bool ITypesUtil::Marshalling(const TextTotalConfig &input, MessageParcel &data) +{ + if (!Marshal(data, input.inputAttribute.inputPattern, input.inputAttribute.enterKeyType, + input.inputAttribute.inputOption)) { + IMSA_HILOGE("write InputAttribute to message parcel failed"); + return false; + } + if (!Marshal(data, input.cursorInfo.left, input.cursorInfo.top, input.cursorInfo.height, input.cursorInfo.width)) { + IMSA_HILOGE("write CursorInfo to message parcel failed"); + return false; + } + if (!Marshal(data, input.textSelection.oldBegin, input.textSelection.oldEnd, input.textSelection.newBegin, + input.textSelection.newEnd)) { + IMSA_HILOGE("write TextSelection to message parcel failed"); + return false; + } + if (!Marshal(data, input.windowId)) { + IMSA_HILOGE("write windowId to message parcel failed"); + return false; + } + return true; +} + +bool ITypesUtil::Unmarshalling(TextTotalConfig &output, MessageParcel &data) +{ + if (!Unmarshalling(output.inputAttribute, data)) { + IMSA_HILOGE("read InputAttribute from message parcel failed"); + return false; + } + if (!Unmarshal(data, output.cursorInfo.left, output.cursorInfo.top, + output.cursorInfo.height, output.cursorInfo.width)) { + IMSA_HILOGE("read CursorInfo from message parcel failed"); + return false; + } + if (!Unmarshal(data, output.textSelection.oldBegin, output.textSelection.oldEnd, + output.textSelection.newBegin, output.textSelection.newEnd)) { + IMSA_HILOGE("read TextSelection from message parcel failed"); + return false; + } + if (!Unmarshal(data, output.windowId)) { + IMSA_HILOGE("read windowId from message parcel failed"); + return false; + } + return true; +} + bool ITypesUtil::Marshalling(const InputClientInfo &input, MessageParcel &data) { if (!Marshal(data, input.pid, input.uid, input.userID, input.displayID, input.attribute, input.isShowKeyboard, 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 fcd11b831591267e28fa52fe1bcc0962e38a449a..fb0727d40cfc0c6c6ccf8573be19abe2e411b012 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -109,6 +109,21 @@ public: */ IMF_API int32_t Attach(sptr &listener, bool isShowKeyboard, const InputAttribute &attribute); + /** + * @brief Set listener and bind IMSA with given states and textConfig. + * + * This function is used to set listener and bind IMSA. + * Show soft keyboard when state is true, and customized attribute. + * + * @param listener Indicates the listener in order to manipulate text. + * @param isShowKeyboard Indicates the state, if you want to show soft keyboard, please pass in true. + * @param textConfig Indicates the textConfig, such as input attribute, cursorInfo, range of text selection, + * windowId. + * @return Returns 0 for success, others for failure. + * @since 10 + */ + IMF_API int32_t Attach(sptr &listener, bool isShowKeyboard, const TextConfig &textConfig); + /** * @brief Show soft keyboard. * @@ -266,6 +281,17 @@ public: */ IMF_API int32_t GetInputPattern(int32_t &inputPattern); + /** + * @brief Get text config. + * + * This function is used to get text config of current client. + * + * @param textConfig Indicates the text config of current client that will be obtained. + * @return Returns 0 for success, others for failure. + * @since 10 + */ + IMF_API int32_t GetTextConfig(TextTotalConfig &config); + /** * @brief Get current input method property. * @@ -410,7 +436,7 @@ private: bool Initialize(); sptr GetSystemAbilityProxy(); int32_t PrepareInput(InputClientInfo &inputClientInfo); - int32_t StartInput(sptr &client, bool isShowKeyboard); + int32_t StartInput(sptr &client, bool isShowKeyboard, bool attachFlag); int32_t StopInput(sptr &client); int32_t ReleaseInput(sptr &client); void OnSwitchInput(const Property &property, const SubProperty &subProperty); @@ -427,6 +453,7 @@ private: void RestoreAttachInfoInSaDied(); int32_t RestoreListenEventFlag(); void UpdateNativeEventFlag(EventType eventType, bool isOn); + void SaveTextConfig(const TextConfig &textConfig); void GetText(const Message *msg); void GetTextIndexAtCursor(const Message *msg); @@ -458,9 +485,6 @@ private: std::thread workThreadHandler; MessageHandler *msgHandler_; bool stop_; - std::mutex configurationMutex_; - int32_t enterKeyType_ = 0; - int32_t inputPattern_ = 0; std::atomic_bool isEditable_{ false }; std::atomic_bool isBound_{ false }; @@ -470,6 +494,9 @@ private: static constexpr int CURSOR_DIRECTION_BASE_VALUE = 2011; std::atomic_bool isDiedRestoreListen_{ false }; + + std::mutex textConfigLock_; + TextConfig textConfig_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/i_input_method_system_ability.h b/services/include/i_input_method_system_ability.h index 53fc7863e744e32dec1609ecbbc64689251ee840..e2edd18e948e2e816a0af0098e3fe9e9cdd3f8ba 100644 --- a/services/include/i_input_method_system_ability.h +++ b/services/include/i_input_method_system_ability.h @@ -41,7 +41,7 @@ public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodSystemAbility"); virtual int32_t PrepareInput(InputClientInfo &clientInfo) = 0; - virtual int32_t StartInput(sptr client, bool isShowKeyboard) = 0; + virtual int32_t StartInput(sptr client, bool isShowKeyboard, bool attachFlag) = 0; virtual int32_t ShowCurrentInput() = 0; virtual int32_t HideCurrentInput() = 0; virtual int32_t StopInputSession() = 0; diff --git a/services/include/input_attribute.h b/services/include/input_attribute.h index 3c728fa77f4bf7eded85403c523f0ca6933b6497..d598d750cdea9a5186d7ecb46309d2c9962e98a1 100644 --- a/services/include/input_attribute.h +++ b/services/include/input_attribute.h @@ -43,6 +43,12 @@ struct InputAttribute { { return inputPattern == PATTERN_PASSWORD; } + + bool operator==(const InputAttribute &info) const + { + return inputPattern == info.inputPattern && enterKeyType == info.enterKeyType && + inputOption == info.inputOption; + } }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index f56ea0a01650e88ffd7f587037887c77dc5f2d53..4591a27d4a57090330034e8d3b877e25b57684cb 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -58,7 +58,7 @@ public: ~InputMethodSystemAbility(); int32_t PrepareInput(InputClientInfo &clientInfo) override; - int32_t StartInput(sptr client, bool isShowKeyboard) override; + int32_t StartInput(sptr client, bool isShowKeyboard, bool attachFlag) override; int32_t ShowCurrentInput() override; int32_t HideCurrentInput() override; int32_t StopInput(sptr client) override; diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index 5ffa82e10f1bfb04ae618ed2b5872a1180a42e79..8a6a331b8ee850b4c0496a6d0851dc56ec86db7d 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -75,7 +75,7 @@ public: ~PerUserSession(); int32_t OnPrepareInput(const InputClientInfo &clientInfo); - int32_t OnStartInput(const sptr &client, bool isShowKeyboard); + int32_t OnStartInput(const sptr &client, bool isShowKeyboard, bool attachFlag); int32_t OnStopInput(sptr client); int32_t OnReleaseInput(const sptr &client); int32_t OnSetCoreAndAgent(const sptr &core, const sptr &agent); @@ -122,8 +122,8 @@ private: int AddClient(sptr inputClient, const InputClientInfo &clientInfo, ClientAddEvent event); void UpdateClient(sptr inputClient, bool isShowKeyboard); int32_t RemoveClient(const sptr &client, bool isClientDied); - int32_t ShowKeyboard( - const sptr &channel, const sptr &inputClient, bool isShowKeyboard); + int32_t ShowKeyboard(const sptr &channel, const sptr &inputClient, + bool isShowKeyboard, bool attachFlag); int32_t HideKeyboard(const sptr &inputClient); int32_t ClearDataChannel(const sptr &channel); int32_t SendAgentToSingleClient(const sptr &client); diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 65ea498e9f8d3a407f3198fdd4895c1f58a628bb..822f1e6364b44068bb7b78406d5e218d08d973cc 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -246,7 +246,7 @@ int32_t InputMethodSystemAbility::ReleaseInput(sptr client) return userSession_->OnReleaseInput(client); }; -int32_t InputMethodSystemAbility::StartInput(sptr client, bool isShowKeyboard) +int32_t InputMethodSystemAbility::StartInput(sptr client, bool isShowKeyboard, bool attachFlag) { if (!BundleChecker::IsFocused(IPCSkeleton::GetCallingUid())) { return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; @@ -255,7 +255,7 @@ int32_t InputMethodSystemAbility::StartInput(sptr client, bool isS IMSA_HILOGE("InputMethodSystemAbility::client is nullptr"); return ErrorCode::ERROR_CLIENT_NULL_POINTER; } - return userSession_->OnStartInput(client, isShowKeyboard); + return userSession_->OnStartInput(client, isShowKeyboard, attachFlag); }; int32_t InputMethodSystemAbility::StopInput(sptr client) diff --git a/services/src/input_method_system_ability_stub.cpp b/services/src/input_method_system_ability_stub.cpp index 02066f45722bdec67550433bb8e0e5ebb5420f50..5db90007a2c593ec43aebf91c3512f2c41126388 100644 --- a/services/src/input_method_system_ability_stub.cpp +++ b/services/src/input_method_system_ability_stub.cpp @@ -63,7 +63,8 @@ int32_t InputMethodSystemAbilityStub::StartInputOnRemote(MessageParcel &data, Me return ErrorCode::ERROR_EX_PARCELABLE; } bool isShowKeyboard = data.ReadBool(); - int32_t ret = StartInput(iface_cast(clientObject), isShowKeyboard); + bool attachFlag = data.ReadBool(); + int32_t ret = StartInput(iface_cast(clientObject), isShowKeyboard, attachFlag); return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE; } diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index e1a3716eb9378a2ebf22d0d8937627fba9846c72..ef4debaf8282c91731b5d4ff26e3620594bf1c8f 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -141,8 +141,8 @@ int32_t PerUserSession::RemoveClient(const sptr &client, bool isC * @return ErrorCode::ERROR_KBD_SHOW_FAILED failed to show keyboard * @return other errors returned by binder driver */ -int32_t PerUserSession::ShowKeyboard( - const sptr& channel, const sptr &inputClient, bool isShowKeyboard) +int32_t PerUserSession::ShowKeyboard(const sptr &channel, const sptr &inputClient, + bool isShowKeyboard, bool attachFlag) { IMSA_HILOGD("PerUserSession, run in"); if (inputClient == nullptr) { @@ -153,7 +153,7 @@ int32_t PerUserSession::ShowKeyboard( IMSA_HILOGE("Aborted! imsCore[%{public}d] is nullptr", CURRENT_IME); return ErrorCode::ERROR_IME_NOT_STARTED; } - int32_t ret = core->ShowKeyboard(channel, isShowKeyboard); + int32_t ret = core->ShowKeyboard(channel, isShowKeyboard, attachFlag); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to show keyboard, ret: %{public}d", ret); return ErrorCode::ERROR_KBD_SHOW_FAILED; @@ -268,7 +268,7 @@ int PerUserSession::OnShowKeyboardSelf() IMSA_HILOGE("client info not found"); return ErrorCode::ERROR_CLIENT_NOT_FOUND; } - return ShowKeyboard(clientInfo->channel, client, true); + return ShowKeyboard(clientInfo->channel, client, true, false); } /** Get ClientInfo @@ -337,9 +337,9 @@ int32_t PerUserSession::OnReleaseInput(const sptr& client) * @param the parameters from remote client * @return ErrorCode */ -int32_t PerUserSession::OnStartInput(const sptr &client, bool isShowKeyboard) +int32_t PerUserSession::OnStartInput(const sptr &client, bool isShowKeyboard, bool attachFlag) { - IMSA_HILOGD("start input with keyboard[%{public}d]", isShowKeyboard); + IMSA_HILOGD("start input with keyboard[%{public}d], attchFlag[%{public}d]", isShowKeyboard, attachFlag); if (client == nullptr) { IMSA_HILOGE("client is nullptr"); return ErrorCode::ERROR_CLIENT_NULL_POINTER; @@ -363,7 +363,7 @@ int32_t PerUserSession::OnStartInput(const sptr &client, bool isSh return ret; } // build channel from ima to imc - return ShowKeyboard(clientInfo->channel, client, isShowKeyboard); + return ShowKeyboard(clientInfo->channel, client, isShowKeyboard, attachFlag); } int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, const sptr &agent) @@ -391,7 +391,7 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, co if (client != nullptr) { auto clientInfo = GetClientInfo(client->AsObject()); if (clientInfo != nullptr) { - ret = OnStartInput(clientInfo->client, clientInfo->isShowKeyboard); + ret = OnStartInput(clientInfo->client, clientInfo->isShowKeyboard, true); IMSA_HILOGI("start input ret: %{public}d", ret); } } diff --git a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp index 6fcb73f19c6d7f6641779943027b02eb2389fa19..26448c60cc7437708516a1179158b09bc62f34e1 100644 --- a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp +++ b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp @@ -67,7 +67,7 @@ bool FuzzPerUserSession(const uint8_t *rawData, size_t size) userSessions->OnSwitchIme(property, subProperty, true); userSessions->StopInputService(str); userSessions->OnHideKeyboardSelf(); - userSessions->OnStartInput(client, isShowKeyboard); + userSessions->OnStartInput(client, isShowKeyboard, false); userSessions->OnStopInput(client); userSessions->OnReleaseInput(client); userSessions->OnSetCoreAndAgent(core, agent); diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 8784b10a8a1dc1abf0685a01733e7b0aa3b40fba..b1aa1b59e4f4b26c130304e4442b49845701effb 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -20,6 +20,7 @@ group("unittest") { deps += [ "cpp_test:InputMethodAbilityTest", + "cpp_test:InputMethodAttachTest", "cpp_test:InputMethodControllerTest", "cpp_test:InputMethodDfxTest", "cpp_test:InputMethodEditorTest", diff --git a/test/unittest/cpp_test/BUILD.gn b/test/unittest/cpp_test/BUILD.gn index 4939236d6aeb60e46ce7f9fca5a9265fbed3aec8..ada3f3eac9cc213eb2df841ba203cd06e6eae762 100644 --- a/test/unittest/cpp_test/BUILD.gn +++ b/test/unittest/cpp_test/BUILD.gn @@ -57,6 +57,31 @@ ohos_unittest("InputMethodControllerTest") { ] } +ohos_unittest("InputMethodAttachTest") { + module_out_path = module_output_path + + sources = [ "src/input_method_attach_test.cpp" ] + + configs = [ ":module_private_config" ] + + deps = [ + "${inputmethod_path}/frameworks/native/inputmethod_ability:inputmethod_ability", + "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static", + "${inputmethod_path}/services:inputmethod_service", + "${inputmethod_path}/test/unittest/cpp_test/common:inputmethod_tdd_util", + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "c_utils:utils", + "hilog:libhilog", + "napi:ace_napi", + ] +} ohos_unittest("InputMethodAbilityTest") { module_out_path = module_output_path diff --git a/test/unittest/cpp_test/common/src/tdd_util.cpp b/test/unittest/cpp_test/common/src/tdd_util.cpp index b9ffad970fe591ab6ea9ba531af0733601d0bb54..04486de9506e17318dcad8cf47087af51e33a569 100644 --- a/test/unittest/cpp_test/common/src/tdd_util.cpp +++ b/test/unittest/cpp_test/common/src/tdd_util.cpp @@ -44,7 +44,6 @@ constexpr const uint16_t EACH_LINE_LENGTH = 500; constexpr int32_t BUFF_LENGTH = 10; constexpr const char *CMD_PIDOF_IMS = "pidof inputmethod_ser"; uint64_t TddUtil::selfTokenID_ = 0; -uint64_t TddUtil::testTokenID_ = 0; int64_t TddUtil::selfUid_ = -1; int32_t TddUtil::userID_ = INVALID_USER_ID; int32_t TddUtil::GetCurrentUserId() @@ -71,27 +70,19 @@ uint64_t TddUtil::AllocTestTokenID(bool isSystemApp, bool needPermission, const HapInfoParams infoParams = { .userID = GetCurrentUserId(), .bundleName = bundleName, .instIndex = 0, - .appIDDesc = "ohos.inputmethod_test.demo", - .isSystemApp = true }; + .appIDDesc = bundleName, + .isSystemApp = isSystemApp }; PermissionStateFull permissionState = { .permissionName = "ohos.permission.CONNECT_IME_ABILITY", .isGeneral = true, .resDeviceID = { "local" }, .grantStatus = { PermissionState::PERMISSION_GRANTED }, .grantFlags = { 1 } }; HapPolicyParams policyParams = { .apl = APL_NORMAL, - .domain = "test.domain.inputmethod", + .domain = bundleName, .permList = {}, .permStateList = { permissionState } }; if (!needPermission) { - policyParams = { .apl = APL_NORMAL, .domain = "test.domain.inputmethod", .permList = {}, .permStateList = {} }; - } - if (!isSystemApp) { - infoParams = { - .userID = GetCurrentUserId(), - .bundleName = bundleName, - .instIndex = 0, - .appIDDesc = "ohos.inputmethod_test.demo" - }; + policyParams = { .apl = APL_NORMAL, .domain = bundleName, .permList = {}, .permStateList = {} }; } auto tokenInfo = AccessTokenKit::AllocHapToken(infoParams, policyParams); return tokenInfo.tokenIDEx; @@ -185,7 +176,7 @@ void TddUtil::KillImsaProcess() IMSA_HILOGE("Kill failed, ret: %{public}d", ret); return; } - IMSA_HILOGE("Kill success."); + IMSA_HILOGI("Kill success."); } sptr TddUtil::GetBundleMgr() 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 ac4a2957604f8d0363d00bef83f2614238b8b4dd..bd43436c68d6e84ed104127ee86f7f034b5d958b 100644 --- a/test/unittest/cpp_test/src/input_method_ability_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_test.cpp @@ -173,7 +173,7 @@ HWTEST_F(InputMethodAbilityTest, testShowKeyboardInputMethodCoreProxy, TestSize. sptr coreProxy = new InputMethodCoreProxy(coreObject); sptr channelProxy = new InputDataChannelProxy(channelObject); - auto ret = coreProxy->ShowKeyboard(channelProxy, false); + auto ret = coreProxy->ShowKeyboard(channelProxy, false, false); std::unique_lock lock(InputMethodAbilityTest::imeListenerCallbackLock_); auto cvStatus = InputMethodAbilityTest::imeListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME)); EXPECT_EQ(ret, ErrorCode::NO_ERROR); @@ -350,6 +350,28 @@ HWTEST_F(InputMethodAbilityTest, testGetEnterKeyType, TestSize.Level0) EXPECT_EQ(inputPattern, (int)textInputType); } +/** +* @tc.name: testGetTextConfig +* @tc.desc: InputMethodAbility GetTextConfig +* @tc.type: FUNC +* @tc.require: +* @tc.author: Hollokin +*/ +HWTEST_F(InputMethodAbilityTest, testGetTextConfig, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbility testGetTextConfig START"); + sptr textListener = new TextListener(); + TextConfig textConfig; + textConfig.inputAttribute = { .inputPattern = 0, .enterKeyType = 1 }; + auto ret = imc_->Attach(textListener, false, textConfig); + TextTotalConfig textTotalConfig; + ret = inputMethodAbility_->GetTextConfig(textTotalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(textTotalConfig.inputAttribute.inputPattern, textConfig.inputAttribute.inputPattern); + EXPECT_EQ(textTotalConfig.inputAttribute.enterKeyType, textConfig.inputAttribute.enterKeyType); + textListener = nullptr; +} + /** * @tc.name: testSelectByRange_001 * @tc.desc: InputMethodAbility SelectByRange diff --git a/test/unittest/cpp_test/src/input_method_attach_test.cpp b/test/unittest/cpp_test/src/input_method_attach_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59cd0f3945b84c75f6e37654bdbb2eb35b03772b --- /dev/null +++ b/test/unittest/cpp_test/src/input_method_attach_test.cpp @@ -0,0 +1,628 @@ +/* + * Copyright (C) 2023 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 +#include + +#include "global.h" +#include "input_attribute.h" +#include "input_method_ability.h" +#include "input_method_controller.h" +#include "tdd_util.h" +#include "text_listener.h" + +using namespace testing::ext; +namespace OHOS { +namespace MiscServices { +class InputMethodAttachTest : public testing::Test { +public: + static sptr inputMethodController_; + static sptr inputMethodAbility_; + + class EngineListenerImpl : public InputMethodEngineListener { + public: + EngineListenerImpl() = default; + ~EngineListenerImpl() = default; + + void OnKeyboardStatus(bool isShow) + { + IMSA_HILOGI("EngineListenerImpl OnKeyboardStatus"); + } + + void OnInputStart() + { + IMSA_HILOGI("EngineListenerImpl OnInputStart"); + } + + void OnInputStop(const std::string &imeId) + { + IMSA_HILOGI("EngineListenerImpl OnInputStop"); + } + + void OnSetCallingWindow(uint32_t windowId) + { + IMSA_HILOGI("EngineListenerImpl OnSetCallingWindow"); + } + + void OnSetSubtype(const SubProperty &property) + { + IMSA_HILOGI("EngineListenerImpl OnSetSubtype"); + } + }; + static void SetUpTestCase(void) + { + IMSA_HILOGI("InputMethodAttachTest::SetUpTestCase"); + // Set the tokenID to the tokenID of the current ime + TddUtil::StorageSelfTokenID(); + std::shared_ptr property = InputMethodController::GetInstance()->GetCurrentInputMethod(); + std::string bundleName = property != nullptr ? property->name : "default.inputmethod.unittest"; + TddUtil::SetTestTokenID(TddUtil::GetTestTokenID(bundleName)); + inputMethodAbility_ = InputMethodAbility::GetInstance(); + inputMethodAbility_->OnImeReady(); + inputMethodAbility_->SetCoreAndAgent(); + TddUtil::RestoreSelfTokenID(); + + // Set the uid to the uid of the focus app + TddUtil::StorageSelfUid(); + TddUtil::SetTestUid(); + inputMethodController_ = InputMethodController::GetInstance(); + } + static void TearDownTestCase(void) + { + IMSA_HILOGI("InputMethodAttachTest::TearDownTestCase"); + TddUtil::RestoreSelfUid(); + } + void SetUp() + { + IMSA_HILOGI("InputMethodAttachTest::SetUp"); + } + void TearDown() + { + IMSA_HILOGI("InputMethodAttachTest::TearDown"); + inputMethodController_->Close(); + } +}; +sptr InputMethodAttachTest::inputMethodController_; +sptr InputMethodAttachTest::inputMethodAbility_; + +/** + * @tc.name: testAttach001 + * @tc.desc: test Attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testAttach001, TestSize.Level0) +{ + IMSA_HILOGI("test testAttach001 after attach."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + int32_t keyType = -1; + ret = inputMethodAbility_->GetEnterKeyType(keyType); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType, 0); + int32_t inputPattern = -1; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + auto pattern = InputAttribute::PATTERN_TEXT; + EXPECT_EQ(inputPattern, pattern); +} + +/** + * @tc.name: testAttach002 + * @tc.desc: test Attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testAttach002, TestSize.Level0) +{ + IMSA_HILOGI("test testAttach002 after attach."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener, false); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + int32_t keyType = -1; + ret = inputMethodAbility_->GetEnterKeyType(keyType); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType, 0); + int32_t inputPattern = -1; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + auto pattern = InputAttribute::PATTERN_TEXT; + EXPECT_EQ(inputPattern, pattern); +} + +/** + * @tc.name: testAttach003 + * @tc.desc: test Attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testAttach003, TestSize.Level0) +{ + IMSA_HILOGI("test testAttach003 after attach."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 2; + attribute.enterKeyType = 1; + auto ret = inputMethodController_->Attach(textListener, true, attribute); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + int32_t keyType = -1; + ret = inputMethodAbility_->GetEnterKeyType(keyType); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType, attribute.enterKeyType); + int32_t inputPattern = -1; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(inputPattern, attribute.inputPattern); +} + +/** + * @tc.name: testAttach004 + * @tc.desc: test Attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testAttach004, TestSize.Level0) +{ + IMSA_HILOGI("test testAttach004 after attach."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + auto ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + int32_t keyType = -1; + ret = inputMethodAbility_->GetEnterKeyType(keyType); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType, config.inputAttribute.enterKeyType); + int32_t inputPattern = -1; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern); +} + +/** + * @tc.name: testAttach005 + * @tc.desc: test Attach, test optional param in TextConfig + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testAttach005, TestSize.Level0) +{ + IMSA_HILOGI("test testAttach005 after attach."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + CursorInfo cursorInfo; + cursorInfo.left = 0; + cursorInfo.top = 1; + cursorInfo.width = 0.5; + cursorInfo.height = 1.2; + config.cursorInfo = cursorInfo; + SelectionRange selectionRange; + selectionRange.start = 0; + selectionRange.end = 2; + config.range = selectionRange; + config.windowId = 10; + auto ret = inputMethodController_->Attach(textListener, true, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + int32_t keyType = -1; + ret = inputMethodAbility_->GetEnterKeyType(keyType); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType, config.inputAttribute.enterKeyType); + int32_t inputPattern = -1; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern); + + TextTotalConfig textConfig; + ret = inputMethodAbility_->GetTextConfig(textConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(textConfig.inputAttribute, config.inputAttribute); + EXPECT_EQ(textConfig.windowId, config.windowId); + EXPECT_EQ(textConfig.cursorInfo, config.cursorInfo); + EXPECT_EQ(textConfig.textSelection.newBegin, config.range.start); + EXPECT_EQ(textConfig.textSelection.newEnd, config.range.end); + EXPECT_EQ(textConfig.textSelection.oldBegin, 0); + EXPECT_EQ(textConfig.textSelection.oldEnd, 0); +} + +/** + * @tc.name: testOnConfigurationChangeWithOutAttach + * @tc.desc: test OnConfigurationChange without attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeWithOutAttach, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAttachTest testOnConfigurationChangeWithOutAttach in."); + Configuration config; + EnterKeyType keyType = EnterKeyType::NEXT; + config.SetEnterKeyType(keyType); + TextInputType textInputType = TextInputType::DATETIME; + config.SetTextInputType(textInputType); + auto ret = inputMethodController_->OnConfigurationChange(config); + EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND); +} + +/** + * @tc.name: testOnConfigurationChange + * @tc.desc: test OnConfigurationChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnConfigurationChange, TestSize.Level0) +{ + IMSA_HILOGI("test OnConfigurationChange after attach."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + Configuration config; + EnterKeyType keyType = EnterKeyType::NEXT; + config.SetEnterKeyType(keyType); + TextInputType textInputType = TextInputType::DATETIME; + config.SetTextInputType(textInputType); + ret = inputMethodController_->OnConfigurationChange(config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + int32_t keyType2; + ret = inputMethodAbility_->GetEnterKeyType(keyType2); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(keyType2, (int)keyType); + int32_t inputPattern; + ret = inputMethodAbility_->GetInputPattern(inputPattern); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(inputPattern, (int)textInputType); +} + +/** + * @tc.name: testGetTextConfig + * @tc.desc: test GetTextConfig of InputMethodAbility + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testGetTextConfig, TestSize.Level0) +{ + IMSA_HILOGI("test OnConfigurationChange001 after attach."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + CursorInfo cursorInfo; + cursorInfo.left = 0; + cursorInfo.top = 1; + cursorInfo.width = 0.5; + cursorInfo.height = 1.2; + config.cursorInfo = cursorInfo; + SelectionRange selectionRange; + selectionRange.start = 0; + selectionRange.end = 2; + config.range = selectionRange; + config.windowId = 10; + auto ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + EXPECT_EQ(totalConfig.inputAttribute, attribute); + EXPECT_EQ(totalConfig.cursorInfo, cursorInfo); + EXPECT_EQ(totalConfig.textSelection.newBegin, selectionRange.start); + EXPECT_EQ(totalConfig.textSelection.newEnd, selectionRange.end); + EXPECT_EQ(totalConfig.textSelection.oldBegin, 0); + EXPECT_EQ(totalConfig.textSelection.oldEnd, 0); + EXPECT_EQ(totalConfig.windowId, config.windowId); +} + +/** + * @tc.name: testOnCursorUpdateAfterAttach001 + * @tc.desc: test OnCursorUpdate after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach001, TestSize.Level0) +{ + IMSA_HILOGI("test testOnCursorUpdateAfterAttach001."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; + ret = inputMethodController_->OnCursorUpdate(cursorInfo); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.cursorInfo.height, -1); + EXPECT_EQ(totalConfig.cursorInfo.width, -1); + EXPECT_EQ(totalConfig.cursorInfo.left, -1); + EXPECT_EQ(totalConfig.cursorInfo.top, -1); +} + +/** + * @tc.name: testOnCursorUpdateAfterAttach002 + * @tc.desc: test OnCursorUpdate after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach002, TestSize.Level0) +{ + IMSA_HILOGI("test testOnCursorUpdateAfterAttach002."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + config.cursorInfo = { .top = 1, .left = 1, .height = 1, .width = 0.4 }; + auto ret = inputMethodController_->Attach(textListener, true, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; + ret = inputMethodController_->OnCursorUpdate(cursorInfo); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.cursorInfo, config.cursorInfo); +} + +/** + * @tc.name: testOnSelectionChangeAfterAttach002 + * @tc.desc: test OnSelectionChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnSelectionChangeAfterAttach002, TestSize.Level0) +{ + IMSA_HILOGI("test testOnSelectionChangeAfterAttach002."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + config.range = { .start = 1, .end = 2 }; + auto ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + int start = 0; + int end = 1; + ret = inputMethodController_->OnSelectionChange(Str8ToStr16("aaa"), start, end); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.textSelection.newBegin, config.range.start); + EXPECT_EQ(totalConfig.textSelection.newEnd, config.range.end); + EXPECT_EQ(totalConfig.textSelection.oldBegin, 0); + EXPECT_EQ(totalConfig.textSelection.oldEnd, 0); +} + +/** + * @tc.name: testOnConfigurationChangeAfterAttach001 + * @tc.desc: test OnConfigurationChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach001, TestSize.Level0) +{ + IMSA_HILOGI("test testOnConfigurationChangeAfterAttach001."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + Configuration config; + config.SetTextInputType(TextInputType::DATETIME); + config.SetEnterKeyType(EnterKeyType::NEXT); + ret = inputMethodController_->OnConfigurationChange(config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast(TextInputType::DATETIME)); + EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast(EnterKeyType::NEXT)); +} + +/** + * @tc.name: testOnConfigurationChangeAfterAttach002 + * @tc.desc: test OnConfigurationChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach002, TestSize.Level0) +{ + IMSA_HILOGI("test testOnConfigurationChangeAfterAttach002."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + auto ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + Configuration configuration; + configuration.SetTextInputType(TextInputType::DATETIME); + configuration.SetEnterKeyType(EnterKeyType::NEXT); + ret = inputMethodController_->OnConfigurationChange(configuration); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast(configuration.GetTextInputType())); + EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast(configuration.GetEnterKeyType())); +} + +/** + * @tc.name: testSetCallingWindowAfterAttach002 + * @tc.desc: test SetCallingWindow after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testSetCallingWindowAfterAttach002, TestSize.Level0) +{ + IMSA_HILOGI("test testSetCallingWindowAfterAttach002."); + sptr textListener = new TextListener(); + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + config.windowId = 88; + auto ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + uint32_t windowId = 99; + ret = inputMethodController_->SetCallingWindow(windowId); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.windowId, config.windowId); +} + +/** + * @tc.name: testOnCursorUpdate001 + * @tc.desc: test OnCursorUpdate after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnCursorUpdate001, TestSize.Level0) +{ + IMSA_HILOGI("test testOnCursorUpdate001."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; + ret = inputMethodController_->OnCursorUpdate(cursorInfo); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + CursorInfo cursorInfo2 = { .top = 10, .left = 9, .width = 8, .height = 7 }; + config.cursorInfo = cursorInfo2; + ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.cursorInfo, cursorInfo2); +} + +/** + * @tc.name: testOnSelectionChange + * @tc.desc: test OnSelectionChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnSelectionChange, TestSize.Level0) +{ + IMSA_HILOGI("test testOnSelectionChange."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + int start = 0; + int end = 1; + ret = inputMethodController_->OnSelectionChange(Str8ToStr16("bbb"), start, end); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + config.range.start = 10; + config.range.end = 20; + ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + EXPECT_EQ(totalConfig.textSelection.newBegin, config.range.start); + EXPECT_EQ(totalConfig.textSelection.newEnd, config.range.end); + EXPECT_EQ(totalConfig.textSelection.oldBegin, 0); + EXPECT_EQ(totalConfig.textSelection.oldEnd, 0); +} + +/** + * @tc.name: testOnConfigurationChange002 + * @tc.desc: test OnConfigurationChange after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testOnConfigurationChange002, TestSize.Level0) +{ + IMSA_HILOGI("test testOnConfigurationChange002."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + Configuration configuration; + configuration.SetTextInputType(TextInputType::DATETIME); + configuration.SetEnterKeyType(EnterKeyType::NEXT); + ret = inputMethodController_->OnConfigurationChange(configuration); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.inputAttribute = attribute; + config.inputAttribute.enterKeyType = 5; + config.inputAttribute.inputPattern = 5; + ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + EXPECT_EQ(totalConfig.inputAttribute, config.inputAttribute); +} + +/** + * @tc.name: testSetCallingWindow + * @tc.desc: test SetCallingWindow after attach + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAttachTest, testSetCallingWindow, TestSize.Level0) +{ + IMSA_HILOGI("test testSetCallingWindow."); + sptr textListener = new TextListener(); + auto ret = inputMethodController_->Attach(textListener); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + uint32_t windowId = 88; + ret = inputMethodController_->SetCallingWindow(windowId); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + InputAttribute attribute; + attribute.inputPattern = 3; + attribute.enterKeyType = 2; + TextConfig config; + config.windowId = 77; + ret = inputMethodController_->Attach(textListener, false, config); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + TextTotalConfig totalConfig; + ret = inputMethodAbility_->GetTextConfig(totalConfig); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + EXPECT_EQ(totalConfig.windowId, config.windowId); +} +} // 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 d91c33cefa1d6c5ebac29230757f5a0f4088242c..2a369c7b036045b090bc2152beaa42f695a99075 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -315,7 +315,8 @@ constexpr uint32_t KEY_EVENT_DELAY_TIME = 100; { IMSA_HILOGI("InputMethodControllerTest::WaitRemoteDiedCallback"); std::unique_lock lock(onRemoteSaDiedMutex_); - return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(1)) != std::cv_status::timeout; + // 2 means wait 2 seconds. + return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(2)) != std::cv_status::timeout; } bool InputMethodControllerTest::CheckKeyEvent(std::shared_ptr keyEvent) @@ -715,45 +716,6 @@ constexpr uint32_t KEY_EVENT_DELAY_TIME = 100; && inputPattern <= static_cast(TextInputType::VISIBLE_PASSWORD)); } - /** - * @tc.name: testIMCOnConfigurationChange - * @tc.desc: IMC testOnConfigurationChange. - * @tc.type: FUNC - * @tc.require: - */ - HWTEST_F(InputMethodControllerTest, testIMCOnConfigurationChange, TestSize.Level0) - { - IMSA_HILOGI("IMC OnConfigurationChange Test START"); - Configuration info; - info.SetEnterKeyType(EnterKeyType::GO); - info.SetTextInputType(TextInputType::NUMBER); - int32_t ret = inputMethodController_->Close(); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - ret = inputMethodController_->OnConfigurationChange(info); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - { - std::unique_lock lock(InputMethodControllerTest::keyboardListenerMutex_); - ret = InputMethodControllerTest::keyboardListenerCv_.wait_for( - lock, std::chrono::seconds(DEALY_TIME), [&info] { - return (static_cast( - InputMethodControllerTest::inputAttribute_.inputPattern) == info.GetTextInputType()) && - (static_cast( - InputMethodControllerTest::inputAttribute_.enterKeyType) == info.GetEnterKeyType()); - }); - EXPECT_NE(InputMethodControllerTest::inputAttribute_.inputPattern, - static_cast(info.GetTextInputType())); - EXPECT_NE( - InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast(info.GetEnterKeyType())); - } - - auto keyType = static_cast(EnterKeyType::UNSPECIFIED); - auto inputPattern = static_cast(TextInputType::NONE); - ret = inputMethodController_->GetEnterKeyType(keyType); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - ret = inputMethodController_->GetInputPattern(inputPattern); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - } - /** * @tc.name: testOnEditorAttributeChanged * @tc.desc: IMC testOnEditorAttributeChanged. diff --git a/test/unittest/cpp_test/src/input_method_private_member_test.cpp b/test/unittest/cpp_test/src/input_method_private_member_test.cpp index 0948ca800f1a4c2dc4259c5fc7f086237aa7a867..9f6358044c5e9734ab8ad482108df5da9237e47f 100644 --- a/test/unittest/cpp_test/src/input_method_private_member_test.cpp +++ b/test/unittest/cpp_test/src/input_method_private_member_test.cpp @@ -189,7 +189,7 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionCoreOrAgentNullptr, TestSiz auto userSession = std::make_shared(MAIN_USER_ID); userSession->SetImsCore(CURRENT_IME, nullptr); auto imc = InputMethodController::GetInstance(); - int32_t ret = userSession->ShowKeyboard(imc->clientInfo_.channel, imc->clientInfo_.client, false); + int32_t ret = userSession->ShowKeyboard(imc->clientInfo_.channel, imc->clientInfo_.client, false, false); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); ret = userSession->HideKeyboard(imc->clientInfo_.client); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); @@ -252,11 +252,11 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr001, TestSi { IMSA_HILOGI("InputMethodPrivateMemberTest PerUserSessionParameterNullptr001 TEST START"); auto userSession = std::make_shared(MAIN_USER_ID); - int32_t ret = userSession->OnStartInput(nullptr, true); + int32_t ret = userSession->OnStartInput(nullptr, true, false); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); ret = userSession->OnReleaseInput(nullptr); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); - ret = userSession->ShowKeyboard(nullptr, nullptr, false); + ret = userSession->ShowKeyboard(nullptr, nullptr, false, false); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); ret = userSession->RemoveClient(nullptr, false); EXPECT_EQ(ret, ErrorCode::NO_ERROR);