From 7b971f81123e1ae1972b841ed808a77a2eaa2862 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Wed, 30 Apr 2025 15:52:14 +0800 Subject: [PATCH 1/9] =?UTF-8?q?feat=EF=BC=9AArkts=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=8C=96=E6=BC=94=E8=BF=9B=20IDL=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: weishaoxiong --- bundle.json | 6 +- frameworks/ets/taihe/inputMethod/BUILD.gn | 115 +++++++ .../idl/ohos.inputMethod.Panel.taihe | 16 + .../inputMethod/idl/ohos.inputMethod.taihe | 245 +++++++++++++++ .../idl/ohos.inputMethodSubtype.taihe | 13 + .../taihe/inputMethod/include/ani_common.h | 212 +++++++++++++ .../include/input_method_controller_impl.h | 160 ++++++++++ .../include/input_method_event_listener.h | 42 +++ .../include/input_method_setting_impl.h | 91 ++++++ .../input_method_text_changed_listener.h | 64 ++++ .../taihe/inputMethod/src/ani_constructor.cpp | 38 +++ .../src/input_method_controller_impl.cpp | 292 ++++++++++++++++++ .../src/input_method_event_listener.cpp | 46 +++ .../src/input_method_setting_impl.cpp | 282 +++++++++++++++++ .../input_method_text_changed_listener.cpp | 83 +++++ .../inputMethod/src/ohos.inputMethod.impl.cpp | 115 +++++++ 16 files changed, 1818 insertions(+), 2 deletions(-) create mode 100644 frameworks/ets/taihe/inputMethod/BUILD.gn create mode 100644 frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe create mode 100644 frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe create mode 100644 frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe create mode 100644 frameworks/ets/taihe/inputMethod/include/ani_common.h create mode 100644 frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h create mode 100644 frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h create mode 100644 frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h create mode 100644 frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h create mode 100644 frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp create mode 100644 frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp create mode 100644 frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp create mode 100644 frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp create mode 100644 frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp create mode 100644 frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp diff --git a/bundle.json b/bundle.json index b66b135f9..12baa05e2 100644 --- a/bundle.json +++ b/bundle.json @@ -58,7 +58,8 @@ "hicollie", "resource_management", "screenlock_mgr", - "cJSON" + "cJSON", + "runtime_core" ] }, "build": { @@ -69,7 +70,8 @@ "//base/inputmethod/imf/frameworks/js/napi/inputmethodclient:inputmethod", "//base/inputmethod/imf/frameworks/js/napi/inputmethodlist:inputmethodlist", "//base/inputmethod/imf/frameworks/js/napi/inputmethodpanel:panel", - "//base/inputmethod/imf/frameworks/ndk:ohinputmethod" + "//base/inputmethod/imf/frameworks/ndk:ohinputmethod", + "//base/inputmethod/imf/frameworks/ets/taihe/inputMethod:inputmethod_taihe_native" ], "service_group": [ "//base/inputmethod/imf/etc/init:inputmethodservice.cfg", diff --git a/frameworks/ets/taihe/inputMethod/BUILD.gn b/frameworks/ets/taihe/inputMethod/BUILD.gn new file mode 100644 index 000000000..21e1ff861 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/BUILD.gn @@ -0,0 +1,115 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//base/inputmethod/imf/inputmethod.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") + +subsystem_name = "inputmethod" +part_name = "imf" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_taihe") { + sources = [ + "idl/ohos.inputMethod.Panel.taihe", + "idl/ohos.inputMethod.taihe", + "idl/ohos.inputMethodSubtype.taihe" + ] + + external_deps = [] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.inputMethod.ani.cpp", + "$taihe_generated_file_path/src/ohos.inputMethod.abi.c", + "$taihe_generated_file_path/src/ohos.inputMethod.Panel.ani.cpp", + "$taihe_generated_file_path/src/ohos.inputMethod.Panel.abi.c", + "$taihe_generated_file_path/src/ohos.inputMethodSubtype.ani.cpp", + "$taihe_generated_file_path/src/ohos.inputMethodSubtype.abi.c", + ] +} + +taihe_shared_library("inputmethod_taihe_native") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + include_dirs = [ + "include", + "${inputmethod_path}/frameworks/js/napi/inputmethodability", + "${inputmethod_path}/frameworks/js/napi/inputmethodclient", + ] + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/ohos.inputMethod.impl.cpp", + "src/input_method_controller_impl.cpp", + "src/input_method_setting_impl.cpp", + "src/input_method_event_listener.cpp", + "src/input_method_text_changed_listener.cpp", + "${inputmethod_path}/frameworks/js/napi/inputmethodclient/js_utils.cpp", + ] + deps = [ + ":run_taihe", + "${inputmethod_path}/frameworks/js/napi/common:inputmethod_js_common", + "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client", + ] + external_deps = [ + "ability_base:want", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "c_utils:utils", + "eventhandler:libeventhandler", + "ffrt:libffrt", + "hilog:libhilog" + ] +} + +generate_static_abc("inputmethod_abc") { + base_url = "$taihe_generated_file_path" + files = [ + "$taihe_generated_file_path/@ohos.inputMethod.ets", + "$taihe_generated_file_path/@ohos.inputMethod.Panel.ets", + "$taihe_generated_file_path/@ohos.inputMethodSubtype.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/inputmethod_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("inputmethod_etc") { + source = "$target_out_dir/inputmethod_abc.abc" + module_install_dir = "framework" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [ ":inputmethod_abc"] +} + +group("inputmethod_taihe") { + deps = [ + ":inputmethod_etc", + ":inputmethod_taihe_native", + ] +} diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe new file mode 100644 index 000000000..ff509ff8b --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe @@ -0,0 +1,16 @@ +@!namespace("@ohos.inputMethod.Panel") +enum PanelFlag: i32 { + FLAG_FIXED = 0, + FLAG_FLOATING = 1, + FLAG_CANDIDATE = 2 +} + +enum PanelType: i32 { + SOFT_KEYBOARD = 0, + STATUS_BAR = 1 +} + +struct PanelInfo { + type : PanelType; + flag : Optional; +} \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe new file mode 100644 index 000000000..0abef1f69 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -0,0 +1,245 @@ +@!namespace("@ohos.inputMethod", "inputMethod") +from ohos.inputMethod.Panel use PanelInfo; +from ohos.inputMethodSubtype use InputMethodSubtype; + +struct InputMethodProperty { + @readonly packageName: String; + @readonly methodId: String; + @readonly name: String; + @readonly id: String; + @readonly label: Optional; + @readonly labelId: Optional; + @readonly icon: Optional; + @readonly iconId: Optional; + extra: Optional; +} + +struct InputWindowInfo { + name: String; + left: i32; + top: i32; + width: u32; + height: u32; +} + +interface InputMethodSetting { + @gen_async("getInputMethods") + @gen_promise("getInputMethods") + GetInputMethodSync(enable: bool): Array; + @gen_async("listCurrentInputMethodSubtype") + @gen_promise("listCurrentInputMethodSubtype") + ListCurrentInputMethodSubtypeSync(): Array; + @gen_async("listInputMethodSubtype") + @gen_promise("listInputMethodSubtype") + ListInputMethodSubtypeSync(inputMethodProperty: InputMethodProperty): Array; + IsPanelShown(panelInfo: PanelInfo): bool; + @gen_async("getAllInputMethods") + @gen_promise("getAllInputMethods") + GetAllInputMethodsSync(): Array; + @!sts_inject_into_interface(""" + on(type: string, cb: Object) { + switch(type) { + case "imeHide": return this.onImeHide(cb as (info: Array) => void, cb); + case "imeShow": return this.onImeShow(cb as (info: Array) => void, cb); + case "imeChange": return this.onImeChange(cb as (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_inputMethodSubtype.InputMethodSubtype) => void, cb); + default: throw new Error(`Unknown type: ${type}`); + } + } + off(type: string, cb?: Object) { + switch(type) { + case "imeHide": return this.offImeHide(cb); + case "imeShow": return this.offImeShow(cb); + case "imeChange": return this.offImeChange(cb); + default: throw new Error(`Unknown type: ${type}`); + } + } + """) + OnImeHide(f: (info: Array) => void, opq: Opaque); + OffImeHide(opq: Optional); + OnImeShow(f: (info: Array) => void, opq: Opaque); + OffImeShow(opq: Optional); + OnImeChange(f: (inputMethodProperty: InputMethodProperty, inputMethodSubtype: InputMethodSubtype) => void, opq: Opaque); + OffImeChange(opq: Optional); +} + +struct CursorInfo { + left: f64; + top: f64; + width: f64; + height: f64; +} + +enum Direction : i32 { + CURSOR_UP = 1, + CURSOR_DOWN = 2, + CURSOR_LEFT = 3, + CURSOR_RIGHT = 4 +} + +struct Range { + start: i32; + end: i32; +} + +struct Movement { + direction : Direction; +} + +enum ExtendAction : i32 { + SELECT_ALL = 0, + CUT = 3, + COPY = 4, + PASTE = 5 +} + +enum TextInputType : i32 { + NONE = -1, + TEXT = 0, + MULTILINE = 1, + NUMBER = 2, + PHONE = 3, + DATETIME = 4, + EMAIL_ADDRESS = 5, + URL = 6, + VISIBLE_PASSWORD = 7, + NUMBER_PASSWORD = 8 +} + +enum EnterKeyType : i32 { + UNSPECIFIED = 0, + NONE = 1, + GO = 2, + SEARCH = 3, + SEND = 4, + NEXT = 5, + DONE = 6, + PREVIOUS = 7, + NEWLINE = 8 +} + +struct FunctionKey { + enterKeyType : EnterKeyType; +} + +struct InputAttribute { + textInputType: TextInputType; + enterKeyType: EnterKeyType; +} + +struct TextConfig { + inputAttribute: InputAttribute; + @readonly cursorInfo: CursorInfo; + @readonly selection: Range; + @readonly windowId: i32; +} + + +enum KeyboardStatus : i32 { + NONE = 0, + HIDE = 1, + SHOW = 2 +} + +enum RequestKeyboardReason : i32 { + NONE = 0, + MOUSE = 1, + TOUCH = 2, + OTHER = 20 +} + +interface InputMethodController { + @gen_async("hideSoftKeyboard") + @gen_promise("hideSoftKeyboard") + HideSoftKeyboardSync(); + @gen_promise("showTextInput") + ShowTextInputHasParam(requestKeyboardReason: RequestKeyboardReason); + @gen_async("showTextInput") + @gen_promise("showTextInput") + ShowTextInputSync(); + @gen_async("hideTextInput") + @gen_promise("hideTextInput") + HideTextInputSync(); + @gen_async("attach") + @gen_promise("attach") + AttachSync(showKeyboard: bool, textConfig: TextConfig); + @gen_promise("attach") + AttachWithReason(showKeyboard: bool, textConfig: TextConfig, requestKeyboardReason: RequestKeyboardReason); + @gen_async("detach") + @gen_promise("detach") + DetachSync(); + @!sts_inject_into_interface(""" + on(type: string, cb: Object) { + switch(type) { + case "selectByRange": return this.onSelectByRange(cb as (range : Range) => void, cb); + case "selectByMovement": return this.onSelectByMovement(cb as (movement : Movement) => void, cb); + case "insertText": return this.onInsertText(cb as (text: String) => void, cb); + case "deleteLeft": return this.onDeleteLeft(cb as (length: i32) => void, cb); + case "deleteRight": return this.onDeleteRight(cb as (length: i32) => void, cb); + case "sendKeyboardStatus": return this.onSendKeyboardStatus(cb as (keyboardStatus: KeyboardStatus) => void, cb); + case "sendFunctionKey": return this.onSendFunctionKey(cb as (functionKey: FunctionKey) => void, cb); + case "moveCursor": return this.onMoveCursor(cb as (direction: Direction) => void, cb); + case "handleExtendSelection": return this.onHandleExtendSelection(cb as (extendAction: ExtendAction) => void, cb); + case "getLeftTextOfCursor": return this.onGetLeftTextOfCursor(cb as (length: i32) => void, cb); + case "getRightTextOfCursor": return this.onGetRightTextOfCursor(cb as (length: i32) => void, cb); + case "getTextIndexAtCursor": return this.onGetTextIndexAtCursor(cb as () => i32, cb); + default: throw new Error(`Unknown type: ${type}`); + } + off(type: string, cb?: Object) { + switch(type) { + case "selectByRange": return this.offSelectByRange(cb); + case "selectByMovement": return this.offSelectByMovement(cb); + case "insertText": return this.offInsertText(cb); + case "deleteLeft": return this.offDeleteLeft(cb); + case "deleteRight": return this.offDeleteRight(cb); + case "sendKeyboardStatus": return this.offSendKeyboardStatus(cb); + case "sendFunctionKey": return this.offSendFunctionKey(cb); + case "moveCursor": return this.offMoveCursor(cb); + case "handleExtendSelection": return this.offHandleExtendSelection(cb); + case "getLeftTextOfCursor": return this.offGetLeftTextOfCursor(cb); + case "getRightTextOfCursor": return this.offGetRightTextOfCursor(cb); + case "getTextIndexAtCursor": return this.offGetTextIndexAtCursor(cb); + default: throw new Error(`Unknown type: ${type}`); + } + } + } + """) + OnSelectByRange(f: (range : Range) => void, opq: Opaque); + OffSelectByRange(opq: Optional); + OnSelectByMovement(f: (movement : Movement) => void, opq: Opaque); + OffSelectByMovement(opq: Optional); + OnInsertText(f: (text: String) => void, opq: Opaque); + OffInsertText(opq: Optional); + OnDeleteLeft(f: (length: i32) => void, opq: Opaque); + OffDeleteLeft(opq: Optional); + OnDeleteRight(f: (length: i32) => void, opq: Opaque); + OffDeleteRight(opq: Optional); + OnSendKeyboardStatus(f: (keyboardStatus: KeyboardStatus) => void, opq: Opaque); + OffSendKeyboardStatus(opq: Optional); + OnSendFunctionKey(f: (functionKey: FunctionKey) => void, opq: Opaque); + OffSendFunctionKey(opq: Optional); + OnMoveCursor(f: (direction: Direction) => void, opq: Opaque); + OffMoveCursor(opq: Optional); + OnHandleExtendAction(f: (action: ExtendAction) => void, opq: Opaque); + OffHandleExtendAction(opq: Optional); + OnGetLeftTextOfCursor(f: (length: i32) => void, opq: Opaque); + OffGetLeftTextOfCursor(opq: Optional); + OnGetRightTextOfCursor(f: (length: i32) => void, opq: Opaque); + OffGetRightTextOfCursor(opq: Optional); + OnGetTextIndexAtCursor(f: () => i32, opq: Opaque); + OffGetTextIndexAtCursor(opq: Optional); +} + +function GetSetting(): InputMethodSetting; +function GetController(): InputMethodController; +function GetDefaultInputMethod(): InputMethodProperty; +function GetCurrentInputMethod(): InputMethodProperty; +function GetCurrentInputMethodSubtype(): InputMethodSubtype; +function GetSystemInputMethodConfigAbility(): Opaque; +@gen_async("switchInputMethod") +@gen_promise("switchInputMethod") +function SwitchInputMethodWithTarget(target: InputMethodProperty): bool; +@gen_promise("switchInputMethod") +function SwitchInputMethodSync(bundleName: String, subtypeId: Optional); +@gen_async("switchCurrentInputMethodSubtype") +@gen_promise("switchCurrentInputMethodSubtype") +function SwitchCurrentInputMethodSubtypeSync(target: InputMethodProperty): bool; \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe new file mode 100644 index 000000000..fc85da497 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe @@ -0,0 +1,13 @@ +@!namespace("@ohos.inputMethodSubtype") +struct InputMethodSubtype { + @readonly name: String; + @readonly id: String; + @readonly locale: String; + @readonly language: String; + @readonly mode: Optional; + @readonly icon: Optional; + @readonly iconId: Optional; + @readonly label: Optional; + @readonly labelId: Optional; + extra: Optional; +} \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h new file mode 100644 index 000000000..2163ae51e --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INPUT_METHOD_TAIHE_ANI_COMMON_H +#define INPUT_METHOD_TAIHE_ANI_COMMON_H + +#include "ohos.inputMethod.proj.hpp" +#include "ohos.inputMethod.impl.hpp" +#include "input_method_property.h" +#include "taihe/runtime.hpp" +#include "input_method_utils.h" +using InputMethodProperty_t = ohos::inputMethod::InputMethodProperty; +using InputMethodSubtype_t = ohos::inputMethodSubtype::InputMethodSubtype; +using PanelInfo_t = ohos::inputMethod::Panel::PanelInfo; +using InputWindowInfo_t = ohos::inputMethod::InputWindowInfo; +using RequestKeyboardReason_t = ohos::inputMethod::RequestKeyboardReason; +using TextConfig_t = ohos::inputMethod::TextConfig; +using Range_t = ohos::inputMethod::Range; +using Movement_t = ohos::inputMethod::Movement; +using KeyboardStatus_t = ohos::inputMethod::KeyboardStatus; +using FunctionKey_t = ohos::inputMethod::FunctionKey; +using ExtendAction_t = ohos::inputMethod::ExtendAction; +using EnterKeyType_t = ohos::inputMethod::EnterKeyType; +using Direction_t = ohos::inputMethod::Direction; +namespace OHOS { +namespace MiscServices { +class PropertyConverter { +public: + static InputMethodProperty_t ConvertProperty(const std::shared_ptr& obj) { + return ConvertPropertyImpl(*obj); + } + + static InputMethodProperty_t ConvertProperty(const Property& obj) { + return ConvertPropertyImpl(obj); + } + + + static InputMethodSubtype_t ConvertSubProperty(const std::shared_ptr& obj) { + return ConvertSubPropertyImpl(*obj); + } + + static InputMethodSubtype_t ConvertSubProperty(const SubProperty& obj) { + return ConvertSubPropertyImpl(obj); + } + +private: + template + static InputMethodProperty_t ConvertPropertyImpl(T&& obj) { + static_assert(std::is_same_v, Property>, "Invalid type for Property conversion"); + + InputMethodProperty_t result{}; + result.packageName = std::forward(obj).name; + result.name = std::forward(obj).name; + result.methodId = obj.id; + result.id = obj.id; + result.label = taihe::optional(std::in_place_t{}, obj.label); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.icon = taihe::optional(std::in_place_t{}, obj.icon); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + return result; + } + + template + static InputMethodSubtype_t ConvertSubPropertyImpl(T&& obj) { + static_assert(std::is_same_v, SubProperty>, + "Invalid type for SubProperty conversion"); + + InputMethodSubtype_t result{}; + result.name = std::forward(obj).name; + result.id = obj.id; + result.locale = obj.locale; + result.language = obj.language; + result.label = taihe::optional(std::in_place_t{}, obj.label); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.icon = taihe::optional(std::in_place_t{}, obj.icon); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + return result; + } +}; + +using callbackType = std::variant< + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback, + taihe::callback)>, + taihe::callback>; + +struct CallbackObject { + CallbackObject(callbackType cb, ani_ref ref): callback(cb), ref(ref) {} + ~CallbackObject() { + if (auto* env = taihe::get_env()) { + env->GlobalReference_Delete(ref); + } + } + callbackType callback; + ani_ref ref; +}; + +class GlobalRefGuard { + ani_env* env_ = nullptr; + ani_ref ref_ = nullptr; +public: + GlobalRefGuard(ani_env* env, ani_object obj) : env_(env) { + if (!env_) return; + if (ANI_OK != env_->GlobalReference_Create(obj, &ref_)) { + ref_ = nullptr; + } + } + explicit operator bool() const { return ref_ != nullptr; } + ani_ref get() const { return ref_; } + ~GlobalRefGuard() { + if (env_ && ref_) { + env_->GlobalReference_Delete(ref_); + } + } + + GlobalRefGuard(const GlobalRefGuard&) = delete; + GlobalRefGuard& operator=(const GlobalRefGuard&) = delete; +}; + +class EnumConvert { +public: + static Direction_t ConvertDirection(Direction direction) { + switch (direction) { + case Direction::UP: + return Direction_t::key_t::CURSOR_UP; + case Direction::DOWN: + return Direction_t::key_t::CURSOR_DOWN; + case Direction::LEFT: + return Direction_t::key_t::CURSOR_LEFT; + case Direction::RIGHT: + return Direction_t::key_t::CURSOR_RIGHT; + default: + return Direction_t::key_t::CURSOR_UP; + } + } + + static ExtendAction_t ConvertExtendAction(int32_t action) { + switch (action) { + case 0: + return ExtendAction_t::key_t::SELECT_ALL; + case 3: + return ExtendAction_t::key_t::CUT; + case 4: + return ExtendAction_t::key_t::COPY; + case 5: + return ExtendAction_t::key_t::PASTE; + default: + return ExtendAction_t::key_t::SELECT_ALL; + } + } + + static EnterKeyType_t ConvertEnterKeyType(EnterKeyType type) { + switch (type) { + case EnterKeyType::UNSPECIFIED: + return EnterKeyType_t::key_t::UNSPECIFIED; + case EnterKeyType::NONE: + return EnterKeyType_t::key_t::NONE; + case EnterKeyType::GO: + return EnterKeyType_t::key_t::GO; + case EnterKeyType::SEARCH: + return EnterKeyType_t::key_t::SEARCH; + case EnterKeyType::SEND: + return EnterKeyType_t::key_t::SEND; + case EnterKeyType::NEXT: + return EnterKeyType_t::key_t::NEXT; + case EnterKeyType::DONE: + return EnterKeyType_t::key_t::DONE; + case EnterKeyType::PREVIOUS: + return EnterKeyType_t::key_t::PREVIOUS; + case EnterKeyType::NEW_LINE: + return EnterKeyType_t::key_t::NEWLINE; + default: + return EnterKeyType_t::key_t::UNSPECIFIED; + } + } + + static KeyboardStatus_t ConvertKeyboardStatus(KeyboardStatus status) { + switch (status) { + case KeyboardStatus::SHOW: + return KeyboardStatus_t::key_t::SHOW; + case KeyboardStatus::HIDE: + return KeyboardStatus_t::key_t::HIDE; + default: + return KeyboardStatus_t::key_t::NONE; + } + } +}; +} +} +#endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h new file mode 100644 index 000000000..d372f387b --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TAIHE_INPUT_METHOD_CONTROLLER_IMPL_H +#define TAIHE_INPUT_METHOD_CONTROLLER_IMPL_H +#include "ohos.inputMethod.proj.hpp" +#include "ohos.inputMethod.impl.hpp" +#include "input_method_utils.h" +#include "controller_listener.h" +#include "ani_common.h" +#include +#include +#include +#include +#include +namespace OHOS { +namespace MiscServices { +class InputMethodControllerImpl : public ControllerListener { +public: + static std::shared_ptr GetInstance(); + void HideSoftKeyboardSync(); + void ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason); + void ShowTextInputSync(); + void HideTextInputSync(); + void AttachSync(bool showKeyboard, TextConfig_t const& textConfig); + void AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason); + void DetachSync(); + void RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq); + void UnRegisterListener(std::string const& type, taihe::optional_view opq); + + void InsertTextCallback(const std::u16string &text); + void DeleteLeftCallback(int32_t length); + void DeleteRightCallback(int32_t length); + void SendKeyboardStatusCallback(const KeyboardStatus &status); + void SendFunctionKeyCallback(const FunctionKey &key); + void MoveCursorCallback(const Direction &direction); + void HandleExtendActionCallback(int32_t action); + std::u16string GetLeftTextOfCursorCallback(int32_t number); + std::u16string GetRightTextOfCursorCallback(int32_t number); + int32_t GetTextIndexAtCursorCallback(); + + void OnSelectByRange(int32_t start, int32_t end) override; + void OnSelectByMovement(int32_t direction) override; +private: + std::mutex mutex_; + std::map> jsCbMap_; + static std::mutex controllerMutex_; + static std::shared_ptr controller_; +}; + +class IMFControllerImpl { +public: + void HideSoftKeyboardSync() { + InputMethodControllerImpl::GetInstance()->HideSoftKeyboardSync(); + } + void ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason) { + InputMethodControllerImpl::GetInstance()->ShowTextInputHasParam(requestKeyboardReason); + } + void ShowTextInputSync() { + InputMethodControllerImpl::GetInstance()->ShowTextInputSync(); + } + void HideTextInputSync() { + InputMethodControllerImpl::GetInstance()->HideTextInputSync(); + } + void AttachSync(bool showKeyboard, TextConfig_t const& textConfig) { + InputMethodControllerImpl::GetInstance()->AttachSync(showKeyboard, textConfig); + } + void AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason) { + InputMethodControllerImpl::GetInstance()->AttachWithReason(showKeyboard, textConfig, requestKeyboardReason); + } + void DetachSync() { + InputMethodControllerImpl::GetInstance()->DetachSync(); + } + void OnSelectByRange(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("selectByRange", f, opq); + } + void OffSelectByRange(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("selectByRange", opq); + } + void OnSelectByMovement(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("selectByMovement", f, opq); + } + void OffSelectByMovement(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("selectByMovement", opq); + } + void OnInsertText(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("insertText", f, opq); + } + void OffInsertText(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("insertText", opq); + } + void OnDeleteLeft(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("deleteLeft", f, opq); + } + void OffDeleteLeft(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("deleteLeft", opq); + } + void OnDeleteRight(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("deleteRight", f, opq); + } + void OffDeleteRight(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("deleteRight", opq); + } + void OnSendKeyboardStatus(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("sendKeyboardStatus", f, opq); + } + void OffSendKeyboardStatus(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("sendKeyboardStatus", opq); + } + void OnSendFunctionKey(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("sendFunctionKey", f, opq); + } + void OffSendFunctionKey(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("sendFunctionKey", opq); + } + void OnMoveCursor(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("moveCursor", f, opq); + } + void OffMoveCursor(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("moveCursor", opq); + } + void OnHandleExtendAction(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("handleExtendAction", f, opq); + } + void OffHandleExtendAction(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("handleExtendAction", opq); + } + void OnGetLeftTextOfCursor(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("getLeftTextOfCursor", f, opq); + } + void OffGetLeftTextOfCursor(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("getLeftTextOfCursor", opq); + } + void OnGetRightTextOfCursor(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("getRightTextOfCursor", f, opq); + } + void OffGetRightTextOfCursor(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("getRightTextOfCursor", opq); + } + void OnGetTextIndexAtCursor(taihe::callback_view f, uintptr_t opq) { + InputMethodControllerImpl::GetInstance()->RegisterListener("getTextIndexAtCursor", f, opq); + } + void OffGetTextIndexAtCursor(taihe::optional_view opq) { + InputMethodControllerImpl::GetInstance()->UnRegisterListener("getTextIndexAtCursor", opq); + } +}; +} +} +#endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h b/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h new file mode 100644 index 000000000..ba26faf5b --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_EVENT_LISTENER_H +#define FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_EVENT_LISTENER_H + +#include "ani_common.h" +#include "input_method_property.h" +#include "input_window_info.h" +#include "ime_event_listener.h" + +namespace OHOS { +namespace MiscServices { +class InputMethodEventListener: public ImeEventListener { +public: + InputMethodEventListener() = default; + ~InputMethodEventListener() = default; + static std::shared_ptr GetInstance(); + void OnImeChange(const Property &property, const SubProperty &subProperty); + void OnImeShow(const ImeWindowInfo &info); + void OnImeHide(const ImeWindowInfo &info); +private: + static std::mutex listenerMutex_; + static std::shared_ptr inputMethodListener_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_EVENT_LISTENER_H + \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h new file mode 100644 index 000000000..7d75f3fab --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TAIHE_INPUT_METHOD_SETTING_IMPL_H +#define TAIHE_INPUT_METHOD_SETTING_IMPL_H +#include "ohos.inputMethod.proj.hpp" +#include "ohos.inputMethod.impl.hpp" +#include "input_window_info.h" +#include "ime_event_listener.h" +#include "ani_common.h" +#include +#include +#include +namespace OHOS { +namespace MiscServices { +class InputMethodSettingImpl { +public: + static InputMethodSettingImpl& GetInstance(); + taihe::array GetInputMethodSync(bool enable); + taihe::array ListCurrentInputMethodSubtypeSync(); + taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty); + bool IsPanelShown(PanelInfo_t const& panelInfo); + taihe::array GetAllInputMethodsSync(); + void OnImeChangeCallback(const Property &property, const SubProperty &subProperty); + void OnImeShowCallback(const ImeWindowInfo &info); + void OnImeHideCallback(const ImeWindowInfo &info); + void RegisterImeEvent(std::string const& eventName, int32_t eventMask, callbackType&& f, uintptr_t opq); + void UnregisterImeEvent(std::string const& eventName, int32_t eventMask, taihe::optional_view opq); +private: + PanelFlag softKbShowingFlag_{ FLG_CANDIDATE_COLUMN }; + PanelFlag GetSoftKbShowingFlag(); + void SetSoftKbShowingFlag(PanelFlag flag); + void OnPanelStatusChange(std::string const& type, const InputWindowInfo &info); + void RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq); + void UnregisterListener(std::string const& type, taihe::optional_view opq, bool& isUpdateFlag); + void HandleRegistrationError(std::string const& eventName, int32_t errorCode); + std::mutex mutex_; + std::map> jsCbMap_; +}; + +class IMFSettingImpl { +public: + IMFSettingImpl() {} + taihe::array GetInputMethodSync(bool enable) { + return InputMethodSettingImpl::GetInstance().GetInputMethodSync(enable); + } + taihe::array ListCurrentInputMethodSubtypeSync() { + return InputMethodSettingImpl::GetInstance().ListCurrentInputMethodSubtypeSync(); + } + taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty) { + return InputMethodSettingImpl::GetInstance().ListInputMethodSubtypeSync(inputMethodProperty); + } + bool IsPanelShown(PanelInfo_t const& panelInfo) { + return InputMethodSettingImpl::GetInstance().IsPanelShown(panelInfo); + } + taihe::array GetAllInputMethodsSync() { + return InputMethodSettingImpl::GetInstance().GetAllInputMethodsSync(); + } + void OnImeHide(taihe::callback_view)> f, uintptr_t opq) { + InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeHide", EVENT_IME_HIDE_MASK, f, opq); + } + void OffImeHide(taihe::optional_view opq) { + InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeHide", EVENT_IME_HIDE_MASK, opq); + } + void OnImeShow(taihe::callback_view)> f, uintptr_t opq) { + InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeShow", EVENT_IME_SHOW_MASK, f, opq); + } + void OffImeShow(taihe::optional_view opq) { + InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeShow", EVENT_IME_SHOW_MASK, opq); + } + void OnImeChange(taihe::callback_view f, uintptr_t opq) { + InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeChange", EVENT_IME_CHANGE_MASK, f, opq); + } + void OffImeChange(taihe::optional_view opq) { + InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeChange", EVENT_IME_CHANGE_MASK, opq); + } +}; +} +} +#endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h b/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h new file mode 100644 index 000000000..a2e5b6a7c --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H + #define FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H + + #include "input_method_controller.h" + namespace OHOS { + namespace MiscServices { + class InputMethodTextChangedListener : public OnTextChangedListener { + public: + InputMethodTextChangedListener() = default; + ~InputMethodTextChangedListener() = default; + static sptr GetInstance(); + + void InsertText(const std::u16string &text) override; + void DeleteForward(int32_t length) override; + void DeleteBackward(int32_t length) override; + void SendKeyEventFromInputMethod(const KeyEvent &event) override + { + } + void SendKeyboardStatus(const KeyboardStatus &status) override; + void SendFunctionKey(const FunctionKey &functionKey) override; + void SetKeyboardStatus(bool status) override + { + } + void MoveCursor(const Direction direction) override; + void HandleSetSelection(int32_t start, int32_t end) override + { + } + void HandleExtendAction(int32_t action) override; + void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override + { + } + std::u16string GetLeftTextOfCursor(int32_t number) override; + std::u16string GetRightTextOfCursor(int32_t number) override; + int32_t GetTextIndexAtCursor() override; + int32_t ReceivePrivateCommand(const std::unordered_map &privateCommand) override + { return 0; } + bool IsFromTs() override + { return false; } + int32_t SetPreviewText(const std::u16string &text, const Range &range) override + { return 0; } + void FinishTextPreview() override + {} + + private: + static std::mutex listenerMutex_; + static sptr inputMethodListener_; + }; + } // namespace MiscServices + } // namespace OHOS + #endif // FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGE_LISTENER_H \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp new file mode 100644 index 000000000..56dc199d2 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ohos.inputMethod.ani.hpp" +#include "ohos.inputMethodSubtype.ani.hpp" +#include "ohos.inputMethod.Panel.ani.hpp" +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::inputMethod::ANIRegister(env)) { + std::cerr << "Error from ohos::inputMethod::ANIRegister" << std::endl; + return ANI_ERROR; + } + if (ANI_OK != ohos::inputMethodSubtype::ANIRegister(env)) { + std::cerr << "Error from ohos::inputMethodSubtype::ANIRegister" << std::endl; + return ANI_ERROR; + } + if (ANI_OK != ohos::inputMethod::Panel::ANIRegister(env)) { + std::cerr << "Error from ohos::inputMethod::Panel::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp new file mode 100644 index 000000000..9c86e745a --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "input_method_controller_impl.h" +#include "input_method_text_changed_listener.h" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include "input_method_controller.h" +#include "ani_common.h" +#include "js_utils.h" +#include +#include "string_ex.h" + +namespace OHOS { +namespace MiscServices { +using namespace taihe; +std::mutex InputMethodControllerImpl::controllerMutex_; +std::shared_ptr InputMethodControllerImpl::controller_ { nullptr }; +std::shared_ptr InputMethodControllerImpl::GetInstance() +{ + if (controller_ == nullptr) { + std::lock_guard lock(controllerMutex_); + if (controller_ == nullptr) { + auto controller = std::make_shared(); + controller_ = controller; + InputMethodController::GetInstance()->SetControllerListener(controller_); + } + } + return controller_; +} + +void InputMethodControllerImpl::HideSoftKeyboardSync() +{ + int32_t errCode = InputMethodController::GetInstance()->HideSoftKeyboard(); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +void InputMethodControllerImpl::ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason) +{ + AttachOptions attachOptions; + attachOptions.requestKeyboardReason = static_cast(requestKeyboardReason.get_value()); + int32_t errCode = InputMethodController::GetInstance()->ShowTextInput(attachOptions, ClientType::JS); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +void InputMethodControllerImpl::ShowTextInputSync() +{ + ShowTextInputHasParam(RequestKeyboardReason_t::key_t::NONE); +} + +void InputMethodControllerImpl::HideTextInputSync() +{ + int32_t errCode = InputMethodController::GetInstance()->HideTextInput(); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +void InputMethodControllerImpl::AttachSync(bool showKeyboard, TextConfig_t const& textConfig) +{ + AttachWithReason(showKeyboard, textConfig, RequestKeyboardReason_t::key_t::NONE); +} + +void InputMethodControllerImpl::AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason) +{ + AttachOptions attachOptions; + attachOptions.isShowKeyboard = showKeyboard; + attachOptions.requestKeyboardReason = static_cast(requestKeyboardReason.get_value()); + TextConfig config; + config.inputAttribute.inputPattern = textConfig.inputAttribute.textInputType.get_value(); + config.inputAttribute.enterKeyType = textConfig.inputAttribute.enterKeyType.get_value(); + config.cursorInfo.left = textConfig.cursorInfo.left; + config.cursorInfo.top = textConfig.cursorInfo.top; + config.cursorInfo.width = textConfig.cursorInfo.width; + config.cursorInfo.height = textConfig.cursorInfo.height; + config.range.start = textConfig.selection.start; + config.range.end = textConfig.selection.end; + config.windowId = textConfig.windowId; + // TODO isTextPreviewSupported + + int32_t errCode = InputMethodController::GetInstance()->Attach(InputMethodTextChangedListener::GetInstance(), attachOptions, config, ClientType::JS); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +void InputMethodControllerImpl::DetachSync() +{ + int32_t errCode = InputMethodController::GetInstance()->Close(); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +void InputMethodControllerImpl::RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq) +{ + std::lock_guard lock(mutex_); + ani_object callbackObj = reinterpret_cast(opq); + ani_ref callbackRef; + ani_env *env = taihe::get_env(); + if (env == nullptr || ANI_OK != env->GlobalReference_Create(callbackObj, &callbackRef)) { + return; + } + auto& cbVec = jsCbMap_[type]; + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), + [env, callbackRef](const CallbackObject& obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj.ref, &isEqual)) && isEqual; + } + ); + if (isDuplicate) { + env->GlobalReference_Delete(callbackRef); + return; + } + cbVec.emplace_back(cb, callbackRef); +} +void InputMethodControllerImpl::UnRegisterListener(std::string const& type, taihe::optional_view opq) +{ + std::lock_guard lock(mutex_); + const auto iter = jsCbMap_.find(type); + if (iter == jsCbMap_.end()) { + return; + } + + if (!opq.has_value()) { + jsCbMap_.erase(iter); + return; + } + + ani_env* env = taihe::get_env(); + if (env == nullptr) { + return; + } + + GlobalRefGuard guard(env, reinterpret_cast(opq.value())); + if (!guard) { + return; + } + + const auto pred = [env, targetRef = guard.get()](const CallbackObject& obj) { + ani_boolean is_equal = false; + return (ANI_OK == env->Reference_StrictEquals(targetRef, obj.ref, &is_equal)) && is_equal; + }; + auto& callbacks = iter->second; + const auto it = std::find_if(callbacks.begin(), callbacks.end(), pred); + if (it != callbacks.end()) { + callbacks.erase(it); + } + if (callbacks.empty()) { + jsCbMap_.erase(iter); + } +} + + +void InputMethodControllerImpl::InsertTextCallback(const std::u16string &text) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["insertText"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + taihe::string textStr = Str16ToStr8(text); + func(textStr); + } +} +void InputMethodControllerImpl::DeleteLeftCallback(int32_t length) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["deleteLeft"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + func(length); + } +} +void InputMethodControllerImpl::DeleteRightCallback(int32_t length) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["deleteRight"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + func(length); + } +} +void InputMethodControllerImpl::SendKeyboardStatusCallback(const KeyboardStatus &status) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["sendKeyboardStatus"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + KeyboardStatus_t state = EnumConvert::ConvertKeyboardStatus(status); + func(state); + } +} +void InputMethodControllerImpl::SendFunctionKeyCallback(const FunctionKey &key) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["sendFunctionKey"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + FunctionKey_t funcKey{.enterKeyType = EnumConvert::ConvertEnterKeyType(key.GetEnterKeyType())}; + func(funcKey); + } +} +void InputMethodControllerImpl::MoveCursorCallback(const Direction &direction) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["moveCursor"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + Direction_t directionType = EnumConvert::ConvertDirection(direction); + func(directionType); + } +} +void InputMethodControllerImpl::HandleExtendActionCallback(int32_t action) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["handleExtendAction"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + ExtendAction_t actionType = EnumConvert::ConvertExtendAction(action); + func(actionType); + } +} +std::u16string InputMethodControllerImpl::GetLeftTextOfCursorCallback(int32_t number) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["getLeftTextOfCursor"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + taihe::string s = func(number); + return Str8ToStr16(std::string(s)); + } + return Str8ToStr16(std::string()); +} +std::u16string InputMethodControllerImpl::GetRightTextOfCursorCallback(int32_t number) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["getRightTextOfCursor"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + taihe::string s = func(number); + return Str8ToStr16(std::string(s)); + } + return Str8ToStr16(std::string()); +} +int32_t InputMethodControllerImpl::GetTextIndexAtCursorCallback() +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["getTextIndexAtCursor"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + return func(); + } + return 0; +} + +void InputMethodControllerImpl::OnSelectByRange(int32_t start, int32_t end) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["selectByRange"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + Range_t range{.start = start, .end = end}; + func(range); + } +} +void InputMethodControllerImpl::OnSelectByMovement(int32_t direction) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["selectByMovement"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + Movement_t movement{.direction = EnumConvert::ConvertDirection(static_cast(direction))}; + func(movement); + } +} +} +} \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp new file mode 100644 index 000000000..355793cf4 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "input_method_event_listener.h" +#include "input_method_setting_impl.h" +namespace OHOS { +namespace MiscServices { +std::mutex InputMethodEventListener::listenerMutex_; +std::shared_ptr InputMethodEventListener::inputMethodListener_{ nullptr }; +std::shared_ptr InputMethodEventListener::GetInstance() +{ + if (inputMethodListener_ == nullptr) { + std::lock_guard lock(listenerMutex_); + if (inputMethodListener_ == nullptr) { + inputMethodListener_ = std::make_shared(); + } + } + return inputMethodListener_; +} +void InputMethodEventListener::OnImeChange(const Property &property, const SubProperty &subProperty) +{ + InputMethodSettingImpl::GetInstance().OnImeChangeCallback(property, subProperty); +} + +void InputMethodEventListener::OnImeShow(const ImeWindowInfo &info) +{ + InputMethodSettingImpl::GetInstance().OnImeShowCallback(info); +} + +void InputMethodEventListener::OnImeHide(const ImeWindowInfo &info) +{ + InputMethodSettingImpl::GetInstance().OnImeHideCallback(info); +} +} +} \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp new file mode 100644 index 000000000..34f16d4a8 --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "input_method_setting_impl.h" +#include "input_method_event_listener.h" +#include "ime_event_monitor_manager_impl.h" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include "input_method_controller.h" +#include "js_utils.h" +#include "ani_common.h" + +namespace OHOS { +namespace MiscServices { +using namespace taihe; + +InputMethodSettingImpl& InputMethodSettingImpl::GetInstance() +{ + static InputMethodSettingImpl instance; + return instance; +} + +array InputMethodSettingImpl::GetInputMethodSync(bool enable) { + std::vector properties; + int32_t errCode = + InputMethodController::GetInstance()->ListInputMethod(enable, properties); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), "failed to get input method!"); + return array(nullptr, 0); + } + std::vector vecProperty; + for (const auto& property : properties) { + vecProperty.push_back(PropertyConverter::ConvertProperty(property)); + } + return array(vecProperty); +} + +array InputMethodSettingImpl::ListCurrentInputMethodSubtypeSync() +{ + std::vector subProperties; + int32_t errCode = + InputMethodController::GetInstance()->ListCurrentInputMethodSubtype(subProperties); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + return array(nullptr, 0); + } + std::vector vecSubtype; + for (const auto& property : subProperties) { + vecSubtype.push_back(PropertyConverter::ConvertSubProperty(property)); + } + return array(vecSubtype); + +} + +array InputMethodSettingImpl::ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty) +{ + Property property{.name = std::string(inputMethodProperty.name), .id = std::string(inputMethodProperty.id)}; + if (property.name.empty() || property.id.empty()) { + property.name = inputMethodProperty.packageName; + property.id = inputMethodProperty.methodId; + } + if (property.name.empty() || property.id.empty()) { + set_business_error(IMFErrorCode::EXCEPTION_PARAMCHECK, "name and id must be string and cannot empty"); + return array(nullptr, 0); + } + std::vector subProperties; + int32_t errCode = + InputMethodController::GetInstance()->ListInputMethodSubtype(property, subProperties); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + return array(nullptr, 0); + } + std::vector vecSubtype; + for (const auto& property : subProperties) { + vecSubtype.push_back(PropertyConverter::ConvertSubProperty(property)); + } + return array(vecSubtype); +} + +bool InputMethodSettingImpl::IsPanelShown(PanelInfo_t const& panelInfo) +{ + PanelInfo info; + if (panelInfo.flag.has_value()) { + info.panelFlag = static_cast(panelInfo.flag.value().get_value()); + } + info.panelType = static_cast(panelInfo.type.get_value()); + bool isShown = false; + int32_t errorCode = InputMethodController::GetInstance()->IsPanelShown(info, isShown); + if (errorCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errorCode), "failed to query is panel shown!"); + return false; //napi 接口返回null + } + return isShown; +} + +array InputMethodSettingImpl::GetAllInputMethodsSync() +{ + TH_THROW(std::runtime_error, "GetAllInputMethodsSync not implemented"); + std::vector properties; + int32_t errCode = + InputMethodController::GetInstance()->ListInputMethod(properties); + if (errCode != ErrorCode::NO_ERROR) { + set_business_error(JsUtils::Convert(errCode), "failed to get input method!"); + return array(nullptr, 0); + } + std::vector vecProperty; + for (const auto& property : properties) { + vecProperty.push_back(PropertyConverter::ConvertProperty(property)); + } + return array(vecProperty); +} + +void InputMethodSettingImpl::RegisterImeEvent(std::string const& eventName, int32_t eventMask, callbackType&& f, uintptr_t opq) +{ + auto ret = ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener( + eventMask, InputMethodEventListener::GetInstance()); + + if (ret == ErrorCode::NO_ERROR) { + RegisterListener(eventName, std::forward(f), opq); + } else { + HandleRegistrationError(eventName, ret); + } +} +void InputMethodSettingImpl::UnregisterImeEvent(std::string const& eventName, int32_t eventMask, optional_view opq) +{ + bool isUpdateFlag = false; + UnregisterListener(eventName, opq, isUpdateFlag); + + if (isUpdateFlag) { + auto ret = ImeEventMonitorManagerImpl::GetInstance().UnRegisterImeEventListener( + eventMask, InputMethodEventListener::GetInstance()); + IMSA_HILOGI("Updated event: %{public}s flag, ret: %{public}d", eventName.c_str(), ret); + } +} +void InputMethodSettingImpl::HandleRegistrationError(std::string const& eventName, int32_t errorCode) +{ + auto errCode = JsUtils::Convert(errorCode); + if (errCode == EXCEPTION_SYSTEM_PERMISSION) { + set_business_error(EXCEPTION_SYSTEM_PERMISSION, + JsUtils::ToMessage(EXCEPTION_SYSTEM_PERMISSION)); + } + IMSA_HILOGE("Failed to register %{public}s, error: %{public}d", eventName.c_str(), errorCode); +} +void InputMethodSettingImpl::RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq) +{ + std::lock_guard lock(mutex_); + ani_object callbackObj = reinterpret_cast(opq); + ani_ref callbackRef; + ani_env *env = taihe::get_env(); + if (env == nullptr || ANI_OK != env->GlobalReference_Create(callbackObj, &callbackRef)) { + return; + } + auto& cbVec = jsCbMap_[type]; + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), + [env, callbackRef](const CallbackObject& obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj.ref, &isEqual)) && isEqual; + } + ); + if (isDuplicate) { + env->GlobalReference_Delete(callbackRef); + return; + } + cbVec.emplace_back(cb, callbackRef); +} +void InputMethodSettingImpl::UnregisterListener(std::string const& type, optional_view opq, bool& isUpdateFlag) +{ + std::lock_guard lock(mutex_); + const auto iter = jsCbMap_.find(type); + if (iter == jsCbMap_.end()) { + return; + } + + if (!opq.has_value()) { + jsCbMap_.erase(iter); + isUpdateFlag = true; + return; + } + + ani_env* env = taihe::get_env(); + if (env == nullptr) { + return; + } + + GlobalRefGuard guard(env, reinterpret_cast(opq.value())); + if (!guard) { + return; + } + + const auto pred = [env, targetRef = guard.get()](const CallbackObject& obj) { + ani_boolean is_equal = false; + return (ANI_OK == env->Reference_StrictEquals(targetRef, obj.ref, &is_equal)) && is_equal; + }; + auto& callbacks = iter->second; + const auto it = std::find_if(callbacks.begin(), callbacks.end(), pred); + if (it != callbacks.end()) { + callbacks.erase(it); + } + if (callbacks.empty()) { + jsCbMap_.erase(iter); + isUpdateFlag = true; + } +} + +void InputMethodSettingImpl::OnImeChangeCallback(const Property &property, const SubProperty &subProperty) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_["imeChange"]; + for(auto &cb : cbVec) { + auto& func = std::get>(cb.callback); + func(PropertyConverter::ConvertProperty(property), PropertyConverter::ConvertSubProperty(subProperty)); + } +} +void InputMethodSettingImpl::OnImeShowCallback(const ImeWindowInfo &info) +{ + if (info.panelInfo.panelType != PanelType::SOFT_KEYBOARD || + (info.panelInfo.panelFlag != FLG_FLOATING && info.panelInfo.panelFlag != FLG_FIXED)) { + return; + } + auto showingFlag = GetSoftKbShowingFlag(); + // FLG_FIXED->FLG_FLOATING in show + if (info.panelInfo.panelFlag == FLG_FLOATING && showingFlag == FLG_FIXED) { + InputWindowInfo windowInfo{ info.windowInfo.name, 0, 0, 0, 0 }; + OnPanelStatusChange("imeHide", windowInfo); + } + // FLG_FLOATING->FLG_FIXED in show/show FLG_FIXED/ rotating(resize) in FLG_FIXED show + if ((info.panelInfo.panelFlag == FLG_FIXED && showingFlag == FLG_FLOATING) || + (info.panelInfo.panelFlag == FLG_FIXED && showingFlag == FLG_CANDIDATE_COLUMN) || + (info.panelInfo.panelFlag == FLG_FIXED && showingFlag == FLG_FIXED)) { + OnPanelStatusChange("imeShow", info.windowInfo); + } + SetSoftKbShowingFlag(info.panelInfo.panelFlag); +} + +void InputMethodSettingImpl::OnImeHideCallback(const ImeWindowInfo &info) +{ + SetSoftKbShowingFlag(FLG_CANDIDATE_COLUMN); + if (info.panelInfo.panelType != PanelType::SOFT_KEYBOARD || info.panelInfo.panelFlag != PanelFlag::FLG_FIXED) { + return; + } + OnPanelStatusChange("imeHide", info.windowInfo); +} + +PanelFlag InputMethodSettingImpl::GetSoftKbShowingFlag() +{ + return softKbShowingFlag_; +} +void InputMethodSettingImpl::SetSoftKbShowingFlag(PanelFlag flag) +{ + softKbShowingFlag_ = flag; +} + +void InputMethodSettingImpl::OnPanelStatusChange(std::string const& type, const InputWindowInfo &info) +{ + std::lock_guard lock(mutex_); + auto& cbVec = jsCbMap_[type]; + for(auto &cb : cbVec) { + InputWindowInfo_t inputWindowInfo{ + .name = info.name, + .left = info.left, + .top = info.top, + .width = info.width, + .height = info.height + }; + taihe::array arrInfo{inputWindowInfo}; + auto& func = std::get)>>(cb.callback); + func(arrInfo); + } +} +} +} \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp new file mode 100644 index 000000000..5379ca5de --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "input_method_text_changed_listener.h" +#include "input_method_controller_impl.h" + +namespace OHOS { +namespace MiscServices { +std::mutex InputMethodTextChangedListener::listenerMutex_; +sptr InputMethodTextChangedListener::inputMethodListener_{ nullptr }; +sptr InputMethodTextChangedListener::GetInstance() +{ + if (inputMethodListener_ == nullptr) { + std::lock_guard lock(listenerMutex_); + if (inputMethodListener_ == nullptr) { + inputMethodListener_ = new (std::nothrow) InputMethodTextChangedListener(); + } + } + return inputMethodListener_; +} + +void InputMethodTextChangedListener::InsertText(const std::u16string &text) +{ + InputMethodControllerImpl::GetInstance()->InsertTextCallback(text); +} + +void InputMethodTextChangedListener::DeleteForward(int32_t length) +{ + InputMethodControllerImpl::GetInstance()->DeleteRightCallback(length); +} + +void InputMethodTextChangedListener::DeleteBackward(int32_t length) +{ + InputMethodControllerImpl::GetInstance()->DeleteLeftCallback(length); +} + +void InputMethodTextChangedListener::SendKeyboardStatus(const KeyboardStatus &status) +{ + InputMethodControllerImpl::GetInstance()->SendKeyboardStatusCallback(status); +} + +void InputMethodTextChangedListener::SendFunctionKey(const FunctionKey &functionKey) +{ + InputMethodControllerImpl::GetInstance()->SendFunctionKeyCallback(functionKey); +} + +void InputMethodTextChangedListener::MoveCursor(const Direction direction) +{ + InputMethodControllerImpl::GetInstance()->MoveCursorCallback(direction); +} + +void InputMethodTextChangedListener::HandleExtendAction(int32_t action) +{ + InputMethodControllerImpl::GetInstance()->HandleExtendActionCallback(action); +} + +std::u16string InputMethodTextChangedListener::GetLeftTextOfCursor(int32_t number) +{ + return InputMethodControllerImpl::GetInstance()->GetLeftTextOfCursorCallback(number); +} + +std::u16string InputMethodTextChangedListener::GetRightTextOfCursor(int32_t number) +{ + return InputMethodControllerImpl::GetInstance()->GetRightTextOfCursorCallback(number); +} + +int32_t InputMethodTextChangedListener::GetTextIndexAtCursor() +{ + return InputMethodControllerImpl::GetInstance()->GetTextIndexAtCursorCallback(); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp new file mode 100644 index 000000000..cf3b2351f --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp @@ -0,0 +1,115 @@ +#include "ohos.inputMethod.proj.hpp" +#include "ohos.inputMethod.impl.hpp" +#include "taihe/runtime.hpp" +#include "stdexcept" +#include "input_method_controller_impl.h" +#include "input_method_setting_impl.h" +#include "input_method_controller.h" +#include "ani_common.h" +#include "js_utils.h" + +using namespace taihe; +using namespace ohos::inputMethod; +using namespace ohos::inputMethodSubtype; +using namespace OHOS::MiscServices; +namespace { +InputMethodSetting GetSetting() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +ohos::inputMethod::InputMethodController GetController() { + // The parameters in the make_holder function should be of the same type + // as the parameters in the constructor of the actual implementation class. + return make_holder(); +} + +InputMethodProperty GetDefaultInputMethod() { + InputMethodProperty inputMethodProperty{}; + std::shared_ptr property; + int32_t ret = OHOS::MiscServices::InputMethodController::GetInstance()->GetDefaultInputMethod(property); + if (ret != ErrorCode::NO_ERROR) { + taihe::set_business_error(JsUtils::Convert(ret), "failed to get default input method!"); + return inputMethodProperty; + } + inputMethodProperty = PropertyConverter::ConvertProperty(property); + return inputMethodProperty; +} + +InputMethodProperty GetCurrentInputMethod() { + InputMethodProperty inputMethodProperty{}; + std::shared_ptr property = OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethod(); + if (property == nullptr) { + IMSA_HILOGE("current input method is nullptr!"); + return inputMethodProperty; + } + inputMethodProperty = PropertyConverter::ConvertProperty(property); + return inputMethodProperty; +} + +InputMethodSubtype GetCurrentInputMethodSubtype() { + InputMethodSubtype inputMethodSubtype{}; + std::shared_ptr subProperty = OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); + if (subProperty == nullptr) { + IMSA_HILOGE("current input method subtype is nullptr!"); + return inputMethodSubtype; + } + inputMethodSubtype = PropertyConverter::ConvertSubProperty(subProperty); + return inputMethodSubtype; +} + +uintptr_t GetSystemInputMethodConfigAbility() { + TH_THROW(std::runtime_error, "GetSystemInputMethodConfigAbility not implemented"); +} + +bool SwitchInputMethodWithTarget(InputMethodProperty const& target) { + std::string packageName(target.name); + std::string id(target.id); + if (packageName.empty() || id.empty()) { + packageName = target.packageName; + id = target.methodId; + } + int32_t errCode = + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, packageName, id); + if (errCode != ErrorCode::NO_ERROR) { + taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + return false; + } + return true; +} + +void SwitchInputMethodSync(string_view bundleName, optional_view subtypeId) { + std::string id; + if (subtypeId.has_value()) { + id = subtypeId.value(); + } + int32_t errCode = + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::SYSTEM_APP, std::string(bundleName), id); + if (errCode != ErrorCode::NO_ERROR) { + taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + } +} + +bool SwitchCurrentInputMethodSubtypeSync(InputMethodProperty const& target) { + std::string name(target.name); + std::string id(target.id); + int32_t errCode = + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, name, id); + if (errCode != ErrorCode::NO_ERROR) { + taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + return false; + } + return true; +} +} // namespace + +TH_EXPORT_CPP_API_GetSetting(GetSetting); +TH_EXPORT_CPP_API_GetController(GetController); +TH_EXPORT_CPP_API_GetDefaultInputMethod(GetDefaultInputMethod); +TH_EXPORT_CPP_API_GetCurrentInputMethod(GetCurrentInputMethod); +TH_EXPORT_CPP_API_GetCurrentInputMethodSubtype(GetCurrentInputMethodSubtype); +TH_EXPORT_CPP_API_GetSystemInputMethodConfigAbility(GetSystemInputMethodConfigAbility); +TH_EXPORT_CPP_API_SwitchInputMethodWithTarget(SwitchInputMethodWithTarget); +TH_EXPORT_CPP_API_SwitchInputMethodSync(SwitchInputMethodSync); +TH_EXPORT_CPP_API_SwitchCurrentInputMethodSubtypeSync(SwitchCurrentInputMethodSubtypeSync); -- Gitee From 204c2925baee0fbeccc45d2c245c92673d7d9809 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Wed, 30 Apr 2025 18:37:36 +0800 Subject: [PATCH 2/9] fix: codecheck Signed-off-by: weishaoxiong --- bundle.json | 2 +- frameworks/ets/taihe/inputMethod/BUILD.gn | 2 + .../inputMethod/idl/ohos.elementName.taihe | 17 ++ .../idl/ohos.inputMethod.Panel.taihe | 15 ++ .../inputMethod/idl/ohos.inputMethod.taihe | 39 +++-- .../idl/ohos.inputMethodSubtype.taihe | 15 ++ .../taihe/inputMethod/include/ani_common.h | 122 ++++++++------ .../include/input_method_controller_impl.h | 125 +++++++++------ .../include/input_method_event_listener.h | 6 +- .../include/input_method_setting_impl.h | 80 ++++++---- .../input_method_text_changed_listener.h | 107 +++++++------ .../taihe/inputMethod/src/ani_constructor.cpp | 5 +- .../src/input_method_controller_impl.cpp | 150 ++++++++++-------- .../src/input_method_event_listener.cpp | 5 +- .../src/input_method_setting_impl.cpp | 142 +++++++++-------- .../input_method_text_changed_listener.cpp | 1 + .../inputMethod/src/ohos.inputMethod.impl.cpp | 104 ++++++++---- 17 files changed, 576 insertions(+), 361 deletions(-) create mode 100644 frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe diff --git a/bundle.json b/bundle.json index 12baa05e2..c3add9d00 100644 --- a/bundle.json +++ b/bundle.json @@ -71,7 +71,7 @@ "//base/inputmethod/imf/frameworks/js/napi/inputmethodlist:inputmethodlist", "//base/inputmethod/imf/frameworks/js/napi/inputmethodpanel:panel", "//base/inputmethod/imf/frameworks/ndk:ohinputmethod", - "//base/inputmethod/imf/frameworks/ets/taihe/inputMethod:inputmethod_taihe_native" + "//base/inputmethod/imf/frameworks/ets/taihe/inputMethod:inputmethod_taihe" ], "service_group": [ "//base/inputmethod/imf/etc/init:inputmethodservice.cfg", diff --git a/frameworks/ets/taihe/inputMethod/BUILD.gn b/frameworks/ets/taihe/inputMethod/BUILD.gn index 21e1ff861..fc7b95e17 100644 --- a/frameworks/ets/taihe/inputMethod/BUILD.gn +++ b/frameworks/ets/taihe/inputMethod/BUILD.gn @@ -22,6 +22,7 @@ taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" copy_taihe_idl("copy_taihe") { sources = [ + "idl/ohos.elementName.taihe", "idl/ohos.inputMethod.Panel.taihe", "idl/ohos.inputMethod.taihe", "idl/ohos.inputMethodSubtype.taihe" @@ -80,6 +81,7 @@ taihe_shared_library("inputmethod_taihe_native") { "ability_base:want", "ability_runtime:abilitykit_native", "ability_runtime:extensionkit_native", + "bundle_framework:bms_ani_common", "c_utils:utils", "eventhandler:libeventhandler", "ffrt:libffrt", diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe new file mode 100644 index 000000000..173ce4fab --- /dev/null +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@!sts_inject("import {ElementName} from 'bundleManager.ElementName';") +@!namespace("@ohos.inputMethod") \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe index ff509ff8b..25488e3a9 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.Panel.taihe @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @!namespace("@ohos.inputMethod.Panel") enum PanelFlag: i32 { FLAG_FIXED = 0, diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index 0abef1f69..b736de6e1 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @!namespace("@ohos.inputMethod", "inputMethod") from ohos.inputMethod.Panel use PanelInfo; from ohos.inputMethodSubtype use InputMethodSubtype; @@ -25,7 +40,7 @@ struct InputWindowInfo { interface InputMethodSetting { @gen_async("getInputMethods") @gen_promise("getInputMethods") - GetInputMethodSync(enable: bool): Array; + GetInputMethosdSync(enable: bool): Array; @gen_async("listCurrentInputMethodSubtype") @gen_promise("listCurrentInputMethodSubtype") ListCurrentInputMethodSubtypeSync(): Array; @@ -40,7 +55,7 @@ interface InputMethodSetting { on(type: string, cb: Object) { switch(type) { case "imeHide": return this.onImeHide(cb as (info: Array) => void, cb); - case "imeShow": return this.onImeShow(cb as (info: Array) => void, cb); + case "imeShow": return this.onImeShow(cb as (info: Array) => void, cb); case "imeChange": return this.onImeChange(cb as (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_inputMethodSubtype.InputMethodSubtype) => void, cb); default: throw new Error(`Unknown type: ${type}`); } @@ -48,7 +63,7 @@ interface InputMethodSetting { off(type: string, cb?: Object) { switch(type) { case "imeHide": return this.offImeHide(cb); - case "imeShow": return this.offImeShow(cb); + case "imeShow": return this.offImeShow(cb); case "imeChange": return this.offImeChange(cb); default: throw new Error(`Unknown type: ${type}`); } @@ -173,17 +188,18 @@ interface InputMethodController { case "selectByRange": return this.onSelectByRange(cb as (range : Range) => void, cb); case "selectByMovement": return this.onSelectByMovement(cb as (movement : Movement) => void, cb); case "insertText": return this.onInsertText(cb as (text: String) => void, cb); - case "deleteLeft": return this.onDeleteLeft(cb as (length: i32) => void, cb); - case "deleteRight": return this.onDeleteRight(cb as (length: i32) => void, cb); + case "deleteLeft": return this.onDeleteLeft(cb as (length: int) => void, cb); + case "deleteRight": return this.onDeleteRight(cb as (length: int) => void, cb); case "sendKeyboardStatus": return this.onSendKeyboardStatus(cb as (keyboardStatus: KeyboardStatus) => void, cb); case "sendFunctionKey": return this.onSendFunctionKey(cb as (functionKey: FunctionKey) => void, cb); case "moveCursor": return this.onMoveCursor(cb as (direction: Direction) => void, cb); - case "handleExtendSelection": return this.onHandleExtendSelection(cb as (extendAction: ExtendAction) => void, cb); - case "getLeftTextOfCursor": return this.onGetLeftTextOfCursor(cb as (length: i32) => void, cb); - case "getRightTextOfCursor": return this.onGetRightTextOfCursor(cb as (length: i32) => void, cb); - case "getTextIndexAtCursor": return this.onGetTextIndexAtCursor(cb as () => i32, cb); + case "handleExtendAction": return this.onHandleExtendAction(cb as (extendAction: ExtendAction) => void, cb); + case "getLeftTextOfCursor": return this.onGetLeftTextOfCursor(cb as (length: int) => void, cb); + case "getRightTextOfCursor": return this.onGetRightTextOfCursor(cb as (length: int) => void, cb); + case "getTextIndexAtCursor": return this.onGetTextIndexAtCursor(cb as () => int, cb); default: throw new Error(`Unknown type: ${type}`); } + } off(type: string, cb?: Object) { switch(type) { case "selectByRange": return this.offSelectByRange(cb); @@ -194,14 +210,13 @@ interface InputMethodController { case "sendKeyboardStatus": return this.offSendKeyboardStatus(cb); case "sendFunctionKey": return this.offSendFunctionKey(cb); case "moveCursor": return this.offMoveCursor(cb); - case "handleExtendSelection": return this.offHandleExtendSelection(cb); + case "handleExtendAction": return this.offHandleExtendAction(cb); case "getLeftTextOfCursor": return this.offGetLeftTextOfCursor(cb); case "getRightTextOfCursor": return this.offGetRightTextOfCursor(cb); case "getTextIndexAtCursor": return this.offGetTextIndexAtCursor(cb); default: throw new Error(`Unknown type: ${type}`); } } - } """) OnSelectByRange(f: (range : Range) => void, opq: Opaque); OffSelectByRange(opq: Optional); @@ -234,7 +249,7 @@ function GetController(): InputMethodController; function GetDefaultInputMethod(): InputMethodProperty; function GetCurrentInputMethod(): InputMethodProperty; function GetCurrentInputMethodSubtype(): InputMethodSubtype; -function GetSystemInputMethodConfigAbility(): Opaque; +function GetSystemInputMethodConfigAbility(): @sts_type("ElementName") Opaque; @gen_async("switchInputMethod") @gen_promise("switchInputMethod") function SwitchInputMethodWithTarget(target: InputMethodProperty): bool; diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe index fc85da497..04ffff53e 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + @!namespace("@ohos.inputMethodSubtype") struct InputMethodSubtype { @readonly name: String; diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h index 2163ae51e..bfeb78d34 100644 --- a/frameworks/ets/taihe/inputMethod/include/ani_common.h +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -16,11 +16,11 @@ #ifndef INPUT_METHOD_TAIHE_ANI_COMMON_H #define INPUT_METHOD_TAIHE_ANI_COMMON_H -#include "ohos.inputMethod.proj.hpp" -#include "ohos.inputMethod.impl.hpp" #include "input_method_property.h" -#include "taihe/runtime.hpp" #include "input_method_utils.h" +#include "ohos.inputMethod.impl.hpp" +#include "ohos.inputMethod.proj.hpp" +#include "taihe/runtime.hpp" using InputMethodProperty_t = ohos::inputMethod::InputMethodProperty; using InputMethodSubtype_t = ohos::inputMethodSubtype::InputMethodSubtype; using PanelInfo_t = ohos::inputMethod::Panel::PanelInfo; @@ -36,30 +36,39 @@ using EnterKeyType_t = ohos::inputMethod::EnterKeyType; using Direction_t = ohos::inputMethod::Direction; namespace OHOS { namespace MiscServices { +constexpr const int32_t SELECT_ALL = 0; +constexpr const int32_t CUT = 3; +constexpr const int32_t COPY = 4; +constexpr const int32_t PASTE = 5; + class PropertyConverter { public: - static InputMethodProperty_t ConvertProperty(const std::shared_ptr& obj) { + static InputMethodProperty_t ConvertProperty(const std::shared_ptr &obj) + { return ConvertPropertyImpl(*obj); } - static InputMethodProperty_t ConvertProperty(const Property& obj) { + static InputMethodProperty_t ConvertProperty(const Property &obj) + { return ConvertPropertyImpl(obj); } - - static InputMethodSubtype_t ConvertSubProperty(const std::shared_ptr& obj) { + static InputMethodSubtype_t ConvertSubProperty(const std::shared_ptr &obj) + { return ConvertSubPropertyImpl(*obj); } - static InputMethodSubtype_t ConvertSubProperty(const SubProperty& obj) { + static InputMethodSubtype_t ConvertSubProperty(const SubProperty &obj) + { return ConvertSubPropertyImpl(obj); } private: template - static InputMethodProperty_t ConvertPropertyImpl(T&& obj) { + static InputMethodProperty_t ConvertPropertyImpl(T &&obj) + { static_assert(std::is_same_v, Property>, "Invalid type for Property conversion"); - + InputMethodProperty_t result{}; result.packageName = std::forward(obj).name; result.name = std::forward(obj).name; @@ -73,9 +82,9 @@ private: } template - static InputMethodSubtype_t ConvertSubPropertyImpl(T&& obj) { - static_assert(std::is_same_v, SubProperty>, - "Invalid type for SubProperty conversion"); + static InputMethodSubtype_t ConvertSubPropertyImpl(T &&obj) + { + static_assert(std::is_same_v, SubProperty>, "Invalid type for SubProperty conversion"); InputMethodSubtype_t result{}; result.name = std::forward(obj).name; @@ -90,27 +99,22 @@ private: } }; -using callbackType = std::variant< - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback, - taihe::callback)>, - taihe::callback>; +using callbackType = std::variant, taihe::callback, + taihe::callback, taihe::callback, taihe::callback, + taihe::callback, taihe::callback, + taihe::callback, taihe::callback, + taihe::callback, taihe::callback, + taihe::callback, taihe::callback)>, + taihe::callback>; struct CallbackObject { - CallbackObject(callbackType cb, ani_ref ref): callback(cb), ref(ref) {} - ~CallbackObject() { - if (auto* env = taihe::get_env()) { - env->GlobalReference_Delete(ref); + CallbackObject(callbackType cb, ani_ref ref) : callback(cb), ref(ref) + { + } + ~CallbackObject() + { + if (auto *env = taihe::get_env()) { + env->GlobalReference_Delete(ref); } } callbackType callback; @@ -118,30 +122,41 @@ struct CallbackObject { }; class GlobalRefGuard { - ani_env* env_ = nullptr; + ani_env *env_ = nullptr; ani_ref ref_ = nullptr; + public: - GlobalRefGuard(ani_env* env, ani_object obj) : env_(env) { - if (!env_) return; + GlobalRefGuard(ani_env *env, ani_object obj) : env_(env) + { + if (!env_) + return; if (ANI_OK != env_->GlobalReference_Create(obj, &ref_)) { ref_ = nullptr; } } - explicit operator bool() const { return ref_ != nullptr; } - ani_ref get() const { return ref_; } - ~GlobalRefGuard() { + explicit operator bool() const + { + return ref_ != nullptr; + } + ani_ref get() const + { + return ref_; + } + ~GlobalRefGuard() + { if (env_ && ref_) { env_->GlobalReference_Delete(ref_); } } - - GlobalRefGuard(const GlobalRefGuard&) = delete; - GlobalRefGuard& operator=(const GlobalRefGuard&) = delete; + + GlobalRefGuard(const GlobalRefGuard &) = delete; + GlobalRefGuard &operator=(const GlobalRefGuard &) = delete; }; class EnumConvert { public: - static Direction_t ConvertDirection(Direction direction) { + static Direction_t ConvertDirection(Direction direction) + { switch (direction) { case Direction::UP: return Direction_t::key_t::CURSOR_UP; @@ -156,22 +171,24 @@ public: } } - static ExtendAction_t ConvertExtendAction(int32_t action) { + static ExtendAction_t ConvertExtendAction(int32_t action) + { switch (action) { - case 0: + case SELECT_ALL: return ExtendAction_t::key_t::SELECT_ALL; - case 3: + case CUT: return ExtendAction_t::key_t::CUT; - case 4: + case COPY: return ExtendAction_t::key_t::COPY; - case 5: + case PASTE: return ExtendAction_t::key_t::PASTE; default: return ExtendAction_t::key_t::SELECT_ALL; } } - static EnterKeyType_t ConvertEnterKeyType(EnterKeyType type) { + static EnterKeyType_t ConvertEnterKeyType(EnterKeyType type) + { switch (type) { case EnterKeyType::UNSPECIFIED: return EnterKeyType_t::key_t::UNSPECIFIED; @@ -196,8 +213,11 @@ public: } } - static KeyboardStatus_t ConvertKeyboardStatus(KeyboardStatus status) { + static KeyboardStatus_t ConvertKeyboardStatus(KeyboardStatus status) + { switch (status) { + case KeyboardStatus::NONE: + return KeyboardStatus_t::key_t::NONE; case KeyboardStatus::SHOW: return KeyboardStatus_t::key_t::SHOW; case KeyboardStatus::HIDE: @@ -207,6 +227,6 @@ public: } } }; -} -} +} // namespace MiscServices +} // namespace OHOS #endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h index d372f387b..7d915d0ad 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h @@ -14,16 +14,17 @@ */ #ifndef TAIHE_INPUT_METHOD_CONTROLLER_IMPL_H #define TAIHE_INPUT_METHOD_CONTROLLER_IMPL_H -#include "ohos.inputMethod.proj.hpp" -#include "ohos.inputMethod.impl.hpp" -#include "input_method_utils.h" -#include "controller_listener.h" -#include "ani_common.h" #include -#include +#include #include +#include #include -#include + +#include "ani_common.h" +#include "controller_listener.h" +#include "input_method_utils.h" +#include "ohos.inputMethod.impl.hpp" +#include "ohos.inputMethod.proj.hpp" namespace OHOS { namespace MiscServices { class InputMethodControllerImpl : public ControllerListener { @@ -33,11 +34,12 @@ public: void ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason); void ShowTextInputSync(); void HideTextInputSync(); - void AttachSync(bool showKeyboard, TextConfig_t const& textConfig); - void AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason); + void AttachSync(bool showKeyboard, TextConfig_t const &textConfig); + void AttachWithReason(bool showKeyboard, TextConfig_t const &textConfig, + RequestKeyboardReason_t requestKeyboardReason); void DetachSync(); - void RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq); - void UnRegisterListener(std::string const& type, taihe::optional_view opq); + void RegisterListener(std::string const &type, callbackType &&cb, uintptr_t opq); + void UnRegisterListener(std::string const &type, taihe::optional_view opq); void InsertTextCallback(const std::u16string &text); void DeleteLeftCallback(int32_t length); @@ -52,109 +54,142 @@ public: void OnSelectByRange(int32_t start, int32_t end) override; void OnSelectByMovement(int32_t direction) override; + private: std::mutex mutex_; - std::map> jsCbMap_; + std::map>> jsCbMap_; static std::mutex controllerMutex_; static std::shared_ptr controller_; }; class IMFControllerImpl { public: - void HideSoftKeyboardSync() { + void HideSoftKeyboardSync() + { InputMethodControllerImpl::GetInstance()->HideSoftKeyboardSync(); } - void ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason) { + void ShowTextInputHasParam(RequestKeyboardReason_t requestKeyboardReason) + { InputMethodControllerImpl::GetInstance()->ShowTextInputHasParam(requestKeyboardReason); } - void ShowTextInputSync() { + void ShowTextInputSync() + { InputMethodControllerImpl::GetInstance()->ShowTextInputSync(); } - void HideTextInputSync() { + void HideTextInputSync() + { InputMethodControllerImpl::GetInstance()->HideTextInputSync(); } - void AttachSync(bool showKeyboard, TextConfig_t const& textConfig) { + void AttachSync(bool showKeyboard, TextConfig_t const &textConfig) + { InputMethodControllerImpl::GetInstance()->AttachSync(showKeyboard, textConfig); } - void AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason) { + void AttachWithReason(bool showKeyboard, TextConfig_t const &textConfig, + RequestKeyboardReason_t requestKeyboardReason) + { InputMethodControllerImpl::GetInstance()->AttachWithReason(showKeyboard, textConfig, requestKeyboardReason); } - void DetachSync() { + void DetachSync() + { InputMethodControllerImpl::GetInstance()->DetachSync(); } - void OnSelectByRange(taihe::callback_view f, uintptr_t opq) { + void OnSelectByRange(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("selectByRange", f, opq); } - void OffSelectByRange(taihe::optional_view opq) { + void OffSelectByRange(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("selectByRange", opq); } - void OnSelectByMovement(taihe::callback_view f, uintptr_t opq) { + void OnSelectByMovement(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("selectByMovement", f, opq); } - void OffSelectByMovement(taihe::optional_view opq) { + void OffSelectByMovement(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("selectByMovement", opq); } - void OnInsertText(taihe::callback_view f, uintptr_t opq) { + void OnInsertText(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("insertText", f, opq); } - void OffInsertText(taihe::optional_view opq) { + void OffInsertText(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("insertText", opq); } - void OnDeleteLeft(taihe::callback_view f, uintptr_t opq) { + void OnDeleteLeft(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("deleteLeft", f, opq); } - void OffDeleteLeft(taihe::optional_view opq) { + void OffDeleteLeft(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("deleteLeft", opq); } - void OnDeleteRight(taihe::callback_view f, uintptr_t opq) { + void OnDeleteRight(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("deleteRight", f, opq); } - void OffDeleteRight(taihe::optional_view opq) { + void OffDeleteRight(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("deleteRight", opq); } - void OnSendKeyboardStatus(taihe::callback_view f, uintptr_t opq) { + void OnSendKeyboardStatus(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("sendKeyboardStatus", f, opq); } - void OffSendKeyboardStatus(taihe::optional_view opq) { + void OffSendKeyboardStatus(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("sendKeyboardStatus", opq); } - void OnSendFunctionKey(taihe::callback_view f, uintptr_t opq) { + void OnSendFunctionKey(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("sendFunctionKey", f, opq); } - void OffSendFunctionKey(taihe::optional_view opq) { + void OffSendFunctionKey(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("sendFunctionKey", opq); } - void OnMoveCursor(taihe::callback_view f, uintptr_t opq) { + void OnMoveCursor(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("moveCursor", f, opq); } - void OffMoveCursor(taihe::optional_view opq) { + void OffMoveCursor(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("moveCursor", opq); } - void OnHandleExtendAction(taihe::callback_view f, uintptr_t opq) { + void OnHandleExtendAction(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("handleExtendAction", f, opq); } - void OffHandleExtendAction(taihe::optional_view opq) { + void OffHandleExtendAction(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("handleExtendAction", opq); } - void OnGetLeftTextOfCursor(taihe::callback_view f, uintptr_t opq) { + void OnGetLeftTextOfCursor(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("getLeftTextOfCursor", f, opq); } - void OffGetLeftTextOfCursor(taihe::optional_view opq) { + void OffGetLeftTextOfCursor(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("getLeftTextOfCursor", opq); } - void OnGetRightTextOfCursor(taihe::callback_view f, uintptr_t opq) { + void OnGetRightTextOfCursor(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("getRightTextOfCursor", f, opq); } - void OffGetRightTextOfCursor(taihe::optional_view opq) { + void OffGetRightTextOfCursor(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("getRightTextOfCursor", opq); } - void OnGetTextIndexAtCursor(taihe::callback_view f, uintptr_t opq) { + void OnGetTextIndexAtCursor(taihe::callback_view f, uintptr_t opq) + { InputMethodControllerImpl::GetInstance()->RegisterListener("getTextIndexAtCursor", f, opq); } - void OffGetTextIndexAtCursor(taihe::optional_view opq) { + void OffGetTextIndexAtCursor(taihe::optional_view opq) + { InputMethodControllerImpl::GetInstance()->UnRegisterListener("getTextIndexAtCursor", opq); } }; -} -} +} // namespace MiscServices +} // namespace OHOS #endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h b/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h index ba26faf5b..f3fd40690 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_event_listener.h @@ -17,13 +17,13 @@ #define FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_EVENT_LISTENER_H #include "ani_common.h" +#include "ime_event_listener.h" #include "input_method_property.h" #include "input_window_info.h" -#include "ime_event_listener.h" namespace OHOS { namespace MiscServices { -class InputMethodEventListener: public ImeEventListener { +class InputMethodEventListener : public ImeEventListener { public: InputMethodEventListener() = default; ~InputMethodEventListener() = default; @@ -31,6 +31,7 @@ public: void OnImeChange(const Property &property, const SubProperty &subProperty); void OnImeShow(const ImeWindowInfo &info); void OnImeHide(const ImeWindowInfo &info); + private: static std::mutex listenerMutex_; static std::shared_ptr inputMethodListener_; @@ -39,4 +40,3 @@ private: } // namespace OHOS #endif // FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_EVENT_LISTENER_H - \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h index 7d75f3fab..5a3dc76c0 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h @@ -14,78 +14,94 @@ */ #ifndef TAIHE_INPUT_METHOD_SETTING_IMPL_H #define TAIHE_INPUT_METHOD_SETTING_IMPL_H -#include "ohos.inputMethod.proj.hpp" -#include "ohos.inputMethod.impl.hpp" -#include "input_window_info.h" -#include "ime_event_listener.h" -#include "ani_common.h" -#include #include +#include #include + +#include "ani_common.h" +#include "ime_event_listener.h" +#include "input_window_info.h" +#include "ohos.inputMethod.impl.hpp" +#include "ohos.inputMethod.proj.hpp" namespace OHOS { namespace MiscServices { class InputMethodSettingImpl { public: - static InputMethodSettingImpl& GetInstance(); - taihe::array GetInputMethodSync(bool enable); + static InputMethodSettingImpl &GetInstance(); + taihe::array GetInputMethosdSync(bool enable); taihe::array ListCurrentInputMethodSubtypeSync(); - taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty); - bool IsPanelShown(PanelInfo_t const& panelInfo); + taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const &inputMethodProperty); + bool IsPanelShown(PanelInfo_t const &panelInfo); taihe::array GetAllInputMethodsSync(); void OnImeChangeCallback(const Property &property, const SubProperty &subProperty); void OnImeShowCallback(const ImeWindowInfo &info); void OnImeHideCallback(const ImeWindowInfo &info); - void RegisterImeEvent(std::string const& eventName, int32_t eventMask, callbackType&& f, uintptr_t opq); - void UnregisterImeEvent(std::string const& eventName, int32_t eventMask, taihe::optional_view opq); + void RegisterImeEvent(std::string const &eventName, int32_t eventMask, callbackType &&f, uintptr_t opq); + void UnregisterImeEvent(std::string const &eventName, int32_t eventMask, taihe::optional_view opq); + private: PanelFlag softKbShowingFlag_{ FLG_CANDIDATE_COLUMN }; PanelFlag GetSoftKbShowingFlag(); void SetSoftKbShowingFlag(PanelFlag flag); - void OnPanelStatusChange(std::string const& type, const InputWindowInfo &info); - void RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq); - void UnregisterListener(std::string const& type, taihe::optional_view opq, bool& isUpdateFlag); - void HandleRegistrationError(std::string const& eventName, int32_t errorCode); + void OnPanelStatusChange(std::string const &type, const InputWindowInfo &info); + void RegisterListener(std::string const &type, callbackType &&cb, uintptr_t opq); + void UnregisterListener(std::string const &type, taihe::optional_view opq, bool &isUpdateFlag); + void HandleRegistrationError(std::string const &eventName, int32_t errorCode); std::mutex mutex_; - std::map> jsCbMap_; + std::map>> jsCbMap_; }; class IMFSettingImpl { public: - IMFSettingImpl() {} - taihe::array GetInputMethodSync(bool enable) { - return InputMethodSettingImpl::GetInstance().GetInputMethodSync(enable); + IMFSettingImpl() + { + } + taihe::array GetInputMethosdSync(bool enable) + { + return InputMethodSettingImpl::GetInstance().GetInputMethosdSync(enable); } - taihe::array ListCurrentInputMethodSubtypeSync() { + taihe::array ListCurrentInputMethodSubtypeSync() + { return InputMethodSettingImpl::GetInstance().ListCurrentInputMethodSubtypeSync(); } - taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty) { + taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const &inputMethodProperty) + { return InputMethodSettingImpl::GetInstance().ListInputMethodSubtypeSync(inputMethodProperty); } - bool IsPanelShown(PanelInfo_t const& panelInfo) { + bool IsPanelShown(PanelInfo_t const &panelInfo) + { return InputMethodSettingImpl::GetInstance().IsPanelShown(panelInfo); } - taihe::array GetAllInputMethodsSync() { + taihe::array GetAllInputMethodsSync() + { return InputMethodSettingImpl::GetInstance().GetAllInputMethodsSync(); } - void OnImeHide(taihe::callback_view)> f, uintptr_t opq) { + void OnImeHide(taihe::callback_view)> f, uintptr_t opq) + { InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeHide", EVENT_IME_HIDE_MASK, f, opq); } - void OffImeHide(taihe::optional_view opq) { + void OffImeHide(taihe::optional_view opq) + { InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeHide", EVENT_IME_HIDE_MASK, opq); } - void OnImeShow(taihe::callback_view)> f, uintptr_t opq) { + void OnImeShow(taihe::callback_view)> f, uintptr_t opq) + { InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeShow", EVENT_IME_SHOW_MASK, f, opq); } - void OffImeShow(taihe::optional_view opq) { + void OffImeShow(taihe::optional_view opq) + { InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeShow", EVENT_IME_SHOW_MASK, opq); } - void OnImeChange(taihe::callback_view f, uintptr_t opq) { + void OnImeChange(taihe::callback_view f, + uintptr_t opq) + { InputMethodSettingImpl::GetInstance().RegisterImeEvent("imeChange", EVENT_IME_CHANGE_MASK, f, opq); } - void OffImeChange(taihe::optional_view opq) { + void OffImeChange(taihe::optional_view opq) + { InputMethodSettingImpl::GetInstance().UnregisterImeEvent("imeChange", EVENT_IME_CHANGE_MASK, opq); } }; -} -} +} // namespace MiscServices +} // namespace OHOS #endif \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h b/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h index a2e5b6a7c..777372266 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_text_changed_listener.h @@ -12,53 +12,60 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H - #define FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H - - #include "input_method_controller.h" - namespace OHOS { - namespace MiscServices { - class InputMethodTextChangedListener : public OnTextChangedListener { - public: - InputMethodTextChangedListener() = default; - ~InputMethodTextChangedListener() = default; - static sptr GetInstance(); - - void InsertText(const std::u16string &text) override; - void DeleteForward(int32_t length) override; - void DeleteBackward(int32_t length) override; - void SendKeyEventFromInputMethod(const KeyEvent &event) override - { - } - void SendKeyboardStatus(const KeyboardStatus &status) override; - void SendFunctionKey(const FunctionKey &functionKey) override; - void SetKeyboardStatus(bool status) override - { - } - void MoveCursor(const Direction direction) override; - void HandleSetSelection(int32_t start, int32_t end) override - { - } - void HandleExtendAction(int32_t action) override; - void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override - { - } - std::u16string GetLeftTextOfCursor(int32_t number) override; - std::u16string GetRightTextOfCursor(int32_t number) override; - int32_t GetTextIndexAtCursor() override; - int32_t ReceivePrivateCommand(const std::unordered_map &privateCommand) override - { return 0; } - bool IsFromTs() override - { return false; } - int32_t SetPreviewText(const std::u16string &text, const Range &range) override - { return 0; } - void FinishTextPreview() override - {} - - private: - static std::mutex listenerMutex_; - static sptr inputMethodListener_; - }; - } // namespace MiscServices - } // namespace OHOS - #endif // FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGE_LISTENER_H \ No newline at end of file +#ifndef FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H +#define FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGED_LISTENER_H + +#include "input_method_controller.h" +namespace OHOS { +namespace MiscServices { +class InputMethodTextChangedListener : public OnTextChangedListener { +public: + InputMethodTextChangedListener() = default; + ~InputMethodTextChangedListener() = default; + static sptr GetInstance(); + + void InsertText(const std::u16string &text) override; + void DeleteForward(int32_t length) override; + void DeleteBackward(int32_t length) override; + void SendKeyEventFromInputMethod(const KeyEvent &event) override + { + } + void SendKeyboardStatus(const KeyboardStatus &status) override; + void SendFunctionKey(const FunctionKey &functionKey) override; + void SetKeyboardStatus(bool status) override + { + } + void MoveCursor(const Direction direction) override; + void HandleSetSelection(int32_t start, int32_t end) override + { + } + void HandleExtendAction(int32_t action) override; + void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override + { + } + std::u16string GetLeftTextOfCursor(int32_t number) override; + std::u16string GetRightTextOfCursor(int32_t number) override; + int32_t GetTextIndexAtCursor() override; + int32_t ReceivePrivateCommand(const std::unordered_map &privateCommand) override + { + return 0; + } + bool IsFromTs() override + { + return false; + } + int32_t SetPreviewText(const std::u16string &text, const Range &range) override + { + return 0; + } + void FinishTextPreview() override + { + } + +private: + static std::mutex listenerMutex_; + static sptr inputMethodListener_; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // FRAMEWORKS_ETS_TAIHE_INPUT_METHOD_TEXT_CHANGE_LISTENER_H \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp index 56dc199d2..8b2c78e28 100644 --- a/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp +++ b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp @@ -13,10 +13,11 @@ * limitations under the License. */ +#include "ohos.inputMethod.Panel.ani.hpp" #include "ohos.inputMethod.ani.hpp" #include "ohos.inputMethodSubtype.ani.hpp" -#include "ohos.inputMethod.Panel.ani.hpp" -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ ani_env *env; if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { return ANI_ERROR; diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp index 9c86e745a..e28c871cd 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -13,20 +13,22 @@ * limitations under the License. */ #include "input_method_controller_impl.h" -#include "input_method_text_changed_listener.h" -#include "taihe/runtime.hpp" -#include "stdexcept" -#include "input_method_controller.h" + +#include + #include "ani_common.h" +#include "input_method_controller.h" +#include "input_method_text_changed_listener.h" #include "js_utils.h" -#include +#include "stdexcept" #include "string_ex.h" +#include "taihe/runtime.hpp" namespace OHOS { namespace MiscServices { using namespace taihe; std::mutex InputMethodControllerImpl::controllerMutex_; -std::shared_ptr InputMethodControllerImpl::controller_ { nullptr }; +std::shared_ptr InputMethodControllerImpl::controller_{ nullptr }; std::shared_ptr InputMethodControllerImpl::GetInstance() { if (controller_ == nullptr) { @@ -45,6 +47,7 @@ void InputMethodControllerImpl::HideSoftKeyboardSync() int32_t errCode = InputMethodController::GetInstance()->HideSoftKeyboard(); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("InputMethodController::HideSoftKeyboard failed, errCode: %{public}d!", errCode); } } @@ -55,6 +58,7 @@ void InputMethodControllerImpl::ShowTextInputHasParam(RequestKeyboardReason_t re int32_t errCode = InputMethodController::GetInstance()->ShowTextInput(attachOptions, ClientType::JS); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("InputMethodController::ShowTextInput failed, errCode: %{public}d!", errCode); } } @@ -68,15 +72,17 @@ void InputMethodControllerImpl::HideTextInputSync() int32_t errCode = InputMethodController::GetInstance()->HideTextInput(); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("InputMethodController::HideTextInput failed, errCode: %{public}d!", errCode); } } -void InputMethodControllerImpl::AttachSync(bool showKeyboard, TextConfig_t const& textConfig) +void InputMethodControllerImpl::AttachSync(bool showKeyboard, TextConfig_t const &textConfig) { AttachWithReason(showKeyboard, textConfig, RequestKeyboardReason_t::key_t::NONE); } -void InputMethodControllerImpl::AttachWithReason(bool showKeyboard, TextConfig_t const& textConfig, RequestKeyboardReason_t requestKeyboardReason) +void InputMethodControllerImpl::AttachWithReason(bool showKeyboard, TextConfig_t const &textConfig, + RequestKeyboardReason_t requestKeyboardReason) { AttachOptions attachOptions; attachOptions.isShowKeyboard = showKeyboard; @@ -91,11 +97,12 @@ void InputMethodControllerImpl::AttachWithReason(bool showKeyboard, TextConfig_t config.range.start = textConfig.selection.start; config.range.end = textConfig.selection.end; config.windowId = textConfig.windowId; - // TODO isTextPreviewSupported - int32_t errCode = InputMethodController::GetInstance()->Attach(InputMethodTextChangedListener::GetInstance(), attachOptions, config, ClientType::JS); + int32_t errCode = InputMethodController::GetInstance()->Attach(InputMethodTextChangedListener::GetInstance(), + attachOptions, config, ClientType::JS); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("InputMethodController::Attach failed, errCode: %{public}d!", errCode); } } @@ -104,59 +111,65 @@ void InputMethodControllerImpl::DetachSync() int32_t errCode = InputMethodController::GetInstance()->Close(); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("InputMethodController::Close failed, errCode: %{public}d!", errCode); } } -void InputMethodControllerImpl::RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq) +void InputMethodControllerImpl::RegisterListener(std::string const &type, callbackType &&cb, uintptr_t opq) { std::lock_guard lock(mutex_); ani_object callbackObj = reinterpret_cast(opq); ani_ref callbackRef; ani_env *env = taihe::get_env(); if (env == nullptr || ANI_OK != env->GlobalReference_Create(callbackObj, &callbackRef)) { + IMSA_HILOGE("ani_env is nullptr or GlobalReference_Create failed, type: %{public}s!", type.c_str()); return; } - auto& cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), - [env, callbackRef](const CallbackObject& obj) { - ani_boolean isEqual = false; - return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj.ref, &isEqual)) && isEqual; - } - ); + auto &cbVec = jsCbMap_[type]; + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::shared_ptr &obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; + }); if (isDuplicate) { env->GlobalReference_Delete(callbackRef); + IMSA_HILOGD("callback already registered, type: %{public}s!", type.c_str()); return; } - cbVec.emplace_back(cb, callbackRef); + cbVec.emplace_back(std::make_shared(cb, callbackRef)); + IMSA_HILOGI("register callback success, type: %{public}s!", type.c_str()); } -void InputMethodControllerImpl::UnRegisterListener(std::string const& type, taihe::optional_view opq) +void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taihe::optional_view opq) { std::lock_guard lock(mutex_); const auto iter = jsCbMap_.find(type); if (iter == jsCbMap_.end()) { + IMSA_HILOGE("methodName: %{public}s already unRegistered!", type.c_str()); return; } - + if (!opq.has_value()) { jsCbMap_.erase(iter); + IMSA_HILOGE("callback is nullptr!"); return; } - - ani_env* env = taihe::get_env(); + + ani_env *env = taihe::get_env(); if (env == nullptr) { + IMSA_HILOGE("ani_env is nullptr!"); return; } GlobalRefGuard guard(env, reinterpret_cast(opq.value())); if (!guard) { + IMSA_HILOGE("GlobalRefGuard is false!"); return; } - - const auto pred = [env, targetRef = guard.get()](const CallbackObject& obj) { + + const auto pred = [env, targetRef = guard.get()](std::shared_ptr &obj) { ani_boolean is_equal = false; - return (ANI_OK == env->Reference_StrictEquals(targetRef, obj.ref, &is_equal)) && is_equal; + return (ANI_OK == env->Reference_StrictEquals(targetRef, obj->ref, &is_equal)) && is_equal; }; - auto& callbacks = iter->second; + auto &callbacks = iter->second; const auto it = std::find_if(callbacks.begin(), callbacks.end(), pred); if (it != callbacks.end()) { callbacks.erase(it); @@ -166,13 +179,12 @@ void InputMethodControllerImpl::UnRegisterListener(std::string const& type, taih } } - void InputMethodControllerImpl::InsertTextCallback(const std::u16string &text) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["insertText"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["insertText"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); taihe::string textStr = Str16ToStr8(text); func(textStr); } @@ -180,27 +192,27 @@ void InputMethodControllerImpl::InsertTextCallback(const std::u16string &text) void InputMethodControllerImpl::DeleteLeftCallback(int32_t length) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["deleteLeft"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["deleteLeft"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); func(length); } } void InputMethodControllerImpl::DeleteRightCallback(int32_t length) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["deleteRight"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["deleteRight"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); func(length); } } void InputMethodControllerImpl::SendKeyboardStatusCallback(const KeyboardStatus &status) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["sendKeyboardStatus"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["sendKeyboardStatus"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); KeyboardStatus_t state = EnumConvert::ConvertKeyboardStatus(status); func(state); } @@ -208,19 +220,19 @@ void InputMethodControllerImpl::SendKeyboardStatusCallback(const KeyboardStatus void InputMethodControllerImpl::SendFunctionKeyCallback(const FunctionKey &key) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["sendFunctionKey"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); - FunctionKey_t funcKey{.enterKeyType = EnumConvert::ConvertEnterKeyType(key.GetEnterKeyType())}; + auto &cbVec = jsCbMap_["sendFunctionKey"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); + FunctionKey_t funcKey{ .enterKeyType = EnumConvert::ConvertEnterKeyType(key.GetEnterKeyType()) }; func(funcKey); } } void InputMethodControllerImpl::MoveCursorCallback(const Direction &direction) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["moveCursor"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["moveCursor"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); Direction_t directionType = EnumConvert::ConvertDirection(direction); func(directionType); } @@ -228,9 +240,9 @@ void InputMethodControllerImpl::MoveCursorCallback(const Direction &direction) void InputMethodControllerImpl::HandleExtendActionCallback(int32_t action) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["handleExtendAction"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["handleExtendAction"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); ExtendAction_t actionType = EnumConvert::ConvertExtendAction(action); func(actionType); } @@ -238,9 +250,9 @@ void InputMethodControllerImpl::HandleExtendActionCallback(int32_t action) std::u16string InputMethodControllerImpl::GetLeftTextOfCursorCallback(int32_t number) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["getLeftTextOfCursor"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["getLeftTextOfCursor"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); taihe::string s = func(number); return Str8ToStr16(std::string(s)); } @@ -249,9 +261,9 @@ std::u16string InputMethodControllerImpl::GetLeftTextOfCursorCallback(int32_t nu std::u16string InputMethodControllerImpl::GetRightTextOfCursorCallback(int32_t number) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["getRightTextOfCursor"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["getRightTextOfCursor"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); taihe::string s = func(number); return Str8ToStr16(std::string(s)); } @@ -260,9 +272,9 @@ std::u16string InputMethodControllerImpl::GetRightTextOfCursorCallback(int32_t n int32_t InputMethodControllerImpl::GetTextIndexAtCursorCallback() { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["getTextIndexAtCursor"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["getTextIndexAtCursor"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); return func(); } return 0; @@ -271,22 +283,22 @@ int32_t InputMethodControllerImpl::GetTextIndexAtCursorCallback() void InputMethodControllerImpl::OnSelectByRange(int32_t start, int32_t end) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["selectByRange"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); - Range_t range{.start = start, .end = end}; + auto &cbVec = jsCbMap_["selectByRange"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); + Range_t range{ .start = start, .end = end }; func(range); } } void InputMethodControllerImpl::OnSelectByMovement(int32_t direction) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["selectByMovement"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); - Movement_t movement{.direction = EnumConvert::ConvertDirection(static_cast(direction))}; + auto &cbVec = jsCbMap_["selectByMovement"]; + for (auto &cb : cbVec) { + auto &func = std::get>(cb->callback); + Movement_t movement{ .direction = EnumConvert::ConvertDirection(static_cast(direction)) }; func(movement); } } -} -} \ No newline at end of file +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp index 355793cf4..e5ff11f1d 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_event_listener.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "input_method_event_listener.h" + #include "input_method_setting_impl.h" namespace OHOS { namespace MiscServices { @@ -42,5 +43,5 @@ void InputMethodEventListener::OnImeHide(const ImeWindowInfo &info) { InputMethodSettingImpl::GetInstance().OnImeHideCallback(info); } -} -} \ No newline at end of file +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp index 34f16d4a8..bf1453fbf 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -13,34 +13,36 @@ * limitations under the License. */ #include "input_method_setting_impl.h" -#include "input_method_event_listener.h" + +#include "ani_common.h" #include "ime_event_monitor_manager_impl.h" -#include "taihe/runtime.hpp" -#include "stdexcept" #include "input_method_controller.h" +#include "input_method_event_listener.h" #include "js_utils.h" -#include "ani_common.h" +#include "stdexcept" +#include "taihe/runtime.hpp" namespace OHOS { namespace MiscServices { using namespace taihe; -InputMethodSettingImpl& InputMethodSettingImpl::GetInstance() +InputMethodSettingImpl &InputMethodSettingImpl::GetInstance() { static InputMethodSettingImpl instance; return instance; } -array InputMethodSettingImpl::GetInputMethodSync(bool enable) { +array InputMethodSettingImpl::GetInputMethosdSync(bool enable) +{ std::vector properties; - int32_t errCode = - InputMethodController::GetInstance()->ListInputMethod(enable, properties); + int32_t errCode = InputMethodController::GetInstance()->ListInputMethod(enable, properties); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), "failed to get input method!"); + IMSA_HILOGE("failed to get input method, errCode:%{public}d!", errCode); return array(nullptr, 0); } std::vector vecProperty; - for (const auto& property : properties) { + for (const auto &property : properties) { vecProperty.push_back(PropertyConverter::ConvertProperty(property)); } return array(vecProperty); @@ -49,46 +51,47 @@ array InputMethodSettingImpl::GetInputMethodSync(bool ena array InputMethodSettingImpl::ListCurrentInputMethodSubtypeSync() { std::vector subProperties; - int32_t errCode = - InputMethodController::GetInstance()->ListCurrentInputMethodSubtype(subProperties); + int32_t errCode = InputMethodController::GetInstance()->ListCurrentInputMethodSubtype(subProperties); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("failed to get input method subtype, errCode:%{public}d!", errCode); return array(nullptr, 0); } std::vector vecSubtype; - for (const auto& property : subProperties) { + for (const auto &property : subProperties) { vecSubtype.push_back(PropertyConverter::ConvertSubProperty(property)); } return array(vecSubtype); - } -array InputMethodSettingImpl::ListInputMethodSubtypeSync(InputMethodProperty_t const& inputMethodProperty) +array InputMethodSettingImpl::ListInputMethodSubtypeSync( + InputMethodProperty_t const &inputMethodProperty) { - Property property{.name = std::string(inputMethodProperty.name), .id = std::string(inputMethodProperty.id)}; + Property property{ .name = std::string(inputMethodProperty.name), .id = std::string(inputMethodProperty.id) }; if (property.name.empty() || property.id.empty()) { property.name = inputMethodProperty.packageName; property.id = inputMethodProperty.methodId; } if (property.name.empty() || property.id.empty()) { set_business_error(IMFErrorCode::EXCEPTION_PARAMCHECK, "name and id must be string and cannot empty"); + IMSA_HILOGE("Property name and id must be string and cannot empty"); return array(nullptr, 0); } std::vector subProperties; - int32_t errCode = - InputMethodController::GetInstance()->ListInputMethodSubtype(property, subProperties); + int32_t errCode = InputMethodController::GetInstance()->ListInputMethodSubtype(property, subProperties); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + IMSA_HILOGE("failed to get input method subtype, errCode:%{public}d!", errCode); return array(nullptr, 0); } std::vector vecSubtype; - for (const auto& property : subProperties) { + for (const auto &property : subProperties) { vecSubtype.push_back(PropertyConverter::ConvertSubProperty(property)); } return array(vecSubtype); } -bool InputMethodSettingImpl::IsPanelShown(PanelInfo_t const& panelInfo) +bool InputMethodSettingImpl::IsPanelShown(PanelInfo_t const &panelInfo) { PanelInfo info; if (panelInfo.flag.has_value()) { @@ -99,110 +102,116 @@ bool InputMethodSettingImpl::IsPanelShown(PanelInfo_t const& panelInfo) int32_t errorCode = InputMethodController::GetInstance()->IsPanelShown(info, isShown); if (errorCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errorCode), "failed to query is panel shown!"); - return false; //napi 接口返回null + IMSA_HILOGE("failed to query is panel shown, errCode:%{public}d!", errorCode); + return false; } return isShown; } array InputMethodSettingImpl::GetAllInputMethodsSync() { - TH_THROW(std::runtime_error, "GetAllInputMethodsSync not implemented"); std::vector properties; - int32_t errCode = - InputMethodController::GetInstance()->ListInputMethod(properties); + int32_t errCode = InputMethodController::GetInstance()->ListInputMethod(properties); if (errCode != ErrorCode::NO_ERROR) { set_business_error(JsUtils::Convert(errCode), "failed to get input method!"); + IMSA_HILOGE("failed to get input method, errCode:%{public}d!", errCode); return array(nullptr, 0); } std::vector vecProperty; - for (const auto& property : properties) { + for (const auto &property : properties) { vecProperty.push_back(PropertyConverter::ConvertProperty(property)); } return array(vecProperty); } -void InputMethodSettingImpl::RegisterImeEvent(std::string const& eventName, int32_t eventMask, callbackType&& f, uintptr_t opq) +void InputMethodSettingImpl::RegisterImeEvent(std::string const &eventName, int32_t eventMask, callbackType &&f, + uintptr_t opq) { - auto ret = ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener( - eventMask, InputMethodEventListener::GetInstance()); - + auto ret = ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener(eventMask, + InputMethodEventListener::GetInstance()); if (ret == ErrorCode::NO_ERROR) { RegisterListener(eventName, std::forward(f), opq); } else { HandleRegistrationError(eventName, ret); } } -void InputMethodSettingImpl::UnregisterImeEvent(std::string const& eventName, int32_t eventMask, optional_view opq) + +void InputMethodSettingImpl::UnregisterImeEvent(std::string const &eventName, int32_t eventMask, + optional_view opq) { bool isUpdateFlag = false; UnregisterListener(eventName, opq, isUpdateFlag); - + if (isUpdateFlag) { - auto ret = ImeEventMonitorManagerImpl::GetInstance().UnRegisterImeEventListener( - eventMask, InputMethodEventListener::GetInstance()); + auto ret = ImeEventMonitorManagerImpl::GetInstance().UnRegisterImeEventListener(eventMask, + InputMethodEventListener::GetInstance()); IMSA_HILOGI("Updated event: %{public}s flag, ret: %{public}d", eventName.c_str(), ret); } } -void InputMethodSettingImpl::HandleRegistrationError(std::string const& eventName, int32_t errorCode) +void InputMethodSettingImpl::HandleRegistrationError(std::string const &eventName, int32_t errorCode) { auto errCode = JsUtils::Convert(errorCode); if (errCode == EXCEPTION_SYSTEM_PERMISSION) { - set_business_error(EXCEPTION_SYSTEM_PERMISSION, - JsUtils::ToMessage(EXCEPTION_SYSTEM_PERMISSION)); + set_business_error(EXCEPTION_SYSTEM_PERMISSION, JsUtils::ToMessage(EXCEPTION_SYSTEM_PERMISSION)); } IMSA_HILOGE("Failed to register %{public}s, error: %{public}d", eventName.c_str(), errorCode); } -void InputMethodSettingImpl::RegisterListener(std::string const& type, callbackType&& cb, uintptr_t opq) +void InputMethodSettingImpl::RegisterListener(std::string const &type, callbackType &&cb, uintptr_t opq) { std::lock_guard lock(mutex_); ani_object callbackObj = reinterpret_cast(opq); ani_ref callbackRef; ani_env *env = taihe::get_env(); if (env == nullptr || ANI_OK != env->GlobalReference_Create(callbackObj, &callbackRef)) { + IMSA_HILOGE("Failed to register %{public}s", type.c_str()); return; } - auto& cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), - [env, callbackRef](const CallbackObject& obj) { - ani_boolean isEqual = false; - return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj.ref, &isEqual)) && isEqual; - } - ); + auto &cbVec = jsCbMap_[type]; + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::shared_ptr &obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; + }); if (isDuplicate) { env->GlobalReference_Delete(callbackRef); + IMSA_HILOGD("%{public}s is already registered", type.c_str()); return; } - cbVec.emplace_back(cb, callbackRef); + cbVec.emplace_back(std::make_shared(cb, callbackRef)); + IMSA_HILOGI("Registered success type: %{public}s", type.c_str()); } -void InputMethodSettingImpl::UnregisterListener(std::string const& type, optional_view opq, bool& isUpdateFlag) +void InputMethodSettingImpl::UnregisterListener(std::string const &type, optional_view opq, + bool &isUpdateFlag) { std::lock_guard lock(mutex_); const auto iter = jsCbMap_.find(type); if (iter == jsCbMap_.end()) { + IMSA_HILOGE("%{public}s is not registered", type.c_str()); return; } - + if (!opq.has_value()) { jsCbMap_.erase(iter); isUpdateFlag = true; return; } - - ani_env* env = taihe::get_env(); + + ani_env *env = taihe::get_env(); if (env == nullptr) { + IMSA_HILOGE("Failed to unregister %{public}s, env is nullptr", type.c_str()); return; } GlobalRefGuard guard(env, reinterpret_cast(opq.value())); if (!guard) { + IMSA_HILOGE("Failed to unregister %{public}s, GlobalRefGuard is false!", type.c_str()); return; } - - const auto pred = [env, targetRef = guard.get()](const CallbackObject& obj) { + + const auto pred = [env, targetRef = guard.get()](std::shared_ptr &obj) { ani_boolean is_equal = false; - return (ANI_OK == env->Reference_StrictEquals(targetRef, obj.ref, &is_equal)) && is_equal; + return (ANI_OK == env->Reference_StrictEquals(targetRef, obj->ref, &is_equal)) && is_equal; }; - auto& callbacks = iter->second; + auto &callbacks = iter->second; const auto it = std::find_if(callbacks.begin(), callbacks.end(), pred); if (it != callbacks.end()) { callbacks.erase(it); @@ -210,15 +219,16 @@ void InputMethodSettingImpl::UnregisterListener(std::string const& type, optiona if (callbacks.empty()) { jsCbMap_.erase(iter); isUpdateFlag = true; - } + } } void InputMethodSettingImpl::OnImeChangeCallback(const Property &property, const SubProperty &subProperty) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_["imeChange"]; - for(auto &cb : cbVec) { - auto& func = std::get>(cb.callback); + auto &cbVec = jsCbMap_["imeChange"]; + for (auto &cb : cbVec) { + auto &func = + std::get>(cb->callback); func(PropertyConverter::ConvertProperty(property), PropertyConverter::ConvertSubProperty(subProperty)); } } @@ -261,22 +271,20 @@ void InputMethodSettingImpl::SetSoftKbShowingFlag(PanelFlag flag) softKbShowingFlag_ = flag; } -void InputMethodSettingImpl::OnPanelStatusChange(std::string const& type, const InputWindowInfo &info) +void InputMethodSettingImpl::OnPanelStatusChange(std::string const &type, const InputWindowInfo &info) { std::lock_guard lock(mutex_); - auto& cbVec = jsCbMap_[type]; - for(auto &cb : cbVec) { - InputWindowInfo_t inputWindowInfo{ - .name = info.name, + auto &cbVec = jsCbMap_[type]; + for (auto &cb : cbVec) { + InputWindowInfo_t inputWindowInfo{ .name = info.name, .left = info.left, .top = info.top, .width = info.width, - .height = info.height - }; - taihe::array arrInfo{inputWindowInfo}; - auto& func = std::get)>>(cb.callback); + .height = info.height }; + taihe::array arrInfo{ inputWindowInfo }; + auto &func = std::get)>>(cb->callback); func(arrInfo); } } -} -} \ No newline at end of file +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp index 5379ca5de..d59aeae38 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_text_changed_listener.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "input_method_text_changed_listener.h" + #include "input_method_controller_impl.h" namespace OHOS { diff --git a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp index cf3b2351f..2394a75cc 100644 --- a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp @@ -1,45 +1,68 @@ -#include "ohos.inputMethod.proj.hpp" +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "ohos.inputMethod.impl.hpp" -#include "taihe/runtime.hpp" -#include "stdexcept" + +#include "ani_common.h" +#include "common_fun_ani.h" +#include "input_method_controller.h" #include "input_method_controller_impl.h" #include "input_method_setting_impl.h" -#include "input_method_controller.h" -#include "ani_common.h" #include "js_utils.h" +#include "ohos.inputMethod.proj.hpp" +#include "stdexcept" +#include "taihe/runtime.hpp" using namespace taihe; using namespace ohos::inputMethod; using namespace ohos::inputMethodSubtype; using namespace OHOS::MiscServices; namespace { -InputMethodSetting GetSetting() { +InputMethodSetting GetSetting() +{ // The parameters in the make_holder function should be of the same type // as the parameters in the constructor of the actual implementation class. return make_holder(); } -ohos::inputMethod::InputMethodController GetController() { +ohos::inputMethod::InputMethodController GetController() +{ // The parameters in the make_holder function should be of the same type // as the parameters in the constructor of the actual implementation class. return make_holder(); } -InputMethodProperty GetDefaultInputMethod() { +InputMethodProperty GetDefaultInputMethod() +{ InputMethodProperty inputMethodProperty{}; std::shared_ptr property; int32_t ret = OHOS::MiscServices::InputMethodController::GetInstance()->GetDefaultInputMethod(property); if (ret != ErrorCode::NO_ERROR) { taihe::set_business_error(JsUtils::Convert(ret), "failed to get default input method!"); + IMSA_HILOGE("failed to get default input method!"); return inputMethodProperty; } inputMethodProperty = PropertyConverter::ConvertProperty(property); return inputMethodProperty; } -InputMethodProperty GetCurrentInputMethod() { +InputMethodProperty GetCurrentInputMethod() +{ InputMethodProperty inputMethodProperty{}; - std::shared_ptr property = OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethod(); + std::shared_ptr property = + OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethod(); if (property == nullptr) { IMSA_HILOGE("current input method is nullptr!"); return inputMethodProperty; @@ -48,61 +71,88 @@ InputMethodProperty GetCurrentInputMethod() { return inputMethodProperty; } -InputMethodSubtype GetCurrentInputMethodSubtype() { +InputMethodSubtype GetCurrentInputMethodSubtype() +{ InputMethodSubtype inputMethodSubtype{}; - std::shared_ptr subProperty = OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); + std::shared_ptr subProperty = + OHOS::MiscServices::InputMethodController::GetInstance()->GetCurrentInputMethodSubtype(); if (subProperty == nullptr) { IMSA_HILOGE("current input method subtype is nullptr!"); return inputMethodSubtype; } inputMethodSubtype = PropertyConverter::ConvertSubProperty(subProperty); - return inputMethodSubtype; + return inputMethodSubtype; } -uintptr_t GetSystemInputMethodConfigAbility() { - TH_THROW(std::runtime_error, "GetSystemInputMethodConfigAbility not implemented"); +uintptr_t GetSystemInputMethodConfigAbility() +{ + OHOS::AppExecFwk::ElementName elementName; + int32_t ret = OHOS::MiscServices::InputMethodController::GetInstance()->GetInputMethodConfig(elementName); + if (ret != ErrorCode::NO_ERROR) { + taihe::set_business_error(JsUtils::Convert(ret), "failed to get input method config ability!"); + IMSA_HILOGE("failed to get input method config ability!"); + return reinterpret_cast(nullptr); + } + ani_object obj = OHOS::AppExecFwk::CommonFunAni::ConvertElementName(taihe::get_env(), elementName); + return reinterpret_cast(obj); } -bool SwitchInputMethodWithTarget(InputMethodProperty const& target) { +bool SwitchInputMethodWithTarget(InputMethodProperty const &target) +{ std::string packageName(target.name); std::string id(target.id); if (packageName.empty() || id.empty()) { packageName = target.packageName; id = target.methodId; } - int32_t errCode = - OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, packageName, id); + int32_t errCode = + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, + packageName, id); if (errCode != ErrorCode::NO_ERROR) { - taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + int32_t code = JsUtils::Convert(errCode); + std::string message = JsUtils::ToMessage(code); + taihe::set_business_error(code, message); + IMSA_HILOGE("failed to switch input method, code:%{public}d message: %{public}s", code, message.c_str()); return false; } return true; } -void SwitchInputMethodSync(string_view bundleName, optional_view subtypeId) { +void SwitchInputMethodSync(string_view bundleName, optional_view subtypeId) +{ std::string id; if (subtypeId.has_value()) { id = subtypeId.value(); } - int32_t errCode = - OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::SYSTEM_APP, std::string(bundleName), id); + int32_t errCode = + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::SYSTEM_APP, + std::string(bundleName), id); if (errCode != ErrorCode::NO_ERROR) { - taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + int32_t code = JsUtils::Convert(errCode); + std::string message = JsUtils::ToMessage(code); + taihe::set_business_error(code, message); + IMSA_HILOGE("failed to switch input method, code:%{public}d message: %{public}s", code, message.c_str()); } } -bool SwitchCurrentInputMethodSubtypeSync(InputMethodProperty const& target) { +bool SwitchCurrentInputMethodSubtypeSync(InputMethodProperty const &target) +{ std::string name(target.name); std::string id(target.id); int32_t errCode = - OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, name, id); + OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, name, + id); if (errCode != ErrorCode::NO_ERROR) { - taihe::set_business_error(JsUtils::Convert(errCode), JsUtils::ToMessage(JsUtils::Convert(errCode))); + int32_t code = JsUtils::Convert(errCode); + std::string message = JsUtils::ToMessage(code); + taihe::set_business_error(code, message); + IMSA_HILOGE("failed to switch Current input method subtype, code:%{public}d message: %{public}s", code, + message.c_str()); return false; } return true; } -} // namespace +} // namespace TH_EXPORT_CPP_API_GetSetting(GetSetting); TH_EXPORT_CPP_API_GetController(GetController); -- Gitee From eaae4196c02d2e2e3da74336f9e55b1958c0addb Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Thu, 8 May 2025 11:14:41 +0800 Subject: [PATCH 3/9] fix: modify on/off Signed-off-by: weishaoxiong --- frameworks/ets/taihe/inputMethod/BUILD.gn | 9 +++--- .../inputMethod/idl/ohos.elementName.taihe | 17 ----------- .../inputMethod/idl/ohos.inputMethod.taihe | 28 ++++++++++++++----- .../idl/ohos.inputMethodSubtype.taihe | 4 +-- .../taihe/inputMethod/include/ani_common.h | 6 ++-- .../include/input_method_controller_impl.h | 6 ++-- .../include/input_method_setting_impl.h | 2 +- .../taihe/inputMethod/src/ani_constructor.cpp | 6 ++-- .../src/input_method_controller_impl.cpp | 14 ++++++---- .../src/input_method_setting_impl.cpp | 6 ++-- .../inputMethod/src/ohos.inputMethod.impl.cpp | 11 ++++++-- 11 files changed, 57 insertions(+), 52 deletions(-) delete mode 100644 frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe diff --git a/frameworks/ets/taihe/inputMethod/BUILD.gn b/frameworks/ets/taihe/inputMethod/BUILD.gn index fc7b95e17..7e537f19c 100644 --- a/frameworks/ets/taihe/inputMethod/BUILD.gn +++ b/frameworks/ets/taihe/inputMethod/BUILD.gn @@ -22,10 +22,9 @@ taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" copy_taihe_idl("copy_taihe") { sources = [ - "idl/ohos.elementName.taihe", "idl/ohos.inputMethod.Panel.taihe", "idl/ohos.inputMethod.taihe", - "idl/ohos.inputMethodSubtype.taihe" + "idl/ohos.InputMethodSubtype.taihe" ] external_deps = [] @@ -39,8 +38,8 @@ ohos_taihe("run_taihe") { "$taihe_generated_file_path/src/ohos.inputMethod.abi.c", "$taihe_generated_file_path/src/ohos.inputMethod.Panel.ani.cpp", "$taihe_generated_file_path/src/ohos.inputMethod.Panel.abi.c", - "$taihe_generated_file_path/src/ohos.inputMethodSubtype.ani.cpp", - "$taihe_generated_file_path/src/ohos.inputMethodSubtype.abi.c", + "$taihe_generated_file_path/src/ohos.InputMethodSubtype.ani.cpp", + "$taihe_generated_file_path/src/ohos.InputMethodSubtype.abi.c", ] } @@ -94,7 +93,7 @@ generate_static_abc("inputmethod_abc") { files = [ "$taihe_generated_file_path/@ohos.inputMethod.ets", "$taihe_generated_file_path/@ohos.inputMethod.Panel.ets", - "$taihe_generated_file_path/@ohos.inputMethodSubtype.ets", + "$taihe_generated_file_path/@ohos.InputMethodSubtype.ets", ] is_boot_abc = "True" device_dst_file = "/system/framework/inputmethod_abc.abc" diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe deleted file mode 100644 index 173ce4fab..000000000 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.elementName.taihe +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@!sts_inject("import {ElementName} from 'bundleManager.ElementName';") -@!namespace("@ohos.inputMethod") \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index b736de6e1..848a3fb07 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -13,9 +13,11 @@ * limitations under the License. */ + +@!sts_inject_into_module("import {ElementName} from 'bundleManager.ElementName';") @!namespace("@ohos.inputMethod", "inputMethod") from ohos.inputMethod.Panel use PanelInfo; -from ohos.inputMethodSubtype use InputMethodSubtype; +from ohos.InputMethodSubtype use InputMethodSubtype; struct InputMethodProperty { @readonly packageName: String; @@ -52,11 +54,17 @@ interface InputMethodSetting { @gen_promise("getAllInputMethods") GetAllInputMethodsSync(): Array; @!sts_inject_into_interface(""" + on(type: string, callback: (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_InputMethodSubtype.InputMethodSubtype) => void): void; + off(type: string, callback?: (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_InputMethodSubtype.InputMethodSubtype) => void): void; + on(type: string, callback: (info: Array) => void): void; + off(type: string, callback?: (info: Array) => void): void; + """) + @!sts_inject_into_class(""" on(type: string, cb: Object) { switch(type) { case "imeHide": return this.onImeHide(cb as (info: Array) => void, cb); case "imeShow": return this.onImeShow(cb as (info: Array) => void, cb); - case "imeChange": return this.onImeChange(cb as (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_inputMethodSubtype.InputMethodSubtype) => void, cb); + case "imeChange": return this.onImeChange(cb as (inputMethodProperty: InputMethodProperty, inputMethodSubtype: __ohos_InputMethodSubtype.InputMethodSubtype) => void, cb); default: throw new Error(`Unknown type: ${type}`); } } @@ -183,6 +191,12 @@ interface InputMethodController { @gen_promise("detach") DetachSync(); @!sts_inject_into_interface(""" + on(type: string, callback: (arg0 : Object) => Object): void; + off(type: string, callback?: (arg0 : Object) => Object): void; + on(type: string, callback: () => int): void; + off(type: string, callback?: () => int): void; + """) + @!sts_inject_into_class(""" on(type: string, cb: Object) { switch(type) { case "selectByRange": return this.onSelectByRange(cb as (range : Range) => void, cb); @@ -194,8 +208,8 @@ interface InputMethodController { case "sendFunctionKey": return this.onSendFunctionKey(cb as (functionKey: FunctionKey) => void, cb); case "moveCursor": return this.onMoveCursor(cb as (direction: Direction) => void, cb); case "handleExtendAction": return this.onHandleExtendAction(cb as (extendAction: ExtendAction) => void, cb); - case "getLeftTextOfCursor": return this.onGetLeftTextOfCursor(cb as (length: int) => void, cb); - case "getRightTextOfCursor": return this.onGetRightTextOfCursor(cb as (length: int) => void, cb); + case "getLeftTextOfCursor": return this.onGetLeftTextOfCursor(cb as (length: int) => String, cb); + case "getRightTextOfCursor": return this.onGetRightTextOfCursor(cb as (length: int) => String, cb); case "getTextIndexAtCursor": return this.onGetTextIndexAtCursor(cb as () => int, cb); default: throw new Error(`Unknown type: ${type}`); } @@ -236,9 +250,9 @@ interface InputMethodController { OffMoveCursor(opq: Optional); OnHandleExtendAction(f: (action: ExtendAction) => void, opq: Opaque); OffHandleExtendAction(opq: Optional); - OnGetLeftTextOfCursor(f: (length: i32) => void, opq: Opaque); + OnGetLeftTextOfCursor(f: (length: i32) => String, opq: Opaque); OffGetLeftTextOfCursor(opq: Optional); - OnGetRightTextOfCursor(f: (length: i32) => void, opq: Opaque); + OnGetRightTextOfCursor(f: (length: i32) => String, opq: Opaque); OffGetRightTextOfCursor(opq: Optional); OnGetTextIndexAtCursor(f: () => i32, opq: Opaque); OffGetTextIndexAtCursor(opq: Optional); @@ -257,4 +271,4 @@ function SwitchInputMethodWithTarget(target: InputMethodProperty): bool; function SwitchInputMethodSync(bundleName: String, subtypeId: Optional); @gen_async("switchCurrentInputMethodSubtype") @gen_promise("switchCurrentInputMethodSubtype") -function SwitchCurrentInputMethodSubtypeSync(target: InputMethodProperty): bool; \ No newline at end of file +function SwitchCurrentInputMethodSubtypeSync(target: InputMethodSubtype): bool; \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe index 04ffff53e..92522f9ad 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -@!namespace("@ohos.inputMethodSubtype") + +@!namespace("@ohos.InputMethodSubtype") struct InputMethodSubtype { @readonly name: String; @readonly id: String; diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h index bfeb78d34..aac367f12 100644 --- a/frameworks/ets/taihe/inputMethod/include/ani_common.h +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -22,7 +22,7 @@ #include "ohos.inputMethod.proj.hpp" #include "taihe/runtime.hpp" using InputMethodProperty_t = ohos::inputMethod::InputMethodProperty; -using InputMethodSubtype_t = ohos::inputMethodSubtype::InputMethodSubtype; +using InputMethodSubtype_t = ohos::InputMethodSubtype::InputMethodSubtype; using PanelInfo_t = ohos::inputMethod::Panel::PanelInfo; using InputWindowInfo_t = ohos::inputMethod::InputWindowInfo; using RequestKeyboardReason_t = ohos::inputMethod::RequestKeyboardReason; @@ -99,7 +99,7 @@ private: } }; -using callbackType = std::variant, taihe::callback, +using callbackType = std::variant, taihe::callback, taihe::callback, taihe::callback, taihe::callback, taihe::callback, taihe::callback, taihe::callback, taihe::callback, @@ -111,7 +111,7 @@ struct CallbackObject { CallbackObject(callbackType cb, ani_ref ref) : callback(cb), ref(ref) { } - ~CallbackObject() + void Release() { if (auto *env = taihe::get_env()) { env->GlobalReference_Delete(ref); diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h index 7d915d0ad..ca5d9db39 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h @@ -57,7 +57,7 @@ public: private: std::mutex mutex_; - std::map>> jsCbMap_; + std::map>> jsCbMap_; static std::mutex controllerMutex_; static std::shared_ptr controller_; }; @@ -165,7 +165,7 @@ public: { InputMethodControllerImpl::GetInstance()->UnRegisterListener("handleExtendAction", opq); } - void OnGetLeftTextOfCursor(taihe::callback_view f, uintptr_t opq) + void OnGetLeftTextOfCursor(taihe::callback_view f, uintptr_t opq) { InputMethodControllerImpl::GetInstance()->RegisterListener("getLeftTextOfCursor", f, opq); } @@ -173,7 +173,7 @@ public: { InputMethodControllerImpl::GetInstance()->UnRegisterListener("getLeftTextOfCursor", opq); } - void OnGetRightTextOfCursor(taihe::callback_view f, uintptr_t opq) + void OnGetRightTextOfCursor(taihe::callback_view f, uintptr_t opq) { InputMethodControllerImpl::GetInstance()->RegisterListener("getRightTextOfCursor", f, opq); } diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h index 5a3dc76c0..ff0a832bd 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h @@ -48,7 +48,7 @@ private: void UnregisterListener(std::string const &type, taihe::optional_view opq, bool &isUpdateFlag); void HandleRegistrationError(std::string const &eventName, int32_t errorCode); std::mutex mutex_; - std::map>> jsCbMap_; + std::map>> jsCbMap_; }; class IMFSettingImpl { diff --git a/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp index 8b2c78e28..b3719ccb2 100644 --- a/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp +++ b/frameworks/ets/taihe/inputMethod/src/ani_constructor.cpp @@ -15,7 +15,7 @@ #include "ohos.inputMethod.Panel.ani.hpp" #include "ohos.inputMethod.ani.hpp" -#include "ohos.inputMethodSubtype.ani.hpp" +#include "ohos.InputMethodSubtype.ani.hpp" ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { ani_env *env; @@ -26,8 +26,8 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) std::cerr << "Error from ohos::inputMethod::ANIRegister" << std::endl; return ANI_ERROR; } - if (ANI_OK != ohos::inputMethodSubtype::ANIRegister(env)) { - std::cerr << "Error from ohos::inputMethodSubtype::ANIRegister" << std::endl; + if (ANI_OK != ohos::InputMethodSubtype::ANIRegister(env)) { + std::cerr << "Error from ohos::InputMethodSubtype::ANIRegister" << std::endl; return ANI_ERROR; } if (ANI_OK != ohos::inputMethod::Panel::ANIRegister(env)) { diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp index e28c871cd..c48defac1 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -126,7 +126,7 @@ void InputMethodControllerImpl::RegisterListener(std::string const &type, callba return; } auto &cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::shared_ptr &obj) { + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { ani_boolean isEqual = false; return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; }); @@ -135,7 +135,7 @@ void InputMethodControllerImpl::RegisterListener(std::string const &type, callba IMSA_HILOGD("callback already registered, type: %{public}s!", type.c_str()); return; } - cbVec.emplace_back(std::make_shared(cb, callbackRef)); + cbVec.emplace_back(std::make_unique(cb, callbackRef)); IMSA_HILOGI("register callback success, type: %{public}s!", type.c_str()); } void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taihe::optional_view opq) @@ -148,6 +148,9 @@ void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taih } if (!opq.has_value()) { + for (auto & uniquePtr: iter->second) { + uniquePtr->Release(); + } jsCbMap_.erase(iter); IMSA_HILOGE("callback is nullptr!"); return; @@ -165,13 +168,14 @@ void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taih return; } - const auto pred = [env, targetRef = guard.get()](std::shared_ptr &obj) { + const auto pred = [env, targetRef = guard.get()](std::unique_ptr &obj) { ani_boolean is_equal = false; return (ANI_OK == env->Reference_StrictEquals(targetRef, obj->ref, &is_equal)) && is_equal; }; auto &callbacks = iter->second; const auto it = std::find_if(callbacks.begin(), callbacks.end(), pred); if (it != callbacks.end()) { + it->get()->Release(); callbacks.erase(it); } if (callbacks.empty()) { @@ -252,7 +256,7 @@ std::u16string InputMethodControllerImpl::GetLeftTextOfCursorCallback(int32_t nu std::lock_guard lock(mutex_); auto &cbVec = jsCbMap_["getLeftTextOfCursor"]; for (auto &cb : cbVec) { - auto &func = std::get>(cb->callback); + auto &func = std::get>(cb->callback); taihe::string s = func(number); return Str8ToStr16(std::string(s)); } @@ -263,7 +267,7 @@ std::u16string InputMethodControllerImpl::GetRightTextOfCursorCallback(int32_t n std::lock_guard lock(mutex_); auto &cbVec = jsCbMap_["getRightTextOfCursor"]; for (auto &cb : cbVec) { - auto &func = std::get>(cb->callback); + auto &func = std::get>(cb->callback); taihe::string s = func(number); return Str8ToStr16(std::string(s)); } diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp index bf1453fbf..f7201d05f 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -167,7 +167,7 @@ void InputMethodSettingImpl::RegisterListener(std::string const &type, callbackT return; } auto &cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::shared_ptr &obj) { + bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { ani_boolean isEqual = false; return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; }); @@ -176,7 +176,7 @@ void InputMethodSettingImpl::RegisterListener(std::string const &type, callbackT IMSA_HILOGD("%{public}s is already registered", type.c_str()); return; } - cbVec.emplace_back(std::make_shared(cb, callbackRef)); + cbVec.emplace_back(std::make_unique(cb, callbackRef)); IMSA_HILOGI("Registered success type: %{public}s", type.c_str()); } void InputMethodSettingImpl::UnregisterListener(std::string const &type, optional_view opq, @@ -207,7 +207,7 @@ void InputMethodSettingImpl::UnregisterListener(std::string const &type, optiona return; } - const auto pred = [env, targetRef = guard.get()](std::shared_ptr &obj) { + const auto pred = [env, targetRef = guard.get()](std::unique_ptr &obj) { ani_boolean is_equal = false; return (ANI_OK == env->Reference_StrictEquals(targetRef, obj->ref, &is_equal)) && is_equal; }; diff --git a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp index 2394a75cc..c7528ba74 100644 --- a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp @@ -27,7 +27,7 @@ using namespace taihe; using namespace ohos::inputMethod; -using namespace ohos::inputMethodSubtype; +using namespace ohos::InputMethodSubtype; using namespace OHOS::MiscServices; namespace { InputMethodSetting GetSetting() @@ -105,9 +105,14 @@ bool SwitchInputMethodWithTarget(InputMethodProperty const &target) packageName = target.packageName; id = target.methodId; } + if (packageName.empty() || id.empty()) { + taihe::set_business_error(IMFErrorCode::EXCEPTION_PARAMCHECK, "packageName and methodId is empty"); + IMSA_HILOGE("failed to switch input method, packageName or id is empty!"); + return false; + } int32_t errCode = OHOS::MiscServices::InputMethodController::GetInstance()->SwitchInputMethod(SwitchTrigger::CURRENT_IME, - packageName, id); + packageName, ""); if (errCode != ErrorCode::NO_ERROR) { int32_t code = JsUtils::Convert(errCode); std::string message = JsUtils::ToMessage(code); @@ -135,7 +140,7 @@ void SwitchInputMethodSync(string_view bundleName, optional_view subtype } } -bool SwitchCurrentInputMethodSubtypeSync(InputMethodProperty const &target) +bool SwitchCurrentInputMethodSubtypeSync(InputMethodSubtype const &target) { std::string name(target.name); std::string id(target.id); -- Gitee From e12b871b991e73f52e4a8f931e9b5daed6745f04 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Tue, 13 May 2025 15:28:52 +0800 Subject: [PATCH 4/9] fix: codeCheck Signed-off-by: weishaoxiong --- .../taihe/inputMethod/idl/ohos.inputMethod.taihe | 8 ++++---- .../ets/taihe/inputMethod/include/ani_common.h | 8 ++++---- ...dSubtype.taihe => ohos.InputMethodSubtype.taihe} | 4 ++-- .../src/input_method_controller_impl.cpp | 11 ++++++----- .../inputMethod/src/input_method_setting_impl.cpp | 13 +++++++------ 5 files changed, 23 insertions(+), 21 deletions(-) rename frameworks/ets/taihe/inputMethod/{idl/ohos.inputMethodSubtype.taihe => ohos.InputMethodSubtype.taihe} (92%) diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index 848a3fb07..6275b6a07 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -25,9 +25,9 @@ struct InputMethodProperty { @readonly name: String; @readonly id: String; @readonly label: Optional; - @readonly labelId: Optional; + @readonly labelId: Optional; @readonly icon: Optional; - @readonly iconId: Optional; + @readonly iconId: Optional; extra: Optional; } @@ -35,8 +35,8 @@ struct InputWindowInfo { name: String; left: i32; top: i32; - width: u32; - height: u32; + width: i64; + height: i64; } interface InputMethodSetting { diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h index aac367f12..30f3c9eee 100644 --- a/frameworks/ets/taihe/inputMethod/include/ani_common.h +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -75,9 +75,9 @@ private: result.methodId = obj.id; result.id = obj.id; result.label = taihe::optional(std::in_place_t{}, obj.label); - result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); result.icon = taihe::optional(std::in_place_t{}, obj.icon); - result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); return result; } @@ -92,9 +92,9 @@ private: result.locale = obj.locale; result.language = obj.language; result.label = taihe::optional(std::in_place_t{}, obj.label); - result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); result.icon = taihe::optional(std::in_place_t{}, obj.icon); - result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); return result; } }; diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/ohos.InputMethodSubtype.taihe similarity index 92% rename from frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe rename to frameworks/ets/taihe/inputMethod/ohos.InputMethodSubtype.taihe index 92522f9ad..8a175f88e 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethodSubtype.taihe +++ b/frameworks/ets/taihe/inputMethod/ohos.InputMethodSubtype.taihe @@ -21,8 +21,8 @@ struct InputMethodSubtype { @readonly language: String; @readonly mode: Optional; @readonly icon: Optional; - @readonly iconId: Optional; + @readonly iconId: Optional; @readonly label: Optional; - @readonly labelId: Optional; + @readonly labelId: Optional; extra: Optional; } \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp index c48defac1..c55fe42f0 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -126,10 +126,11 @@ void InputMethodControllerImpl::RegisterListener(std::string const &type, callba return; } auto &cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { - ani_boolean isEqual = false; - return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; - }); + bool isDuplicate = + std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; + }); if (isDuplicate) { env->GlobalReference_Delete(callbackRef); IMSA_HILOGD("callback already registered, type: %{public}s!", type.c_str()); @@ -148,7 +149,7 @@ void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taih } if (!opq.has_value()) { - for (auto & uniquePtr: iter->second) { + for (auto &uniquePtr : iter->second) { uniquePtr->Release(); } jsCbMap_.erase(iter); diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp index f7201d05f..b7d3bec0f 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -167,10 +167,11 @@ void InputMethodSettingImpl::RegisterListener(std::string const &type, callbackT return; } auto &cbVec = jsCbMap_[type]; - bool isDuplicate = std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { - ani_boolean isEqual = false; - return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; - }); + bool isDuplicate = + std::any_of(cbVec.begin(), cbVec.end(), [env, callbackRef](std::unique_ptr &obj) { + ani_boolean isEqual = false; + return (ANI_OK == env->Reference_StrictEquals(callbackRef, obj->ref, &isEqual)) && isEqual; + }); if (isDuplicate) { env->GlobalReference_Delete(callbackRef); IMSA_HILOGD("%{public}s is already registered", type.c_str()); @@ -279,8 +280,8 @@ void InputMethodSettingImpl::OnPanelStatusChange(std::string const &type, const InputWindowInfo_t inputWindowInfo{ .name = info.name, .left = info.left, .top = info.top, - .width = info.width, - .height = info.height }; + .width = static_cast(info.width), + .height = static_cast(info.height) }; taihe::array arrInfo{ inputWindowInfo }; auto &func = std::get)>>(cb->callback); func(arrInfo); -- Gitee From 549a42a0c2fb4d2936be60558f90c9770eb4989f Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Tue, 13 May 2025 15:29:41 +0800 Subject: [PATCH 5/9] fix: codeCheck Signed-off-by: weishaoxiong --- .../ets/taihe/inputMethod/{ => idl}/ohos.InputMethodSubtype.taihe | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename frameworks/ets/taihe/inputMethod/{ => idl}/ohos.InputMethodSubtype.taihe (100%) diff --git a/frameworks/ets/taihe/inputMethod/ohos.InputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe similarity index 100% rename from frameworks/ets/taihe/inputMethod/ohos.InputMethodSubtype.taihe rename to frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe -- Gitee From d39ebdbd5a052b1622bf42cf9d300e6be3baa4ac Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Wed, 14 May 2025 14:39:56 +0800 Subject: [PATCH 6/9] fix: Signed-off-by: weishaoxiong --- .../idl/ohos.InputMethodSubtype.taihe | 4 ++-- .../inputMethod/idl/ohos.inputMethod.taihe | 16 +++++++------- .../taihe/inputMethod/include/ani_common.h | 8 +++---- .../include/input_method_setting_impl.h | 6 ++--- .../src/input_method_controller_impl.cpp | 22 ++++++++++++------- .../src/input_method_setting_impl.cpp | 6 ++--- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe index 8a175f88e..77f67b211 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.InputMethodSubtype.taihe @@ -21,8 +21,8 @@ struct InputMethodSubtype { @readonly language: String; @readonly mode: Optional; @readonly icon: Optional; - @readonly iconId: Optional; + @readonly iconId: Optional; @readonly label: Optional; - @readonly labelId: Optional; + @readonly labelId: Optional; extra: Optional; } \ No newline at end of file diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index 6275b6a07..8afce5648 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -25,9 +25,9 @@ struct InputMethodProperty { @readonly name: String; @readonly id: String; @readonly label: Optional; - @readonly labelId: Optional; + @readonly labelId: Optional; @readonly icon: Optional; - @readonly iconId: Optional; + @readonly iconId: Optional; extra: Optional; } @@ -35,14 +35,14 @@ struct InputWindowInfo { name: String; left: i32; top: i32; - width: i64; - height: i64; + width: f64; + height: f64; } interface InputMethodSetting { @gen_async("getInputMethods") @gen_promise("getInputMethods") - GetInputMethosdSync(enable: bool): Array; + GetInputMethodsSync(enable: bool): Array; @gen_async("listCurrentInputMethodSubtype") @gen_promise("listCurrentInputMethodSubtype") ListCurrentInputMethodSubtypeSync(): Array; @@ -151,9 +151,9 @@ struct InputAttribute { struct TextConfig { inputAttribute: InputAttribute; - @readonly cursorInfo: CursorInfo; - @readonly selection: Range; - @readonly windowId: i32; + @readonly cursorInfo: Optional; + @readonly selection: Optional; + @readonly windowId: Optional; } diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h index 30f3c9eee..7508d085d 100644 --- a/frameworks/ets/taihe/inputMethod/include/ani_common.h +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -75,9 +75,9 @@ private: result.methodId = obj.id; result.id = obj.id; result.label = taihe::optional(std::in_place_t{}, obj.label); - result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); result.icon = taihe::optional(std::in_place_t{}, obj.icon); - result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); return result; } @@ -92,9 +92,9 @@ private: result.locale = obj.locale; result.language = obj.language; result.label = taihe::optional(std::in_place_t{}, obj.label); - result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); + result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); result.icon = taihe::optional(std::in_place_t{}, obj.icon); - result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); + result.iconId = taihe::optional(std::in_place_t{}, obj.iconId); return result; } }; diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h index ff0a832bd..2e4da0139 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_setting_impl.h @@ -28,7 +28,7 @@ namespace MiscServices { class InputMethodSettingImpl { public: static InputMethodSettingImpl &GetInstance(); - taihe::array GetInputMethosdSync(bool enable); + taihe::array GetInputMethodsSync(bool enable); taihe::array ListCurrentInputMethodSubtypeSync(); taihe::array ListInputMethodSubtypeSync(InputMethodProperty_t const &inputMethodProperty); bool IsPanelShown(PanelInfo_t const &panelInfo); @@ -56,9 +56,9 @@ public: IMFSettingImpl() { } - taihe::array GetInputMethosdSync(bool enable) + taihe::array GetInputMethodsSync(bool enable) { - return InputMethodSettingImpl::GetInstance().GetInputMethosdSync(enable); + return InputMethodSettingImpl::GetInstance().GetInputMethodsSync(enable); } taihe::array ListCurrentInputMethodSubtypeSync() { diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp index c55fe42f0..676be6245 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -90,14 +90,20 @@ void InputMethodControllerImpl::AttachWithReason(bool showKeyboard, TextConfig_t TextConfig config; config.inputAttribute.inputPattern = textConfig.inputAttribute.textInputType.get_value(); config.inputAttribute.enterKeyType = textConfig.inputAttribute.enterKeyType.get_value(); - config.cursorInfo.left = textConfig.cursorInfo.left; - config.cursorInfo.top = textConfig.cursorInfo.top; - config.cursorInfo.width = textConfig.cursorInfo.width; - config.cursorInfo.height = textConfig.cursorInfo.height; - config.range.start = textConfig.selection.start; - config.range.end = textConfig.selection.end; - config.windowId = textConfig.windowId; - + if (textConfig.cursorInfo.has_value()) { + config.cursorInfo.left = textConfig.cursorInfo.value().left; + config.cursorInfo.top = textConfig.cursorInfo.value().top; + config.cursorInfo.width = textConfig.cursorInfo.value().width; + config.cursorInfo.height = textConfig.cursorInfo.value().height; + } + if (textConfig.selection.has_value()) { + config.range.start = textConfig.selection.value().start; + config.range.end = textConfig.selection.value().end; + } + if (textConfig.windowId.has_value()) { + config.windowId = textConfig.windowId.value(); + } + int32_t errCode = InputMethodController::GetInstance()->Attach(InputMethodTextChangedListener::GetInstance(), attachOptions, config, ClientType::JS); if (errCode != ErrorCode::NO_ERROR) { diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp index b7d3bec0f..502063779 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -32,7 +32,7 @@ InputMethodSettingImpl &InputMethodSettingImpl::GetInstance() return instance; } -array InputMethodSettingImpl::GetInputMethosdSync(bool enable) +array InputMethodSettingImpl::GetInputMethodsSync(bool enable) { std::vector properties; int32_t errCode = InputMethodController::GetInstance()->ListInputMethod(enable, properties); @@ -280,8 +280,8 @@ void InputMethodSettingImpl::OnPanelStatusChange(std::string const &type, const InputWindowInfo_t inputWindowInfo{ .name = info.name, .left = info.left, .top = info.top, - .width = static_cast(info.width), - .height = static_cast(info.height) }; + .width = static_cast(info.width), + .height = static_cast(info.height) }; taihe::array arrInfo{ inputWindowInfo }; auto &func = std::get)>>(cb->callback); func(arrInfo); -- Gitee From ed34ae044dc7d9487787b24b042fa2d758b503e9 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Tue, 20 May 2025 20:53:56 +0800 Subject: [PATCH 7/9] fix: Signed-off-by: weishaoxiong --- .../include/input_method_controller_impl.h | 2 ++ .../src/input_method_controller_impl.cpp | 24 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h index ca5d9db39..c84c9fb54 100644 --- a/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h +++ b/frameworks/ets/taihe/inputMethod/include/input_method_controller_impl.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "ani_common.h" #include "controller_listener.h" @@ -60,6 +61,7 @@ private: std::map>> jsCbMap_; static std::mutex controllerMutex_; static std::shared_ptr controller_; + static const std::set TEXT_EVENT_TYPE; }; class IMFControllerImpl { diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp index 676be6245..d149d463c 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_controller_impl.cpp @@ -29,6 +29,18 @@ namespace MiscServices { using namespace taihe; std::mutex InputMethodControllerImpl::controllerMutex_; std::shared_ptr InputMethodControllerImpl::controller_{ nullptr }; +const std::set InputMethodControllerImpl::TEXT_EVENT_TYPE{ + "insertText", + "deleteLeft", + "deleteRight", + "sendKeyboardStatus", + "sendFunctionKey", + "moveCursor", + "handleExtendAction", + "getLeftTextOfCursor", + "getRightTextOfCursor", + "getTextIndexAtCursor", +}; std::shared_ptr InputMethodControllerImpl::GetInstance() { if (controller_ == nullptr) { @@ -123,6 +135,14 @@ void InputMethodControllerImpl::DetachSync() void InputMethodControllerImpl::RegisterListener(std::string const &type, callbackType &&cb, uintptr_t opq) { + if (TEXT_EVENT_TYPE.find(type) != TEXT_EVENT_TYPE.end()) { + if (!InputMethodController::GetInstance()->WasAttached()) { + std::string message = JsUtils::ToMessage(IMFErrorCode::EXCEPTION_DETACHED) + "need to be attached first"; + set_business_error(IMFErrorCode::EXCEPTION_DETACHED, message); + IMSA_HILOGE("RegisterListener failed, need to be attached first type: %{public}s!", type.c_str()); + return; + } + } std::lock_guard lock(mutex_); ani_object callbackObj = reinterpret_cast(opq); ani_ref callbackRef; @@ -139,7 +159,7 @@ void InputMethodControllerImpl::RegisterListener(std::string const &type, callba }); if (isDuplicate) { env->GlobalReference_Delete(callbackRef); - IMSA_HILOGD("callback already registered, type: %{public}s!", type.c_str()); + IMSA_HILOGI("callback already registered, type: %{public}s!", type.c_str()); return; } cbVec.emplace_back(std::make_unique(cb, callbackRef)); @@ -184,9 +204,11 @@ void InputMethodControllerImpl::UnRegisterListener(std::string const &type, taih if (it != callbacks.end()) { it->get()->Release(); callbacks.erase(it); + IMSA_HILOGI("UnRegisterListener one type:%{public}s", type.c_str()); } if (callbacks.empty()) { jsCbMap_.erase(iter); + IMSA_HILOGI("UnRegisterListener callbacks is empty type:%{public}s", type.c_str()); } } -- Gitee From fb14487cfa34aff2452ebc250226d8c656454a13 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Wed, 21 May 2025 17:34:15 +0800 Subject: [PATCH 8/9] fix: Signed-off-by: weishaoxiong --- frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index 8afce5648..c2ba296e4 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -18,6 +18,9 @@ @!namespace("@ohos.inputMethod", "inputMethod") from ohos.inputMethod.Panel use PanelInfo; from ohos.InputMethodSubtype use InputMethodSubtype; +@!sts_inject(""" +static { loadLibrary("inputmethod_taihe_native.z") } +""") struct InputMethodProperty { @readonly packageName: String; -- Gitee From 6adee8c4914acfa19665ceda3fa117f696756395 Mon Sep 17 00:00:00 2001 From: weishaoxiong Date: Thu, 22 May 2025 10:59:07 +0800 Subject: [PATCH 9/9] fix: codecheck Signed-off-by: weishaoxiong --- frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe | 2 -- frameworks/ets/taihe/inputMethod/include/ani_common.h | 5 ++--- .../ets/taihe/inputMethod/src/input_method_setting_impl.cpp | 4 ---- .../ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp | 4 ---- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe index c2ba296e4..8fd2f5f1a 100644 --- a/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe +++ b/frameworks/ets/taihe/inputMethod/idl/ohos.inputMethod.taihe @@ -23,8 +23,6 @@ static { loadLibrary("inputmethod_taihe_native.z") } """) struct InputMethodProperty { - @readonly packageName: String; - @readonly methodId: String; @readonly name: String; @readonly id: String; @readonly label: Optional; diff --git a/frameworks/ets/taihe/inputMethod/include/ani_common.h b/frameworks/ets/taihe/inputMethod/include/ani_common.h index 7508d085d..756f4af3a 100644 --- a/frameworks/ets/taihe/inputMethod/include/ani_common.h +++ b/frameworks/ets/taihe/inputMethod/include/ani_common.h @@ -70,9 +70,7 @@ private: static_assert(std::is_same_v, Property>, "Invalid type for Property conversion"); InputMethodProperty_t result{}; - result.packageName = std::forward(obj).name; result.name = std::forward(obj).name; - result.methodId = obj.id; result.id = obj.id; result.label = taihe::optional(std::in_place_t{}, obj.label); result.labelId = taihe::optional(std::in_place_t{}, obj.labelId); @@ -113,7 +111,8 @@ struct CallbackObject { } void Release() { - if (auto *env = taihe::get_env()) { + taihe::env_guard guard; + if (auto *env = guard.get_env()) { env->GlobalReference_Delete(ref); } } diff --git a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp index 502063779..bf8a5085a 100644 --- a/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/input_method_setting_impl.cpp @@ -68,10 +68,6 @@ array InputMethodSettingImpl::ListInputMethodSubtypeSync( InputMethodProperty_t const &inputMethodProperty) { Property property{ .name = std::string(inputMethodProperty.name), .id = std::string(inputMethodProperty.id) }; - if (property.name.empty() || property.id.empty()) { - property.name = inputMethodProperty.packageName; - property.id = inputMethodProperty.methodId; - } if (property.name.empty() || property.id.empty()) { set_business_error(IMFErrorCode::EXCEPTION_PARAMCHECK, "name and id must be string and cannot empty"); IMSA_HILOGE("Property name and id must be string and cannot empty"); diff --git a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp index c7528ba74..a4f2c9ac3 100644 --- a/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp +++ b/frameworks/ets/taihe/inputMethod/src/ohos.inputMethod.impl.cpp @@ -101,10 +101,6 @@ bool SwitchInputMethodWithTarget(InputMethodProperty const &target) { std::string packageName(target.name); std::string id(target.id); - if (packageName.empty() || id.empty()) { - packageName = target.packageName; - id = target.methodId; - } if (packageName.empty() || id.empty()) { taihe::set_business_error(IMFErrorCode::EXCEPTION_PARAMCHECK, "packageName and methodId is empty"); IMSA_HILOGE("failed to switch input method, packageName or id is empty!"); -- Gitee