diff --git a/bundle.json b/bundle.json index c232b02e1c69536ecd86d2f56a15902bf198f6b8..d5b821e90c7e99036c0a03bd6ec1dd74cdb04aa9 100755 --- a/bundle.json +++ b/bundle.json @@ -99,6 +99,7 @@ "//foundation/window/window_manager/extension/window_extension:window_extension_module", "//foundation/window/window_manager/wm:libwm", "//foundation/window/window_manager/wm:libwm_lite", + "//foundation/window/window_manager/wm:libwm_ndk", "//foundation/window/window_manager/utils:libwmutil", "//foundation/window/window_manager/utils:libwmutil_base", "//foundation/window/window_manager/window_scene/common:window_scene_common" diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 935e31ed849aee1294e4507d2de89c430aacbcd3..170c69091f15b9fe77747c2bc108b1ca180d4346 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -62,6 +62,7 @@ namespace Rosen { using NotifyNativeWinDestroyFunc = std::function; using NotifyTransferComponentDataFunc = std::function; using NotifyTransferComponentDataForResultFunc = std::function; +using KeyEventFilterFunc = std::function; class RSSurfaceNode; class RSTransaction; class ISession; @@ -1857,6 +1858,32 @@ public: { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; } + + /** + * @brief Get window by id + * + * @param windId window id + * @return sptr + */ + static sptr GetWindowWithId(uint32_t windId); + + /** + * @brief register keyEvent filter. + * + * @param KeyEventFilterFunc callback func when window recieve keyEvent + * @return WMError + */ + virtual WMError SetKeyEventFilter(KeyEventFilterFunc KeyEventFilterFunc) + { + return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; + } + + /** + * @brief clear keyEvent filter. + * + * @return WMError + */ + virtual WMError ClearKeyEventFilter() { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;} }; } } diff --git a/interfaces/kits/ndk/BUILD.gn b/interfaces/kits/ndk/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..81872e570efe08a301b80c47f46b107a005eecad --- /dev/null +++ b/interfaces/kits/ndk/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2024 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/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("../../../windowmanager_aafwk.gni") + +ohos_ndk_headers("window_manager_header") { + dest_dir = "$ndk_headers_out_dir/window_manager" + sources = [ + "oh_window_comm.h", + "oh_window_event_filter.h", + ] +} + +ohos_ndk_library("native_window_manager") { + output_name = "native_window_manager" + output_extension = "so" + ndk_description_file = "./libwm.ndk.json" + system_capability = "SystemCapability.Window.SessionManager" + system_capability_headers = [ + "oh_window_comm.h", + "oh_window_event_filter.h", + ] + min_compact_version = "12" +} diff --git a/interfaces/kits/ndk/libwm.ndk.json b/interfaces/kits/ndk/libwm.ndk.json new file mode 100644 index 0000000000000000000000000000000000000000..3ed362ce4eab5ea3605853f9a5eded6cca11cc5f --- /dev/null +++ b/interfaces/kits/ndk/libwm.ndk.json @@ -0,0 +1,10 @@ +[ + { + "first_instroduced":"12", + "name":"OH_NativeWindowManager_RegisterKeyEventFilter" + }, + { + "first_instroduced":"12", + "name":"OH_NativeWindowManager_UnregisterKeyEventFilter" + } +] \ No newline at end of file diff --git a/interfaces/kits/ndk/wm/oh_window_comm.h b/interfaces/kits/ndk/wm/oh_window_comm.h new file mode 100644 index 0000000000000000000000000000000000000000..da74fd76f5d1344aa34c96d8c042cc188248623b --- /dev/null +++ b/interfaces/kits/ndk/wm/oh_window_comm.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024 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 OH_WINDOW_COMM_H +#define OH_WINDOW_COMM_H + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerates the result types of the wm interface + * + * @since 12 + */ +typedef enum { + /** succ. */ + WS_OK = 0, + /** window id is invaild. */ + WS_INVAILD_WINID = 1000, + /** failed. */ + WS_ERR = 2000, +} OH_WMErrCode; + +#ifdef __cplusplus +} +#endif + +#endif // OH_WINDOW_COMM_H \ No newline at end of file diff --git a/interfaces/kits/ndk/wm/oh_window_event_filter.h b/interfaces/kits/ndk/wm/oh_window_event_filter.h new file mode 100644 index 0000000000000000000000000000000000000000..e34dbd0242dc67593143c773347b3973173963f8 --- /dev/null +++ b/interfaces/kits/ndk/wm/oh_window_event_filter.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 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 OH_WINDOW_EVENT_FILTER_H +#define OH_WINDOW_EVENT_FILTER_H + +#include "foundation/multimodalinput/input/interfaces/kits/c/input/oh_input_manager.h" +#include "key_event.h" +#include "oh_window_comm.h" +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief the callback funcation type when keyEvent was filter + * @param keyEvent multimodal keyEvent + * @since 12 + */ +typedef bool (*KeyEventFilter)(Input_KeyEvent* keyEvent); + +/** + * @brief Registers a filter callback for the window, the callback is called when the + * window is dispatched to the event + * + * @param windowId windowId when window is created + * @param keyEventFilter key event callback ,called when the window is dispatched + * to the event + * @return Returns the status code of the execution. + * @since 12 + */ +OH_WMErrCode OH_NativeWindowManager_RegisterKeyEventFilter(int32_t windowId, + KeyEventFilter keyEventFilter); + +/** + * @brief clear callback for the window + * + * @param windowId windowId when window is created + * @return Returns the status code of the execution. + * @since 12 + */ +OH_WMErrCode OH_NativeWindowManager_UnregisterKeyEventFilter(int32_t windowId); + +#ifdef __cplusplus +} +#endif +#endif // OH_WINDOW_EVENT_FILTER_H diff --git a/wm/BUILD.gn b/wm/BUILD.gn index 0dd34d36a04df7cf67ece68fa67078e9611e427a..9c395bb1785564f848f1f209bada194bbc1e133e 100644 --- a/wm/BUILD.gn +++ b/wm/BUILD.gn @@ -405,3 +405,36 @@ group("test") { testonly = true deps = [ "test:test" ] } + +## Build libwm_ndk.so +ohos_shared_library("libwm_ndk") { + output_name = "libnative_window_manager" + output_extension = "so" + branch_protector_ret = "pac_ret" + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + include_dirs = [ + "${window_base_path}/interfaces/kits/ndk/wm", + "${window_base_path}/interfaces/inner_kits/wm", + ] + + sources = [ "src/oh_window_event_filter.cpp" ] + + deps = [ ":libwm" ] + innerapi_tags = [ "ndk" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "input:oh_input_manager", + ] + + part_name = "window_manager" + subsystem_name = "window" +} diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index d3beb247230d19b1b1f404606df4ce72612bcc85..e0579e730dcdc57c04b9cc4e603319f2c458f1e5 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -111,6 +111,7 @@ public: static sptr Find(const std::string& id); static sptr GetTopWindowWithContext(const std::shared_ptr& context = nullptr); static sptr GetTopWindowWithId(uint32_t mainWinId); + static sptr GetWindowWithId(uint32_t winId); static std::vector> GetSubWindow(uint32_t parantId); static void UpdateConfigurationForAll(const std::shared_ptr& configuration); virtual std::shared_ptr GetSurfaceNode() const override; diff --git a/wm/include/window_scene_session_impl.h b/wm/include/window_scene_session_impl.h index 919c2c4d742f73115151b0144f0cd077fb2cb0a3..1418f527d56eef85dc24a8f770e9bff40ce2b826 100644 --- a/wm/include/window_scene_session_impl.h +++ b/wm/include/window_scene_session_impl.h @@ -85,6 +85,7 @@ public: static sptr GetTopWindowWithId(uint32_t mainWinId); static sptr GetMainWindowWithContext(const std::shared_ptr& context = nullptr); static sptr GetMainWindowWithId(uint32_t mainWinId); + static sptr GetWindowWithId(uint32_t windId); virtual void UpdateConfiguration(const std::shared_ptr& configuration) override; WMError NotifyMemoryLevel(int32_t level) override; diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index 3523bb3902336b9310e3ea11ba48db8ef8aa13bd..6cdefcf7cc02d3e4b87b6f21e505dc5b64c46728 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -247,6 +247,7 @@ protected: void NotifyTransformChange(const Transform& transForm) override; bool IsKeyboardEvent(const std::shared_ptr& keyEvent) const; void DispatchKeyEventCallback(const std::shared_ptr& keyEvent, bool& isConsumed); + bool FilterKeyEvent(const std::shared_ptr& keyEvent); WMError RegisterExtensionAvoidAreaChangeListener(sptr& listener); WMError UnregisterExtensionAvoidAreaChangeListener(sptr& listener); @@ -279,7 +280,8 @@ protected: bool escKeyEventTriggered_ = false; // Check whether the UIExtensionAbility process is started static bool isUIExtensionAbilityProcess_; - + virtual WMError SetKeyEventFilter(KeyEventFilterFunc filter) override; + virtual WMError ClearKeyEventFilter() override; private: //Trans between colorGamut and colorSpace static ColorSpace GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut); @@ -375,6 +377,7 @@ private: std::string subWindowTitle_ = { "" }; WindowTitleVisibleFlags windowTitleVisibleFlags_; + KeyEventFilterFunc keyEventFilter_; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/src/oh_window_event_filter.cpp b/wm/src/oh_window_event_filter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..335356bd920f12c028aaf18278a071a92971e041 --- /dev/null +++ b/wm/src/oh_window_event_filter.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 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 "cstdint" +#include "functional" +#include "oh_window_comm.h" +#include "oh_window_event_filter.h" +#include "key_event.h" +#include "window.h" +#include "window_manager_hilog.h" +#include "wm_common.h" + +using namespace OHOS::Rosen; + +KeyEventFilterFunc convert2Func(KeyEventFilter filter) +{ + std::function func = [filter](OHOS::MMI::KeyEvent& keyEvent) { + Input_KeyEvent *input = OH_Input_CreateKeyEvent(); + OH_Input_SetKeyEventKeyCode(input, keyEvent.GetKeyCode()); + OH_Input_SetKeyEventAction(input, keyEvent.GetKeyAction()); + OH_Input_SetKeyEventActionTime(input, keyEvent.GetActionTime()); + return filter(input); + }; + return func ; +} + +OH_WMErrCode OH_NativeWindowManager_RegisterKeyEventFilter(int32_t windowId, KeyEventFilter filter) +{ + TLOGI(WmsLogTag::WMS_EVENT, "register keyEventCallback, windowId:%{public}d", windowId); + auto mainWindow = OHOS::Rosen::Window::GetWindowWithId(windowId); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_EVENT, "window is null, windowId:%{public}d", windowId); + return OH_WMErrCode::WS_INVAILD_WINID; + } + auto res = mainWindow->SetKeyEventFilter(convert2Func(filter)); + + return res == WMError::WM_OK ? OH_WMErrCode::WS_OK : OH_WMErrCode::WS_ERR; +} + +OH_WMErrCode OH_NativeWindowManager_UnregisterKeyEventFilter(int32_t windowId) +{ + TLOGI(WmsLogTag::WMS_EVENT, "clear keyEventCallback, windowId:%{public}d", windowId); + auto mainWindow = OHOS::Rosen::Window::GetWindowWithId(windowId); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_EVENT, "window is null, windowId:%{public}d", windowId); + return OH_WMErrCode::WS_INVAILD_WINID; + } + auto res = mainWindow->ClearKeyEventFilter(); + return res == WMError::WM_OK ? OH_WMErrCode::WS_OK : OH_WMErrCode::WS_ERR; +} diff --git a/wm/src/window.cpp b/wm/src/window.cpp index 3bf2e7bf459e0a7be854190b241b38f248b8d8b2..16c44befd8c905aee61ee404865da1ccc5f1018b 100644 --- a/wm/src/window.cpp +++ b/wm/src/window.cpp @@ -210,6 +210,15 @@ sptr Window::GetMainWindowWithContext(const std::shared_ptr Window::GetWindowWithId(uint32_t windId) +{ + if (SceneBoardJudgement::IsSceneBoardEnabled()) { + return WindowSceneSessionImpl::GetWindowWithId(windId); + } else { + return WindowImpl::GetWindowWithId(windId); + } +} + std::vector> Window::GetSubWindow(uint32_t parentId) { if (SceneBoardJudgement::IsSceneBoardEnabled()) { diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index f3e91a6e5354eda0b6e6b085ff3600d2c618305b..5c94ae4be106cc7e6378de11c9fed0193d874582 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -200,6 +200,11 @@ sptr WindowImpl::GetTopWindowWithId(uint32_t mainWinId) return FindWindowById(topWinId); } +sptr WindowImpl::GetWindowWithId(uint32_t WinId) +{ + return FindWindowById(WinId); +} + sptr WindowImpl::GetTopWindowWithContext(const std::shared_ptr& context) { if (windowMap_.empty()) { diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index c762cef94ce794d8fd2a1272c83f480bda290c1d..7248786b4ce998f317e3f3f4df459b11e7be38be 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -2065,6 +2065,24 @@ sptr WindowSceneSessionImpl::GetMainWindowWithId(uint32_t mai return nullptr; } + +sptr WindowSceneSessionImpl::GetWindowWithId(uint32_t winId) +{ + std::shared_lock lock(windowSessionMutex_); + if (windowSessionMap_.empty()) { + TLOGE(WmsLogTag::WMS_SYSTEM, "Please create mainWindow First!"); + return nullptr; + } + for (const auto& winPair : windowSessionMap_) { + auto win = winPair.second.second; + if (win && winId == win->GetWindowId()) { + return win; + } + } + TLOGE(WmsLogTag::WMS_SYSTEM, "Cannot find Window!"); + return nullptr; +} + void WindowSceneSessionImpl::SetNeedDefaultAnimation(bool needDefaultAnimation) { enableDefaultAnimation_= needDefaultAnimation; diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index b17398261487a29b33b2236f28b9383b2ff59bbd..4a76c608abad3640e247332e0bd62bbf493037a3 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -2327,6 +2327,35 @@ void WindowSessionImpl::NotifyPointerEvent(const std::shared_ptr lock(windowSessionMutex_); + keyEventFilter_ = std::move(filter); + return WMError::WM_OK; +} + +WMError WindowSessionImpl::ClearKeyEventFilter() +{ + std::unique_lock lock(windowSessionMutex_); + keyEventFilter_ = nullptr; + return WMError::WM_OK; +} + +bool WindowSessionImpl::FilterKeyEvent(const std::shared_ptr& keyEvent) +{ + std::shared_lock lock(windowSessionMutex_); + if (keyEventFilter_ != nullptr) { + bool isFilter = keyEventFilter_(*keyEvent.get()); + TLOGE(WmsLogTag::WMS_SYSTEM, "keyCode:%{public}d isFilter:%{public}d", + keyEvent->GetKeyCode(), isFilter); + if (isFilter) { + keyEvent->MarkProcessed(); + return true; + } + } + return false; +} + void WindowSessionImpl::DispatchKeyEventCallback(const std::shared_ptr& keyEvent, bool& isConsumed) { std::shared_ptr inputEventConsumer; @@ -2357,6 +2386,7 @@ void WindowSessionImpl::DispatchKeyEventCallback(const std::shared_ptrMarkProcessed(); } } else if (uiContent_) { + if (FilterKeyEvent(keyEvent)) return; isConsumed = uiContent_->ProcessKeyEvent(keyEvent); if (!isConsumed && keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ESCAPE && property_->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&