From b8cc7bd501981d4cd4a3d806d6077a0ae0676694 Mon Sep 17 00:00:00 2001 From: whqwe Date: Thu, 9 Nov 2023 16:45:29 +0800 Subject: [PATCH] add AI bar layout notification Signed-off-by: whqwe --- interfaces/innerkits/wm/wm_common.h | 1 + .../window_runtime/window_napi/js_window.cpp | 5 ++- .../window_napi/js_window_utils.cpp | 2 + previewer/include/wm_common.h | 1 + .../js_scene_session_manager.cpp | 39 +++++++++++++++++++ .../js_scene_session_manager.h | 2 + .../session/host/include/scene_session.h | 3 ++ .../session/host/src/scene_session.cpp | 10 +++++ .../include/scene_session_manager.h | 6 +++ .../src/scene_session_manager.cpp | 35 ++++++++++++++++- 10 files changed, 101 insertions(+), 3 deletions(-) diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 4febd7be88..57724eb561 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -472,6 +472,7 @@ enum class AvoidAreaType : uint32_t { TYPE_CUTOUT, // cutout of screen TYPE_SYSTEM_GESTURE, // area for system gesture TYPE_KEYBOARD, // area for soft input keyboard + TYPE_AI_NAVIGATION_BAR, // area for AI navigation bar }; /** diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp index ed6f78049b..5a7156a857 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp @@ -304,7 +304,7 @@ napi_value JsWindow::GetAvoidArea(napi_env env, napi_callback_info info) napi_value JsWindow::GetWindowAvoidAreaSync(napi_env env, napi_callback_info info) { - WLOGI("GetAvoidArea"); + WLOGI("GetWindowAvoidAreaSync"); JsWindow* me = CheckParamsAndGetThis(env, info); return (me != nullptr) ? me->OnGetWindowAvoidAreaSync(env, info) : nullptr; } @@ -2193,7 +2193,8 @@ napi_value JsWindow::OnGetWindowAvoidAreaSync(napi_env env, napi_callback_info i uint32_t resultValue = 0; napi_get_value_uint32(env, nativeMode, &resultValue); avoidAreaType = static_cast(resultValue); - errCode = ((avoidAreaType > AvoidAreaType::TYPE_KEYBOARD) || (avoidAreaType < AvoidAreaType::TYPE_SYSTEM)) ? + errCode = ((avoidAreaType > AvoidAreaType::TYPE_AI_NAVIGATION_BAR) || + (avoidAreaType < AvoidAreaType::TYPE_SYSTEM)) ? WmErrorCode::WM_ERROR_INVALID_PARAM : WmErrorCode::WM_OK; } if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) { diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp index eac8b1b09b..3798cf7677 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp @@ -111,6 +111,8 @@ napi_value AvoidAreaTypeInit(napi_env env) static_cast(AvoidAreaType::TYPE_SYSTEM_GESTURE))); napi_set_named_property(env, objValue, "TYPE_KEYBOARD", CreateJsValue(env, static_cast(AvoidAreaType::TYPE_KEYBOARD))); + napi_set_named_property(env, objValue, "TYPE_AI_BAR", + CreateJsValue(env, static_cast(AvoidAreaType::TYPE_AI_NAVIGATION_BAR))); return objValue; } diff --git a/previewer/include/wm_common.h b/previewer/include/wm_common.h index 748cb985fa..8ae8d16098 100644 --- a/previewer/include/wm_common.h +++ b/previewer/include/wm_common.h @@ -454,6 +454,7 @@ enum class AvoidAreaType : uint32_t { TYPE_CUTOUT, // cutout of screen TYPE_SYSTEM_GESTURE, // area for system gesture TYPE_KEYBOARD, // area for soft input keyboard + TYPE_AI_NAVIGATION_BAR, // area for AI navigation bar }; /** diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp index 51da346e93..d83a1d9cd5 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp @@ -103,6 +103,8 @@ napi_value JsSceneSessionManager::Init(napi_env env, napi_value exportObj) BindNativeFunction(env, exportObj, "addWindowDragHotArea", moduleName, JsSceneSessionManager::AddWindowDragHotArea); BindNativeFunction(env, exportObj, "setScreenLocked", moduleName, JsSceneSessionManager::SetScreenLocked); BindNativeFunction(env, exportObj, "updateMaximizeMode", moduleName, JsSceneSessionManager::UpdateMaximizeMode); + BindNativeFunction(env, exportObj, "notifyAINavigationBarShowStatus", moduleName, + JsSceneSessionManager::NotifyAINavigationBarShowStatus); return NapiGetUndefined(env); } @@ -464,6 +466,13 @@ napi_value JsSceneSessionManager::UpdateMaximizeMode(napi_env env, napi_callback return (me != nullptr) ? me->OnUpdateMaximizeMode(env, info) : nullptr; } +napi_value JsSceneSessionManager::NotifyAINavigationBarShowStatus(napi_env env, napi_callback_info info) +{ + WLOGI("[NAPI]NotifyAINavigationBarShowStatus"); + JsSceneSessionManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnNotifyAINavigationBarShowStatus(env, info) : nullptr; +} + bool JsSceneSessionManager::IsCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject) { if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { @@ -1511,4 +1520,34 @@ napi_value JsSceneSessionManager::OnUpdateMaximizeMode(napi_env env, napi_callba SceneSessionManager::GetInstance().UpdateMaximizeMode(persistentId, isMaximize); return NapiGetUndefined(env); } + +napi_value JsSceneSessionManager::OnNotifyAINavigationBarShowStatus(napi_env env, napi_callback_info info) +{ + size_t argc = 4; + napi_value argv[4] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc < ARGC_TWO) { + WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + bool isVisible = false; + if (!ConvertFromJsValue(env, argv[0], isVisible)) { + WLOGFE("[NAPI]Failed to convert parameter to isVisible"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + WSRect barArea; + if (argv[1] == nullptr || !ConvertRectInfoFromJs(env, argv[1], barArea)) { + WLOGFE("[NAPI]Failed to convert parameter to barArea"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + SceneSessionManager::GetInstance().NotifyAINavigationBarShowStatus(isVisible, barArea); + return NapiGetUndefined(env); +} + } // namespace OHOS::Rosen \ No newline at end of file diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h index 0a4e04fc14..4b8e94ed53 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h @@ -63,6 +63,7 @@ public: static napi_value PreloadInLakeApp(napi_env env, napi_callback_info info); static napi_value AddWindowDragHotArea(napi_env env, napi_callback_info info); static napi_value UpdateMaximizeMode(napi_env env, napi_callback_info info); + static napi_value NotifyAINavigationBarShowStatus(napi_env env, napi_callback_info info); private: napi_value OnRegisterCallback(napi_env env, napi_callback_info info); @@ -96,6 +97,7 @@ private: napi_value OnPreloadInLakeApp(napi_env env, napi_callback_info info); napi_value OnAddWindowDragHotArea(napi_env env, napi_callback_info info); napi_value OnUpdateMaximizeMode(napi_env env, napi_callback_info info); + napi_value OnNotifyAINavigationBarShowStatus(napi_env env, napi_callback_info info); void OnStatusBarEnabledUpdate(bool enable); void OnGestureNavigationEnabledUpdate(bool enable); diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index 2e52a0225b..32dc700e3c 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -43,6 +43,7 @@ using GetSceneSessionVectorByTypeCallback = std::function; using NotifyWindowInfoUpdateCallback = std::function; using NotifySessionTouchOutsideCallback = std::function; +using GetAINavigationBarArea = std::function; using NotifyCreateSpecificSessionFunc = std::function& session)>; using NotifyBindDialogSessionFunc = std::function& session)>; @@ -72,6 +73,7 @@ public: UpdateAvoidAreaCallback onUpdateAvoidArea_; NotifyWindowInfoUpdateCallback onWindowInfoUpdate_; NotifySessionTouchOutsideCallback onSessionTouchOutside_; + GetAINavigationBarArea onGetAINavigationBarArea_; }; // callback for notify SceneBoard @@ -130,6 +132,7 @@ public: void GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea); void GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea); void GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea); + void GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea); AvoidArea GetAvoidAreaByType(AvoidAreaType type) override; WSError UpdateAvoidArea(const sptr& avoidArea, AvoidAreaType type); WSError OnShowWhenLocked(bool showWhenLocked); diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index cf6d2dced9..0086e35ced 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -777,6 +777,12 @@ void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea) return; } +void SceneSession::GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea) +{ + WSRect barArea = specificCallback_->onGetAINavigationBarArea_(); + CalculateAvoidAreaRect(rect, barArea, avoidArea); +} + AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type) { return PostSyncTask([weakThis = wptr(this), type]() -> AvoidArea { @@ -801,6 +807,10 @@ AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type) session->GetCutoutAvoidArea(rect, avoidArea); return avoidArea; } + case AvoidAreaType::TYPE_AI_NAVIGATION_BAR: { + session->GetAINavigationBarArea(rect, avoidArea); + return avoidArea; + } default: { WLOGFD("cannot find avoidAreaType: %{public}u", type); return avoidArea; diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 546f290df9..b2f25407ec 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -207,6 +207,9 @@ public: void PreloadInLakeApp(const std::string& bundleName); void AddWindowDragHotArea(int32_t type, WSRect& area); WSError UpdateMaximizeMode(int32_t persistentId, bool isMaximize); + WSError NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea); + WSRect GetAINavigationBarArea(); + public: std::shared_ptr GetTaskScheduler() {return taskScheduler_;}; protected: @@ -364,6 +367,9 @@ private: std::shared_ptr taskScheduler_; sptr bundleMgr_; + bool isAINavigationBarVisible_ = false; + WSRect currAINavigationBarArea_; + std::shared_ptr eventLoop_; std::shared_ptr eventHandler_; bool isReportTaskStart_ = false; diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 809fb4c708..249af186e7 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -791,6 +791,7 @@ sptr SceneSessionManager::CreateSpecificS this, std::placeholders::_1, std::placeholders::_2); specificCb->onSessionTouchOutside_ = std::bind(&SceneSessionManager::NotifySessionTouchOutside, this, std::placeholders::_1); + specificCb->onGetAINavigationBarArea_ = std::bind(&SceneSessionManager::GetAINavigationBarArea, this); return specificCb; } @@ -4640,7 +4641,7 @@ void SceneSessionManager::UpdateNormalSessionAvoidArea( return; } uint32_t start = static_cast(AvoidAreaType::TYPE_SYSTEM); - uint32_t end = static_cast(AvoidAreaType::TYPE_KEYBOARD); + uint32_t end = static_cast(AvoidAreaType::TYPE_AI_NAVIGATION_BAR); for (uint32_t avoidType = start; avoidType <= end; avoidType++) { AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast(avoidType)); ret = UpdateSessionAvoidAreaIfNeed( @@ -4685,6 +4686,38 @@ void SceneSessionManager::UpdateAvoidArea(const int32_t& persistentId) return; } +WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea) +{ + WLOGFI("NotifyAINavigationBarShowStatus: isVisible: %{public}u, area{%{public}d,%{public}d,%{public}d,%{public}d}", + isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_); + auto task = [this, isVisible, barArea]() { + if (isAINavigationBarVisible_ != isVisible || currAINavigationBarArea_ != barArea) { + isAINavigationBarVisible_ = isVisible; + currAINavigationBarArea_ = barArea; + if (!isVisible && !barArea.IsEmpty()) { + WLOGFD("NotifyAINavigationBarShowStatus: barArea should be empty if invisible"); + currAINavigationBarArea_ = WSRect(); + } + for (auto persistentId : avoidAreaListenerSessionSet_) { + auto sceneSession = GetSceneSession(persistentId); + if (sceneSession == nullptr) { + continue; + } + AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_AI_NAVIGATION_BAR); + UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, + AvoidAreaType::TYPE_AI_NAVIGATION_BAR); + } + } + }; + taskScheduler_->PostAsyncTask(task); + return WSError::WS_OK; +} + +WSRect SceneSessionManager::GetAINavigationBarArea() +{ + return currAINavigationBarArea_; +} + WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener) { auto task = [this, persistentId, haveListener]() { -- Gitee