From a6fbbe5ff3acff3e6efdc2669dac91764235c950 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Fri, 4 Jul 2025 18:21:09 +0800 Subject: [PATCH 01/12] Plug-in Framework Signed-off-by: odxiaoying --- .../innerkits/event/include/plugin_stage.h | 107 ++++++ multimodalinput_mini.gni | 1 + service/BUILD.gn | 3 + .../libinput_adapter/src/libinput_adapter.cpp | 22 +- .../include/multimodal_input_plugin_manager.h | 93 +++++ service/module_loader/src/mmi_service.cpp | 2 + .../src/multimodal_input_plugin_manager.cpp | 346 ++++++++++++++++++ .../multimodal_input_plugin_manager_test.cpp | 139 +++++++ service/timer_manager/include/timer_manager.h | 8 +- service/timer_manager/src/timer_manager.cpp | 8 +- .../timer_manager/test/timer_manager_test.cpp | 15 + service/window_manager/test/mock.cpp | 2 +- 12 files changed, 736 insertions(+), 10 deletions(-) create mode 100644 interfaces/native/innerkits/event/include/plugin_stage.h create mode 100644 service/module_loader/include/multimodal_input_plugin_manager.h create mode 100644 service/module_loader/src/multimodal_input_plugin_manager.cpp create mode 100644 service/module_loader/test/multimodal_input_plugin_manager_test.cpp diff --git a/interfaces/native/innerkits/event/include/plugin_stage.h b/interfaces/native/innerkits/event/include/plugin_stage.h new file mode 100644 index 0000000000..bb9b09d3c4 --- /dev/null +++ b/interfaces/native/innerkits/event/include/plugin_stage.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024-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 PLUGIN_STAGE_H +#define PLUGIN_STAGE_H + +#include "key_event.h" +#include "pointer_event.h" +#include "axis_event.h" +#include "input_device.h" +#include "libinput.h" + +namespace OHOS { +namespace MMI { +// 可以用于注册插件的阶段枚举 +enum class InputPluginStage { + INPUT_GLOBAL_INIT = 0, // 全局预留,不允许注册 + INPUT_DEV_ADDED = 3, // 输入设备增加,该Hook不改变行为,仅感知变化 + INPUT_DEV_REMOVEED = 6, // 输入设备删除,该Hook不改变行为,仅感知变化 + INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT = 12, + INPUT_AFTER_LIBINPUT_ADAPTER_ON_EVENT = 13, + INPUT_BEFORE_NORMALIZED = 15, + INPUT_AFTER_NORMALIZED, // 支持添加Hook + INPUT_DEVICE_CHANGE = 20, // 支持添加Hook,该Hook不改变行为,仅感知变化 + INPUT_BEFORE_FILTER = 25, // 支持添加Hook + INPUT_AFTER_FILTER, // 支持添加Hook + INPUT_BEFORE_INTERCEPT = 30, // 支持添加Hook + INPUT_AFTER_INTERCEPT, // 支持添加Hook + INPUT_BEFORE_KEYCOMMAND = 35, // 支持添加Hook,仅在按键时会触发 + INPUT_AFTER_KEYCOMMAND, // 支持添加Hook,,仅在按键时会触发 + INPUT_BEFORE_MONITOR = 40, // 支持添加Hook + INPUT_AFTER_MONITOR, // 支持添加Hook + INPUT_STAGE_BUTT, +}; + +//  可以用于插件返回结论 +enum class PluginResult { + Error = -1, // 出错,视为未消费 + UseNeedReissue = 0, // 0:消费,不向后传递,如果中间和结束事件被消费,则框架补发cancel; + NotUse, // 1:未消费,继续向后派发 + UseNoNeedReissue, // 2:消费,中间事件由插件补发对应事件,无需框架补发cancel +}; + +// 事件派发阶段,该字段用于特殊定制,需要跳过中间环节往后派发事件的场景,但是不允许往前派发事件 +enum class InputDispatchStage { + Filter = 0, + Intercept, + KeyCommand, + Monitor, +}; + +// 不能删除中间的方法,除非所有插件都不使用该方法且统一重新编译 +// 独立的Context区分不同插件到多模方向的交互消息 +// 插件处理事件的方式有消费掉、修改后往后传递、直接往后传递、拦截等待后续条件判定、生成新事件 +// 事件是一条pipeline,在hook点处理完成后,不能返回hook点之前的流程;只能往后派发 +// 仅支持在多模工作线程调用context里面的方法 +struct IPluginContext { + // 调用线程:多模工作线程, 数量要求:同时添加的timer个数不大于3个 + virtual int32_t AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) = 0; + // 调用线程:多模工作线程 + virtual int32_t RemoveTimer(int32_t id) = 0; + // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 + void DispatchEvent(std::shared_ptr keyEvent, InputDispatchStage stage); + // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 + void DispatchEvent(std::shared_ptr pointerEvent, InputDispatchStage stage); + // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 + void DispatchEvent(std::shared_ptr AxisEvent, InputDispatchStage stage); + // libinputAdapter阶段专用 + virtual void DispatchEvent(libinput_event *event, int64_t frameTime) = 0; +}; + +/* 插件处理事件的方式有消费事件、修改后向后传递、直接向后传递、拦截等待后续条件判定、生成新事件 + * param:libinput_event为标准libinput输出的时间类型 + * InputEvent为通用事件类型,通过GetEventType获取具体的事件类型 + * return value 为int32_t值,=0:消费,不向后传递,如果中间和结束事件被消费,则框架补发cancel;=1:未消费 ,继续向后传递, <0 出错,视为未消费;>1 预留,视为无效,,视为未消费 +*/ +struct IInputPlugin { + virtual int32_t GetPriority() const = 0; + virtual const std::string GetVersion() const = 0; + virtual const std::string GetName() const = 0; + virtual InputPluginStage GetStage() const = 0; + virtual void DeviceWillAdded(std::shared_ptr inputDevice){}; + virtual void DeviceDidAdded(std::shared_ptr inputDevice){}; + virtual void DeviceWillRemoved(std::shared_ptr inputDevice){}; + virtual void DeviceDidRemoved(std::shared_ptr inputDevice){}; + // libinput 事件专用 + virtual PluginResult HandleEvent(libinput_event *event, int64_t frameTime) const = 0; + // 性能约束:耗时小于特定时间,比如0.1ms + virtual PluginResult HandleEvent(std::shared_ptr keyEvent, InputPluginStage stage) const = 0; + virtual PluginResult HandleEvent(std::shared_ptr pointerEvent, InputPluginStage stage) const = 0; + virtual PluginResult HandleEvent(std::shared_ptr axisEvent, InputPluginStage stage) const = 0; +}; +} // namespace MMI +} // namespace OHOS +#endif // PLUGIN_STAGE_H \ No newline at end of file diff --git a/multimodalinput_mini.gni b/multimodalinput_mini.gni index 1442967c4e..06d663acff 100644 --- a/multimodalinput_mini.gni +++ b/multimodalinput_mini.gni @@ -155,6 +155,7 @@ declare_args() { "module_loader/src/app_debug_listener.cpp", "module_loader/src/mmi_service.cpp", "module_loader/src/multimodal_input_preferences_manager.cpp", + "module_loader/src/multimodal_input_plugin_manager.cpp", "module_loader/src/uds_server.cpp", "module_loader/src/watchdog_task.cpp", "nap_process/src/nap_process.cpp", diff --git a/service/BUILD.gn b/service/BUILD.gn index ba2d108e1a..7b83f0c10e 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -1922,12 +1922,15 @@ ohos_unittest("ModuleLoaderTest") { "module_loader/test/uds_server_test.cpp", "module_loader/test/watchdog_task_test.cpp", "module_loader/test/multimodal_input_preferences_manager_test.cpp", + "module_loader/test/multimodal_input_plugin_manager_test.cpp", ] deps = [ "${mmi_path}/frameworks/proxy:libmmi-common", "${mmi_path}/service:libmmi-server", "${mmi_path}/util:libmmi-util", + "${mmi_path}/test/facility/libinput_wrapper:libinput_wrapper_sources", + "${mmi_path}/test/facility/virtual_device:virtual_device_sources", ] external_deps = [ diff --git a/service/libinput_adapter/src/libinput_adapter.cpp b/service/libinput_adapter/src/libinput_adapter.cpp index 6480cdbe63..1c51492942 100644 --- a/service/libinput_adapter/src/libinput_adapter.cpp +++ b/service/libinput_adapter/src/libinput_adapter.cpp @@ -32,6 +32,7 @@ #include "common_event_manager.h" #include "common_event_support.h" #endif // OHOS_BUILD_ENABLE_VKEYBOARD +#include "multimodal_input_plugin_manager.h" #undef MMI_LOG_DOMAIN #define MMI_LOG_DOMAIN MMI_LOG_SERVER @@ -217,7 +218,26 @@ bool LibinputAdapter::Init(FunInputEvent funInputEvent) { CALL_DEBUG_ENTER; CHKPF(funInputEvent); - funInputEvent_ = funInputEvent; + + auto callback = [funInputEvent](libinput_event *event, int64_t frameTime) { + funInputEvent(static_cast(event), frameTime); + }; + auto manager = InputPluginManager::GetInstance(); + if (manager != nullptr) { + manager->PluginAssignmentCallBack(callback, InputPluginStage::INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT); + } + funInputEvent_ = [manager, callback](void *event, int64_t frameTime) { + if (manager != nullptr) { + int32_t result = manager->HandleEvent(static_cast(event), + frameTime, + InputPluginStage::INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT); + if (result != 0) { + return; + } + } + callback(static_cast(event), frameTime); + }; + input_ = libinput_path_create_context(&LIBINPUT_INTERFACE, nullptr); CHKPF(input_); libinput_log_set_handler(input_, &HiLogFunc); diff --git a/service/module_loader/include/multimodal_input_plugin_manager.h b/service/module_loader/include/multimodal_input_plugin_manager.h new file mode 100644 index 0000000000..56e0728dfa --- /dev/null +++ b/service/module_loader/include/multimodal_input_plugin_manager.h @@ -0,0 +1,93 @@ +/* + * 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 MULTIMODAL_INPUT_PLUGIN_MANAGER_H +#define MULTIMODAL_INPUT_PLUGIN_MANAGER_H + +#include +#include + +#include +#include +#include + +namespace OHOS { +namespace MMI { + +/* 框架获取plugin对象 + * ctx: 框架注册给plugin调用框架的对象实例 + * plugin:plugin实例 + * return:= 0: success + * !=0: error + */ +typedef int32_t (*InitPlugin)(std::shared_ptr ctx, std::shared_ptr& plugin); +/* 框架通知plugin删除plugin对象 + * ctx: 框架注册给plugin调用框架的对象实例 + * plugin:plugin实例 + * return:= 0: success + * !=0: error + */ +typedef int32_t (*UnintPlugin)(std::shared_ptr plugin); + +struct InputPlugin : public IPluginContext { +public: + InputPlugin() {}; + virtual ~InputPlugin(); + int32_t Init(std::shared_ptr pin); + void UnInit(); + PluginResult HandleEvent(libinput_event *event, int64_t frameTime); + + int32_t AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) override; + int32_t RemoveTimer(int32_t id) override; + void DispatchEvent(libinput_event *event, int64_t frameTime) override; + + int32_t timerCnt_ = 0; + int32_t prio_ = 200; + std::function callback_; + UnintPlugin unintPlugin_ = nullptr; + std::shared_ptr plugin_; + std::string name_; + void* handle_; + +private: + std::mutex timerMutex_; + InputPluginStage stage_; +}; + +struct InputPluginManager { +public: + ~InputPluginManager(); + explicit InputPluginManager(const std::string& directory) : directory_(directory) {}; + static std::shared_ptr GetInstance(const std::string &directory = ""); + int32_t Init(); + void Dump(int fd); + int32_t HandleEvent(libinput_event* event, int64_t frameTime, InputPluginStage stage); + void PluginAssignmentCallBack(std::function callback, InputPluginStage stage); + void PrintPlugins(); + int32_t DoHandleEvent(libinput_event *event, int64_t frameTime, InputPlugin *iplugin, InputPluginStage stage); + +private: + bool IntermediateEndEvent(libinput_event *event); + bool LoadPlugin(const std::string &path); + + std::string directory_; + std::map>> plugins_; + static std::shared_ptr instance_; + static std::once_flag init_flag_; + static std::mutex mutex_; +}; +} // namespace MMI +} // namespace OHOS +#endif // MULTIMODAL_INPUT_PLUGIN_MANAGER_H diff --git a/service/module_loader/src/mmi_service.cpp b/service/module_loader/src/mmi_service.cpp index 29c1c9a7dd..4352735ca7 100644 --- a/service/module_loader/src/mmi_service.cpp +++ b/service/module_loader/src/mmi_service.cpp @@ -66,6 +66,7 @@ #include "touchpad_settings_handler.h" #include "account_manager.h" #endif // OHOS_BUILD_ENABLE_POINTER +#include "multimodal_input_plugin_manager.h" #ifdef OHOS_RSS_CLIENT #include "res_sched_client.h" @@ -404,6 +405,7 @@ int32_t MMIService::Init() NapProcess::GetInstance()->Init(*this); MMI_HILOGD("ANRManager Init"); ANRMgr->Init(*this); + InputPluginManager::GetInstance()->Init(); MMI_HILOGI("PointerDrawingManager Init"); #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING) if (!CursorDrawingComponent::GetInstance().Init()) { diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp new file mode 100644 index 0000000000..7e0c0be689 --- /dev/null +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -0,0 +1,346 @@ +/* + * 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 "multimodal_input_plugin_manager.h" + +#include "mmi_log.h" +#include + +#undef MMI_LOG_DOMAIN +#define MMI_LOG_DOMAIN MMI_LOG_SERVER +#undef MMI_LOG_TAG +#define MMI_LOG_TAG "MultiModalInputPluginManager" + +namespace OHOS { +namespace MMI { +std::shared_ptr InputPluginManager::instance_; +std::once_flag InputPluginManager::init_flag_; +std::mutex InputPluginManager::mutex_; + +const char *FILE_EXTENSION = ".so"; +const char *FOLDER_PATH = "/system/lib64/multimodalinput/module/autorun"; +const int32_t TIMEOUT_US = 300; +const int32_t MAX_TIMER = 3; + +InputPluginManager::~InputPluginManager() +{ + std::lock_guard lock(mutex_); + plugins_.clear(); + if (instance_ != nullptr) { + instance_ = nullptr; + } + MMI_HILOGI("~InputPluginManager"); +} + +std::shared_ptr InputPluginManager::GetInstance(const std::string &directory) +{ + std::call_once(init_flag_, [&directory] { + if (instance_ == nullptr) { + std::lock_guard lock(mutex_); + if (instance_ == nullptr) { + MMI_HILOGI("New InputPluginManager"); + std::string dir = directory.empty() ? FOLDER_PATH : directory; + instance_ = std::make_shared(dir); + } + } + }); + return instance_; +} + +int32_t InputPluginManager::Init() +{ + CALL_DEBUG_ENTER; + DIR *dir = opendir(directory_.c_str()); + if (!dir) { + MMI_HILOGE("Failed to open error:%{private}s", strerror(errno)); + return 0; + } + struct dirent *entry; + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_type == DT_REG && std::string(entry->d_name) != "." && std::string(entry->d_name) != "..") { + std::string path = directory_ + "/" + entry->d_name; + if (path.length() >= strlen(FILE_EXTENSION) && + path.substr(path.size() - strlen(FILE_EXTENSION)) == FILE_EXTENSION) { + LoadPlugin(path); + } + } + } + closedir(dir); + PrintPlugins(); + return 0; +} + +bool InputPluginManager::LoadPlugin(const std::string &path) +{ + CALL_DEBUG_ENTER; + void *handle = dlopen(path.c_str(), RTLD_LAZY); + if (!handle) { + MMI_HILOGE("Failed to load directory: %{private}s", dlerror()); + return false; + } + + InitPlugin func = reinterpret_cast(dlsym(handle, "InitPlugin")); + if (!func) { + MMI_HILOGE("Failed to find symbol InitPlugin in: %{private}s", dlerror()); + dlclose(handle); + return false; + } + + std::shared_ptr cPin = std::make_shared(); + if (!cPin) { + dlclose(handle); + return false; + } + + cPin->unintPlugin_ = reinterpret_cast(dlsym(handle, "UnintPlugin")); + if (!cPin->unintPlugin_) { + MMI_HILOGE("Failed to find symbol UnintPlugin in: %{private}s", dlerror()); + dlclose(handle); + return false; + } + std::shared_ptr iPin; + int32_t ret = func(cPin, iPin); + if (ret != 0 || !iPin) { + MMI_HILOGE("Failed to InitPlugin plugin."); + dlclose(handle); + return false; + } + ret = cPin->Init(iPin); + if (ret != 0) { + MMI_HILOGE("Failed to Init plugin."); + dlclose(handle); + return false; + } + cPin->handle_ = handle; + InputPluginStage stage = iPin->GetStage(); + + auto result = plugins_.insert({stage, {cPin}}); + if (!result.second) { + auto it = std::lower_bound(result.first->second.begin(), result.first->second.end(), cPin, + [](const std::shared_ptr &a, const std::shared_ptr &b) { + return a->prio_ < b->prio_; + }); + result.first->second.insert(it, cPin); + } + return true; +} + +void InputPluginManager::PrintPlugins() +{ + for (const auto &stagePlugins : plugins_) { + MMI_HILOGI("InputPluginManager InputPluginStage : %{public}d", stagePlugins.first); + for (const auto &plugin : stagePlugins.second) { + MMI_HILOGI("InputPluginManager : name:%{public}s prio_:%{public}d", + plugin->name_.c_str(), plugin->prio_); + } + } +} + +void InputPluginManager::PluginAssignmentCallBack( + std::function callback, InputPluginStage stage) +{ + CALL_DEBUG_ENTER; + auto it = plugins_.find(stage); + if (it == plugins_.end()) { + MMI_HILOGI("plugins_ not stage:%{public}d.", stage); + return; + } + for (auto &plugin : it->second) { + plugin->callback_ = callback; + } +} + +int32_t InputPluginManager::HandleEvent(libinput_event *event, int64_t frameTime, InputPluginStage stage) +{ + return DoHandleEvent(event, frameTime, nullptr, stage); +} + +int32_t InputPluginManager::DoHandleEvent( + libinput_event *event, int64_t frameTime, InputPlugin *iplugin, InputPluginStage stage) +{ + if (event == nullptr) { + return 0; + } + auto it = plugins_.find(stage); + if (it == plugins_.end()) { + return 0; + } + CALL_DEBUG_ENTER; + auto &plugins = it->second; + auto start_plugin = plugins.begin(); + if (iplugin != nullptr) { + auto cur_plugin = std::find_if(plugins.begin(), plugins.end(), + [iplugin](const std::shared_ptr &plugin) { return plugin.get() == iplugin; }); + if (cur_plugin == plugins.end()) { + return 0; + } + start_plugin = std::next(cur_plugin); + } + int64_t beginTime = 0; + PluginResult result; + int64_t endTime = 0; + int64_t lostTime = 0; + for (auto pluginIt = start_plugin; pluginIt != plugins.end(); ++pluginIt) { + beginTime = GetSysClockTime(); + result = (*pluginIt)->HandleEvent(event, frameTime); + endTime = GetSysClockTime(); + lostTime = endTime - beginTime; + if (lostTime >= TIMEOUT_US) { + MMI_HILOGE("pluginIt timeout name:%{public}s ,endTime:%{public}" PRId64 ",lostTime:%{public}" PRId64, + (*pluginIt)->name_.c_str(), endTime, lostTime); + } + if (result == PluginResult::UseNeedReissue) { + if (IntermediateEndEvent(event)) { + MMI_HILOGE("pluginIt is intermediate or end event"); + continue; + } + return 1; + } else if (result == PluginResult::UseNoNeedReissue) { + return 1; + } else if (result == PluginResult::Error) { + MMI_HILOGE("pluginIt err name:%{public}s", (*pluginIt)->name_.c_str()); + } + } + return 0; +} + +// LIBINPUT_EVENT_TABLET_TOOL_BUTTON、LIBINPUT_EVENT_TABLET_PAD_BUTTON、LIBINPUT_EVENT_TABLET_PAD_KEY +// These few existence termination events are currently not used and will be supplemented after use +bool InputPluginManager::IntermediateEndEvent(libinput_event *event) +{ + const libinput_event_type type = libinput_event_get_type(event); + switch (type) { + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: + case LIBINPUT_EVENT_POINTER_AXIS: + case LIBINPUT_EVENT_POINTER_SCROLL_FINGER: + case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS: + case LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD: + case LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END: + case LIBINPUT_EVENT_JOYSTICK_AXIS: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_CANCEL: + case LIBINPUT_EVENT_TOUCHPAD_UP: + case LIBINPUT_EVENT_TOUCHPAD_MOTION: + case LIBINPUT_EVENT_TABLET_TOOL_AXIS: + case LIBINPUT_EVENT_TABLET_PAD_RING: + case LIBINPUT_EVENT_TABLET_PAD_STRIP: + case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: + case LIBINPUT_EVENT_GESTURE_SWIPE_END: + case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: + case LIBINPUT_EVENT_GESTURE_PINCH_END: + case LIBINPUT_EVENT_GESTURE_HOLD_END: + return true; + case LIBINPUT_EVENT_KEYBOARD_KEY: { + struct libinput_event_keyboard *keyboardEvent = libinput_event_get_keyboard_event(event); + CHKPR(keyboardEvent, false); + return libinput_event_keyboard_get_key_state(keyboardEvent) == LIBINPUT_KEY_STATE_RELEASED; + } + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_TAP: + case LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD: { + auto touchpadButtonEvent = libinput_event_get_pointer_event(event); + CHKPR(touchpadButtonEvent, false); + return libinput_event_pointer_get_button_state(touchpadButtonEvent) == LIBINPUT_BUTTON_STATE_RELEASED; + } + case LIBINPUT_EVENT_JOYSTICK_BUTTON: { + auto rawBtnEvent = libinput_event_get_joystick_button_event(event); + CHKPR(rawBtnEvent, false); + return libinput_event_joystick_button_get_key_state(rawBtnEvent) == LIBINPUT_BUTTON_STATE_RELEASED; + } + case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: { + auto tabletEvent = libinput_event_get_tablet_tool_event(event); + CHKPR(tabletEvent, false); + return libinput_event_tablet_tool_get_proximity_state(tabletEvent) == + LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT; + } + case LIBINPUT_EVENT_TABLET_TOOL_TIP: { + auto tabletEvent = libinput_event_get_tablet_tool_event(event); + CHKPR(tabletEvent, false); + return libinput_event_tablet_tool_get_tip_state(tabletEvent) == LIBINPUT_TABLET_TOOL_TIP_UP; + } + default: + break; + } + return false; +} + +int32_t InputPlugin::Init(std::shared_ptr pin) +{ + name_ = pin->GetName(); + prio_ = pin->GetPriority(); + stage_ = pin->GetStage(); + plugin_ = pin; + return 0; +} + +void InputPlugin::UnInit() +{ + CHKPV(plugin_); + MMI_HILOGI("InputPlugin UnInit Start name:%{public}s.", name_.c_str()); + if (unintPlugin_) { + unintPlugin_(plugin_); + } +} + +void InputPlugin::DispatchEvent(libinput_event *event, int64_t frameTime) +{ + int32_t result = InputPluginManager::GetInstance()->DoHandleEvent(event, frameTime, this, stage_); + if (result == 0) { + CHKPV(callback_); + callback_(event, frameTime); + } +} + +PluginResult InputPlugin::HandleEvent(libinput_event *event, int64_t frameTime) +{ + CHKPR(plugin_, PluginResult::NotUse); + return plugin_->HandleEvent(event, frameTime); +} + +int32_t InputPlugin::AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) +{ + std::lock_guard lock(timerMutex_); + if (timerCnt_ >= MAX_TIMER) { + return -1; + } + int32_t timerId = TimerMgr->AddTimerInternal(intervalMs, repeatCount, func, name_); + if (timerId != -1) { + timerCnt_++; + } + return timerId; +} + +int32_t InputPlugin::RemoveTimer(int32_t id) +{ + std::lock_guard lock(timerMutex_); + int32_t result = TimerMgr->RemoveTimer(id, name_); + if (timerCnt_ > 0) { + timerCnt_--; + } + return result; +} + +InputPlugin::~InputPlugin() +{ + if (handle_) { + dlclose(handle_); + handle_ = nullptr; + } + MMI_HILOGI("~InputPlugin"); +} +} // namespace MMI +} // namespace OHOS diff --git a/service/module_loader/test/multimodal_input_plugin_manager_test.cpp b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp new file mode 100644 index 0000000000..8bb5b8fdd4 --- /dev/null +++ b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp @@ -0,0 +1,139 @@ +/* + * 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 +#include + +#include "general_mouse.h" +#include "libinput_wrapper.h" +#include "multimodal_input_plugin_manager.h" + +#undef MMI_LOG_TAG +#define MMI_LOG_TAG "MultimodalInputPluginManagerTest" +namespace OHOS { +namespace MMI { +namespace { +using namespace testing::ext; +} // namespace + +const std::string PATH { "/system/lib64/multimodalinput/module/autorun" }; + +class MultimodalInputPluginManagerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static void SetupMouse(); + static void CloseMouse(); + + void SetUp(); +private: + std::shared_ptr manager; + static LibinputWrapper libinput_; + static GeneralMouse vMouse_; +}; + +GeneralMouse MultimodalInputPluginManagerTest::vMouse_; +LibinputWrapper MultimodalInputPluginManagerTest::libinput_; + + +void MultimodalInputPluginManagerTest::SetUpTestCase(void) +{ + ASSERT_TRUE(libinput_.Init()); + SetupMouse(); +} + +void MultimodalInputPluginManagerTest::TearDownTestCase(void) +{ + CloseMouse(); +} + +void MultimodalInputPluginManagerTest::SetupMouse() +{ + ASSERT_TRUE(vMouse_.SetUp()); + std::cout << "device node name: " << vMouse_.GetDevPath() << std::endl; + ASSERT_TRUE(libinput_.AddPath(vMouse_.GetDevPath())); + + libinput_event *event = libinput_.Dispatch(); + ASSERT_TRUE(event != nullptr); + ASSERT_EQ(libinput_event_get_type(event), LIBINPUT_EVENT_DEVICE_ADDED); +} + +void MultimodalInputPluginManagerTest::CloseMouse() +{ + libinput_.RemovePath(vMouse_.GetDevPath()); + vMouse_.Close(); +} + +void MultimodalInputPluginManagerTest::SetUp() +{ + manager = std::make_shared(PATH); +} + +/** + * @tc.name : MultimodalInputPluginManagerTest_Init_001 + * @tc.number: Init_001 + * @tc.desc : 测试初始化是否成功 + */ +HWTEST_F(MultimodalInputPluginManagerTest, MultimodalInputPluginManagerTest_Init_001, TestSize.Level0) { + int32_t valV1 = manager->Init(); + EXPECT_EQ(valV1, RET_OK); +} + +/** + * @tc.name: MultimodalInputPluginManagerTest_HandleEvent_02 + * @tc.desc: Test_HandleEvent_02 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(MultimodalInputPluginManagerTest, MultimodalInputPluginManagerTest_HandleEvent_02, TestSize.Level1) +{ + CALL_TEST_DEBUG; + vMouse_.SendEvent(EV_REL, REL_X, 5); + vMouse_.SendEvent(EV_REL, REL_Y, -10); + vMouse_.SendEvent(EV_SYN, SYN_REPORT, 0); + + libinput_event *event = libinput_.Dispatch(); + ASSERT_TRUE(event != nullptr); + struct libinput_device *dev = libinput_event_get_device(event); + ASSERT_TRUE(dev != nullptr); + std::cout << "pointer device: " << libinput_device_get_name(dev) << std::endl; + int32_t result = manager->HandleEvent(event, GetSysClockTime(), + InputPluginStage::INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT); + EXPECT_GE(result, 0); +} + +/** + * @tc.name: MultimodalInputPluginManagerTest_IntermediateEndEvent_03 + * @tc.desc: Test_IntermediateEndEvent_03 + * @tc.require: + */ +HWTEST_F(MultimodalInputPluginManagerTest, MultimodalInputPluginManagerTest_IntermediateEndEvent_03, TestSize.Level1) +{ + CALL_TEST_DEBUG; + vMouse_.SendEvent(EV_REL, REL_X, 5); + vMouse_.SendEvent(EV_REL, REL_Y, -10); + vMouse_.SendEvent(EV_SYN, SYN_REPORT, 0); + + libinput_event *event = libinput_.Dispatch(); + ASSERT_TRUE(event != nullptr); + struct libinput_device *dev = libinput_event_get_device(event); + ASSERT_TRUE(dev != nullptr); + std::cout << "pointer device: " << libinput_device_get_name(dev) << std::endl; + + EXPECT_TRUE(manager->IntermediateEndEvent(event)); +} + +} // namespace MMI +} // namespace OHOS diff --git a/service/timer_manager/include/timer_manager.h b/service/timer_manager/include/timer_manager.h index d8395cf0cb..6ad0f61670 100644 --- a/service/timer_manager/include/timer_manager.h +++ b/service/timer_manager/include/timer_manager.h @@ -54,11 +54,13 @@ public: const std::string &name = ""); int32_t AddLongTimer(int32_t intervalMs, int32_t repeatCount, std::function callback, const std::string &name = ""); - int32_t RemoveTimer(int32_t timerId); + int32_t RemoveTimer(int32_t timerId, const std::string &name = ""); int32_t ResetTimer(int32_t timerId); bool IsExist(int32_t timerId); int32_t CalcNextDelay(); void ProcessTimers(); + int32_t AddTimerInternal(int32_t intervalMs, int32_t repeatCount, std::function callback, + const std::string &name = ""); private: struct TimerItem { @@ -72,9 +74,7 @@ private: }; private: int32_t TakeNextTimerId(); - int32_t AddTimerInternal(int32_t intervalMs, int32_t repeatCount, std::function callback, - const std::string &name = ""); - int32_t RemoveTimerInternal(int32_t timerId); + int32_t RemoveTimerInternal(int32_t timerId, const std::string &name = ""); int32_t ResetTimerInternal(int32_t timerId); bool IsExistInternal(int32_t timerId); void InsertTimerInternal(std::unique_ptr& timer); diff --git a/service/timer_manager/src/timer_manager.cpp b/service/timer_manager/src/timer_manager.cpp index ccd8d6373f..2fb5199354 100644 --- a/service/timer_manager/src/timer_manager.cpp +++ b/service/timer_manager/src/timer_manager.cpp @@ -56,9 +56,9 @@ int32_t TimerManager::AddLongTimer(int32_t intervalMs, int32_t repeatCount, std: return AddTimerInternal(intervalMs, repeatCount, callback, name); } -int32_t TimerManager::RemoveTimer(int32_t timerId) +int32_t TimerManager::RemoveTimer(int32_t timerId, const std::string &name) { - return RemoveTimerInternal(timerId); + return RemoveTimerInternal(timerId, name); } int32_t TimerManager::ResetTimer(int32_t timerId) @@ -125,11 +125,11 @@ int32_t TimerManager::AddTimerInternal(int32_t intervalMs, int32_t repeatCount, return timerId; } -int32_t TimerManager::RemoveTimerInternal(int32_t timerId) +int32_t TimerManager::RemoveTimerInternal(int32_t timerId, const std::string &name) { std::lock_guard lock(timerMutex_); for (auto it = timers_.begin(); it != timers_.end(); ++it) { - if ((*it)->id == timerId) { + if ((*it)->id == timerId && (name.empty() || (*it)->name == name)) { timers_.erase(it); return RET_OK; } diff --git a/service/timer_manager/test/timer_manager_test.cpp b/service/timer_manager/test/timer_manager_test.cpp index bbddc7fe5f..674919c30d 100644 --- a/service/timer_manager/test/timer_manager_test.cpp +++ b/service/timer_manager/test/timer_manager_test.cpp @@ -114,6 +114,21 @@ HWTEST_F(TimerManagerTest, TimerManagerTest_ManagerTimer_005, TestSize.Level1) EXPECT_EQ(timerld, -1); } +/** + * @tc.name: TimerManagerTest_ManagerTimer_006 + * @tc.desc: Test the function RemoveTimer + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(TimerManagerTest, TimerManagerTest_ManagerTimer_006, TestSize.Level1) +{ + CALL_TEST_DEBUG; + int32_t repeatCount = 3; + int32_t intervalMs = 1000; + int32_t timerld = TimerMgr->AddTimerInternal(intervalMs, repeatCount, AddTimerCallback, "test006"); + ASSERT_EQ(TimerMgr->RemoveTimer(timerld, "test006"), 0); +} + /** * @tc.name: TimerManagerTest_AddTimer_001 * @tc.desc: Test adding a timer to the TimerManager diff --git a/service/window_manager/test/mock.cpp b/service/window_manager/test/mock.cpp index 55cbd2e9ce..29bd3a2134 100644 --- a/service/window_manager/test/mock.cpp +++ b/service/window_manager/test/mock.cpp @@ -170,7 +170,7 @@ int32_t TimerManager::AddTimer(int32_t intervalMs, int32_t repeatCount, std::fun return 0; } -int32_t TimerManager::RemoveTimer(int32_t timerId) +int32_t TimerManager::RemoveTimer(int32_t timerId, const std::string &name) { return 0; } -- Gitee From 1d660dd4e11bb7c811306140c266a48e519ac235 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 06:10:04 +0000 Subject: [PATCH 02/12] update service/module_loader/src/multimodal_input_plugin_manager.cpp. Signed-off-by: odxiaoying --- service/module_loader/src/multimodal_input_plugin_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp index 7e0c0be689..04fa28c885 100644 --- a/service/module_loader/src/multimodal_input_plugin_manager.cpp +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -30,7 +30,7 @@ std::once_flag InputPluginManager::init_flag_; std::mutex InputPluginManager::mutex_; const char *FILE_EXTENSION = ".so"; -const char *FOLDER_PATH = "/system/lib64/multimodalinput/module/autorun"; +const char *FOLDER_PATH = "/system/lib64/multimodalinput/autorun"; const int32_t TIMEOUT_US = 300; const int32_t MAX_TIMER = 3; -- Gitee From a4c4f574e018f323c447aaded5879b5aa6571759 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 06:24:19 +0000 Subject: [PATCH 03/12] update service/module_loader/test/multimodal_input_plugin_manager_test.cpp. Signed-off-by: odxiaoying --- .../module_loader/test/multimodal_input_plugin_manager_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/module_loader/test/multimodal_input_plugin_manager_test.cpp b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp index 8bb5b8fdd4..494afc386f 100644 --- a/service/module_loader/test/multimodal_input_plugin_manager_test.cpp +++ b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp @@ -28,7 +28,7 @@ namespace { using namespace testing::ext; } // namespace -const std::string PATH { "/system/lib64/multimodalinput/module/autorun" }; +const std::string PATH { "/system/lib64/multimodalinput/autorun" }; class MultimodalInputPluginManagerTest : public testing::Test { public: -- Gitee From 6e74e224e20447940bf9f6367ebf458f65f04f10 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 10:09:30 +0000 Subject: [PATCH 04/12] update interfaces/native/innerkits/event/include/plugin_stage.h. Signed-off-by: odxiaoying --- .../innerkits/event/include/plugin_stage.h | 56 ++++++------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/interfaces/native/innerkits/event/include/plugin_stage.h b/interfaces/native/innerkits/event/include/plugin_stage.h index bb9b09d3c4..5a43f65aa6 100644 --- a/interfaces/native/innerkits/event/include/plugin_stage.h +++ b/interfaces/native/innerkits/event/include/plugin_stage.h @@ -24,36 +24,34 @@ namespace OHOS { namespace MMI { -// 可以用于注册插件的阶段枚举 + enum class InputPluginStage { - INPUT_GLOBAL_INIT = 0, // 全局预留,不允许注册 - INPUT_DEV_ADDED = 3, // 输入设备增加,该Hook不改变行为,仅感知变化 - INPUT_DEV_REMOVEED = 6, // 输入设备删除,该Hook不改变行为,仅感知变化 + INPUT_GLOBAL_INIT = 0, + INPUT_DEV_ADDED = 3, + INPUT_DEV_REMOVEED = 6, INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT = 12, INPUT_AFTER_LIBINPUT_ADAPTER_ON_EVENT = 13, INPUT_BEFORE_NORMALIZED = 15, - INPUT_AFTER_NORMALIZED, // 支持添加Hook - INPUT_DEVICE_CHANGE = 20, // 支持添加Hook,该Hook不改变行为,仅感知变化 - INPUT_BEFORE_FILTER = 25, // 支持添加Hook - INPUT_AFTER_FILTER, // 支持添加Hook - INPUT_BEFORE_INTERCEPT = 30, // 支持添加Hook - INPUT_AFTER_INTERCEPT, // 支持添加Hook - INPUT_BEFORE_KEYCOMMAND = 35, // 支持添加Hook,仅在按键时会触发 - INPUT_AFTER_KEYCOMMAND, // 支持添加Hook,,仅在按键时会触发 - INPUT_BEFORE_MONITOR = 40, // 支持添加Hook - INPUT_AFTER_MONITOR, // 支持添加Hook + INPUT_AFTER_NORMALIZED, + INPUT_DEVICE_CHANGE = 20, + INPUT_BEFORE_FILTER = 25, + INPUT_AFTER_FILTER, + INPUT_BEFORE_INTERCEPT = 30, + INPUT_AFTER_INTERCEPT, + INPUT_BEFORE_KEYCOMMAND = 35, + INPUT_AFTER_KEYCOMMAND, + INPUT_BEFORE_MONITOR = 40, + INPUT_AFTER_MONITOR, INPUT_STAGE_BUTT, }; -//  可以用于插件返回结论 enum class PluginResult { - Error = -1, // 出错,视为未消费 - UseNeedReissue = 0, // 0:消费,不向后传递,如果中间和结束事件被消费,则框架补发cancel; - NotUse, // 1:未消费,继续向后派发 - UseNoNeedReissue, // 2:消费,中间事件由插件补发对应事件,无需框架补发cancel + Error = -1, + UseNeedReissue = 0, + NotUse, + UseNoNeedReissue, }; -// 事件派发阶段,该字段用于特殊定制,需要跳过中间环节往后派发事件的场景,但是不允许往前派发事件 enum class InputDispatchStage { Filter = 0, Intercept, @@ -61,31 +59,15 @@ enum class InputDispatchStage { Monitor, }; -// 不能删除中间的方法,除非所有插件都不使用该方法且统一重新编译 -// 独立的Context区分不同插件到多模方向的交互消息 -// 插件处理事件的方式有消费掉、修改后往后传递、直接往后传递、拦截等待后续条件判定、生成新事件 -// 事件是一条pipeline,在hook点处理完成后,不能返回hook点之前的流程;只能往后派发 -// 仅支持在多模工作线程调用context里面的方法 struct IPluginContext { - // 调用线程:多模工作线程, 数量要求:同时添加的timer个数不大于3个 virtual int32_t AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) = 0; - // 调用线程:多模工作线程 virtual int32_t RemoveTimer(int32_t id) = 0; - // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 void DispatchEvent(std::shared_ptr keyEvent, InputDispatchStage stage); - // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 void DispatchEvent(std::shared_ptr pointerEvent, InputDispatchStage stage); - // 调用线程:多模工作线程, 避免在hook过程中调用该接口,以免形成死循环 void DispatchEvent(std::shared_ptr AxisEvent, InputDispatchStage stage); - // libinputAdapter阶段专用 virtual void DispatchEvent(libinput_event *event, int64_t frameTime) = 0; }; -/* 插件处理事件的方式有消费事件、修改后向后传递、直接向后传递、拦截等待后续条件判定、生成新事件 - * param:libinput_event为标准libinput输出的时间类型 - * InputEvent为通用事件类型,通过GetEventType获取具体的事件类型 - * return value 为int32_t值,=0:消费,不向后传递,如果中间和结束事件被消费,则框架补发cancel;=1:未消费 ,继续向后传递, <0 出错,视为未消费;>1 预留,视为无效,,视为未消费 -*/ struct IInputPlugin { virtual int32_t GetPriority() const = 0; virtual const std::string GetVersion() const = 0; @@ -95,9 +77,7 @@ struct IInputPlugin { virtual void DeviceDidAdded(std::shared_ptr inputDevice){}; virtual void DeviceWillRemoved(std::shared_ptr inputDevice){}; virtual void DeviceDidRemoved(std::shared_ptr inputDevice){}; - // libinput 事件专用 virtual PluginResult HandleEvent(libinput_event *event, int64_t frameTime) const = 0; - // 性能约束:耗时小于特定时间,比如0.1ms virtual PluginResult HandleEvent(std::shared_ptr keyEvent, InputPluginStage stage) const = 0; virtual PluginResult HandleEvent(std::shared_ptr pointerEvent, InputPluginStage stage) const = 0; virtual PluginResult HandleEvent(std::shared_ptr axisEvent, InputPluginStage stage) const = 0; -- Gitee From 4d3e0bd47a5aa512006eb854c78bc7a13812edf2 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 10:31:03 +0000 Subject: [PATCH 05/12] update service/module_loader/src/multimodal_input_plugin_manager.cpp. Signed-off-by: odxiaoying --- .../src/multimodal_input_plugin_manager.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp index 04fa28c885..e628ff8aee 100644 --- a/service/module_loader/src/multimodal_input_plugin_manager.cpp +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -46,14 +46,11 @@ InputPluginManager::~InputPluginManager() std::shared_ptr InputPluginManager::GetInstance(const std::string &directory) { - std::call_once(init_flag_, [&directory] { + std::call_once(init_flag_, [this, &directory] { if (instance_ == nullptr) { - std::lock_guard lock(mutex_); - if (instance_ == nullptr) { - MMI_HILOGI("New InputPluginManager"); - std::string dir = directory.empty() ? FOLDER_PATH : directory; - instance_ = std::make_shared(dir); - } + MMI_HILOGI("New InputPluginManager"); + std::string dir = directory.empty() ? FOLDER_PATH : directory; + instance_ = std::make_shared(dir); } }); return instance_; @@ -193,6 +190,9 @@ int32_t InputPluginManager::DoHandleEvent( int64_t endTime = 0; int64_t lostTime = 0; for (auto pluginIt = start_plugin; pluginIt != plugins.end(); ++pluginIt) { + if ((*pluginIt) == nullptr) { + continue; + } beginTime = GetSysClockTime(); result = (*pluginIt)->HandleEvent(event, frameTime); endTime = GetSysClockTime(); -- Gitee From 8fc04e7df5f40e005a883949e068e5e25a3c1f93 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:03:04 +0000 Subject: [PATCH 06/12] update service/module_loader/src/multimodal_input_plugin_manager.cpp. Signed-off-by: odxiaoying --- service/module_loader/src/multimodal_input_plugin_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp index e628ff8aee..623013c2dd 100644 --- a/service/module_loader/src/multimodal_input_plugin_manager.cpp +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -46,7 +46,7 @@ InputPluginManager::~InputPluginManager() std::shared_ptr InputPluginManager::GetInstance(const std::string &directory) { - std::call_once(init_flag_, [this, &directory] { + std::call_once(init_flag_, [&directory] { if (instance_ == nullptr) { MMI_HILOGI("New InputPluginManager"); std::string dir = directory.empty() ? FOLDER_PATH : directory; -- Gitee From 9ef49e2d59cb1bffc027b3cb8f70d5d682c97816 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:32:41 +0000 Subject: [PATCH 07/12] update service/module_loader/include/multimodal_input_plugin_manager.h. Signed-off-by: odxiaoying --- .../module_loader/include/multimodal_input_plugin_manager.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/service/module_loader/include/multimodal_input_plugin_manager.h b/service/module_loader/include/multimodal_input_plugin_manager.h index 56e0728dfa..bce18a21b9 100644 --- a/service/module_loader/include/multimodal_input_plugin_manager.h +++ b/service/module_loader/include/multimodal_input_plugin_manager.h @@ -41,6 +41,9 @@ typedef int32_t (*InitPlugin)(std::shared_ptr ctx, std::shared_p */ typedef int32_t (*UnintPlugin)(std::shared_ptr plugin); +const int32_t RET_NOTDO = 0; +const int32_t RET_DO = 1; + struct InputPlugin : public IPluginContext { public: InputPlugin() {}; -- Gitee From c55c3e4c1ec7ff259fcd768ceb783696297c8a87 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:36:20 +0000 Subject: [PATCH 08/12] update service/module_loader/src/multimodal_input_plugin_manager.cpp. Signed-off-by: odxiaoying --- .../src/multimodal_input_plugin_manager.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp index 623013c2dd..61ca502e42 100644 --- a/service/module_loader/src/multimodal_input_plugin_manager.cpp +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -27,7 +27,6 @@ namespace OHOS { namespace MMI { std::shared_ptr InputPluginManager::instance_; std::once_flag InputPluginManager::init_flag_; -std::mutex InputPluginManager::mutex_; const char *FILE_EXTENSION = ".so"; const char *FOLDER_PATH = "/system/lib64/multimodalinput/autorun"; @@ -36,7 +35,6 @@ const int32_t MAX_TIMER = 3; InputPluginManager::~InputPluginManager() { - std::lock_guard lock(mutex_); plugins_.clear(); if (instance_ != nullptr) { instance_ = nullptr; @@ -168,11 +166,11 @@ int32_t InputPluginManager::DoHandleEvent( libinput_event *event, int64_t frameTime, InputPlugin *iplugin, InputPluginStage stage) { if (event == nullptr) { - return 0; + return RET_NOTDO; } auto it = plugins_.find(stage); if (it == plugins_.end()) { - return 0; + return RET_NOTDO; } CALL_DEBUG_ENTER; auto &plugins = it->second; @@ -181,7 +179,7 @@ int32_t InputPluginManager::DoHandleEvent( auto cur_plugin = std::find_if(plugins.begin(), plugins.end(), [iplugin](const std::shared_ptr &plugin) { return plugin.get() == iplugin; }); if (cur_plugin == plugins.end()) { - return 0; + return RET_NOTDO; } start_plugin = std::next(cur_plugin); } @@ -206,14 +204,14 @@ int32_t InputPluginManager::DoHandleEvent( MMI_HILOGE("pluginIt is intermediate or end event"); continue; } - return 1; + return RET_DO; } else if (result == PluginResult::UseNoNeedReissue) { - return 1; + return RET_DO; } else if (result == PluginResult::Error) { MMI_HILOGE("pluginIt err name:%{public}s", (*pluginIt)->name_.c_str()); } } - return 0; + return RET_NOTDO; } // LIBINPUT_EVENT_TABLET_TOOL_BUTTON、LIBINPUT_EVENT_TABLET_PAD_BUTTON、LIBINPUT_EVENT_TABLET_PAD_KEY @@ -299,7 +297,7 @@ void InputPlugin::UnInit() void InputPlugin::DispatchEvent(libinput_event *event, int64_t frameTime) { int32_t result = InputPluginManager::GetInstance()->DoHandleEvent(event, frameTime, this, stage_); - if (result == 0) { + if (result == RET_NOTDO) { CHKPV(callback_); callback_(event, frameTime); } @@ -313,7 +311,6 @@ PluginResult InputPlugin::HandleEvent(libinput_event *event, int64_t frameTime) int32_t InputPlugin::AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) { - std::lock_guard lock(timerMutex_); if (timerCnt_ >= MAX_TIMER) { return -1; } @@ -326,7 +323,6 @@ int32_t InputPlugin::AddTimer(std::function func, int32_t intervalMs, in int32_t InputPlugin::RemoveTimer(int32_t id) { - std::lock_guard lock(timerMutex_); int32_t result = TimerMgr->RemoveTimer(id, name_); if (timerCnt_ > 0) { timerCnt_--; -- Gitee From 56aab26bdf1abc3b42768c660e23b2bd13dc49f1 Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:37:38 +0000 Subject: [PATCH 09/12] update service/libinput_adapter/src/libinput_adapter.cpp. Signed-off-by: odxiaoying --- service/libinput_adapter/src/libinput_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/libinput_adapter/src/libinput_adapter.cpp b/service/libinput_adapter/src/libinput_adapter.cpp index 1c51492942..4d9899115c 100644 --- a/service/libinput_adapter/src/libinput_adapter.cpp +++ b/service/libinput_adapter/src/libinput_adapter.cpp @@ -231,7 +231,7 @@ bool LibinputAdapter::Init(FunInputEvent funInputEvent) int32_t result = manager->HandleEvent(static_cast(event), frameTime, InputPluginStage::INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT); - if (result != 0) { + if (result != RET_NOTDO) { return; } } -- Gitee From 7da6672a40fd972816b295ce1181e22a5b9cea9c Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:38:53 +0000 Subject: [PATCH 10/12] update service/module_loader/include/multimodal_input_plugin_manager.h. Signed-off-by: odxiaoying --- service/module_loader/include/multimodal_input_plugin_manager.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/service/module_loader/include/multimodal_input_plugin_manager.h b/service/module_loader/include/multimodal_input_plugin_manager.h index bce18a21b9..c30ad29407 100644 --- a/service/module_loader/include/multimodal_input_plugin_manager.h +++ b/service/module_loader/include/multimodal_input_plugin_manager.h @@ -65,7 +65,6 @@ public: void* handle_; private: - std::mutex timerMutex_; InputPluginStage stage_; }; @@ -89,7 +88,6 @@ private: std::map>> plugins_; static std::shared_ptr instance_; static std::once_flag init_flag_; - static std::mutex mutex_; }; } // namespace MMI } // namespace OHOS -- Gitee From cf544a78ea8db8c4760cc0dccef3cdc08237433f Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 11:45:47 +0000 Subject: [PATCH 11/12] update service/module_loader/src/multimodal_input_plugin_manager.cpp. Signed-off-by: odxiaoying --- .../module_loader/src/multimodal_input_plugin_manager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/service/module_loader/src/multimodal_input_plugin_manager.cpp b/service/module_loader/src/multimodal_input_plugin_manager.cpp index 61ca502e42..ae13d69ca6 100644 --- a/service/module_loader/src/multimodal_input_plugin_manager.cpp +++ b/service/module_loader/src/multimodal_input_plugin_manager.cpp @@ -60,7 +60,7 @@ int32_t InputPluginManager::Init() DIR *dir = opendir(directory_.c_str()); if (!dir) { MMI_HILOGE("Failed to open error:%{private}s", strerror(errno)); - return 0; + return RET_OK; } struct dirent *entry; while ((entry = readdir(dir)) != nullptr) { @@ -74,7 +74,7 @@ int32_t InputPluginManager::Init() } closedir(dir); PrintPlugins(); - return 0; + return RET_OK; } bool InputPluginManager::LoadPlugin(const std::string &path) @@ -282,7 +282,7 @@ int32_t InputPlugin::Init(std::shared_ptr pin) prio_ = pin->GetPriority(); stage_ = pin->GetStage(); plugin_ = pin; - return 0; + return RET_OK; } void InputPlugin::UnInit() @@ -312,7 +312,7 @@ PluginResult InputPlugin::HandleEvent(libinput_event *event, int64_t frameTime) int32_t InputPlugin::AddTimer(std::function func, int32_t intervalMs, int32_t repeatCount) { if (timerCnt_ >= MAX_TIMER) { - return -1; + return RET_ERR; } int32_t timerId = TimerMgr->AddTimerInternal(intervalMs, repeatCount, func, name_); if (timerId != -1) { -- Gitee From ea5fa0c17eb74b458deb16952317955b2b51117b Mon Sep 17 00:00:00 2001 From: odxiaoying Date: Mon, 7 Jul 2025 12:21:26 +0000 Subject: [PATCH 12/12] update service/module_loader/test/multimodal_input_plugin_manager_test.cpp. Signed-off-by: odxiaoying --- .../module_loader/test/multimodal_input_plugin_manager_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/module_loader/test/multimodal_input_plugin_manager_test.cpp b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp index 494afc386f..fa09c205b4 100644 --- a/service/module_loader/test/multimodal_input_plugin_manager_test.cpp +++ b/service/module_loader/test/multimodal_input_plugin_manager_test.cpp @@ -111,7 +111,7 @@ HWTEST_F(MultimodalInputPluginManagerTest, MultimodalInputPluginManagerTest_Hand std::cout << "pointer device: " << libinput_device_get_name(dev) << std::endl; int32_t result = manager->HandleEvent(event, GetSysClockTime(), InputPluginStage::INPUT_BEFORE_LIBINPUT_ADAPTER_ON_EVENT); - EXPECT_GE(result, 0); + EXPECT_GE(result, RET_OK); } /** -- Gitee