From 1398b670499ed3b647b63a8d118186a3e71a4a0d Mon Sep 17 00:00:00 2001 From: wangh Date: Wed, 11 Oct 2023 17:07:06 +0800 Subject: [PATCH] add interactive type for window stage event Signed-off-by: wangh --- interfaces/innerkits/wm/window.h | 8 +++ .../window_napi/js_window_listener.cpp | 10 ++++ .../window_napi/js_window_listener.h | 2 + .../window_napi/js_window_utils.h | 2 + .../js_scene_session_manager.cpp | 50 +++++++++++++++++++ .../js_scene_session_manager.h | 2 + .../include/zidl/session_stage_interface.h | 1 + .../zidl/session_stage_ipc_interface_code.h | 3 +- .../include/zidl/session_stage_proxy.h | 1 + .../include/zidl/session_stage_stub.h | 1 + .../src/zidl/session_stage_proxy.cpp | 23 +++++++++ .../container/src/zidl/session_stage_stub.cpp | 11 ++++ window_scene/session/host/include/session.h | 2 + window_scene/session/host/src/session.cpp | 9 ++++ .../include/scene_session_manager.h | 1 + .../src/scene_session_manager.cpp | 26 ++++++++++ window_scene/test/mock/mock_session_stage.h | 1 + wm/include/window_session_impl.h | 3 ++ wm/src/window_session_impl.cpp | 28 +++++++++++ 19 files changed, 183 insertions(+), 1 deletion(-) diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 9a0fb4b489..704864a434 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -107,6 +107,14 @@ public: * @brief Notify caller that window is inactive. */ virtual void AfterInactive() {} + /** + * @brief Notify caller that window is resumed. + */ + virtual void AfterResumed() {} + /** + * @brief Notify caller that window is paused. + */ + virtual void AfterPaused() {} }; /** diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.cpp index 4321b54211..579bcfc658 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.cpp @@ -212,6 +212,16 @@ void JsWindowListener::AfterUnfocused() LifeCycleCallBack(LifeCycleEventType::INACTIVE); } +void JsWindowListener::AfterResumed() +{ + LifeCycleCallBack(LifeCycleEventType::RESUMED); +} + +void JsWindowListener::AfterPaused() +{ + LifeCycleCallBack(LifeCycleEventType::PAUSED); +} + void JsWindowListener::OnSizeChange(const sptr& info, const std::shared_ptr& rsTransaction) { diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.h b/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.h index 661be16bb8..969a51e04d 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_listener.h @@ -69,6 +69,8 @@ public: void AfterBackground() override; void AfterFocused() override; void AfterUnfocused() override; + void AfterResumed() override; + void AfterPaused() override; void OnSizeChange(const sptr& info, const std::shared_ptr& rsTransaction = nullptr) override; void OnTouchOutside() const override; diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h index bf5a0e757f..dfeeac17fa 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h @@ -62,6 +62,8 @@ enum class LifeCycleEventType : uint32_t { ACTIVE, INACTIVE, BACKGROUND, + RESUMED, + PAUSED, }; const std::map NATIVE_JS_TO_WINDOW_TYPE_MAP { 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 9ccd0b6333..71b5d660ae 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 @@ -74,6 +74,8 @@ napi_value JsSceneSessionManager::Init(napi_env env, napi_value exportObj) JsSceneSessionManager::RequestSceneSessionBackground); BindNativeFunction(env, exportObj, "requestSceneSessionDestruction", moduleName, JsSceneSessionManager::RequestSceneSessionDestruction); + BindNativeFunction(env, exportObj, "notifyForegroundInteractiveStatus", moduleName, + JsSceneSessionManager::NotifyForegroundInteractiveStatus); BindNativeFunction(env, exportObj, "on", moduleName, JsSceneSessionManager::RegisterCallback); BindNativeFunction(env, exportObj, "getWindowSceneConfig", moduleName, JsSceneSessionManager::GetWindowSceneConfig); @@ -331,6 +333,13 @@ napi_value JsSceneSessionManager::RequestSceneSessionDestruction(napi_env env, n return (me != nullptr) ? me->OnRequestSceneSessionDestruction(env, info) : nullptr; } +napi_value JsSceneSessionManager::NotifyForegroundInteractiveStatus(napi_env env, napi_callback_info info) +{ + WLOGI("[NAPI]NotifyForegroundInteractiveStatus"); + JsSceneSessionManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnNotifyForegroundInteractiveStatus(env, info) : nullptr; +} + napi_value JsSceneSessionManager::RequestSceneSessionByCall(napi_env env, napi_callback_info info) { WLOGI("[NAPI]RequestSceneSessionByCall"); @@ -972,6 +981,47 @@ napi_value JsSceneSessionManager::OnRequestSceneSessionDestruction(napi_env env, return NapiGetUndefined(env); } +napi_value JsSceneSessionManager::OnNotifyForegroundInteractiveStatus(napi_env env, napi_callback_info info) +{ + WLOGI("[NAPI]OnNotifyForegroundInteractiveStatus"); + 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), "InputInvalid")); + return NapiGetUndefined(env); + } + + napi_value jsSceneSessionObj = argv[0]; + if (jsSceneSessionObj == nullptr) { + WLOGFE("[NAPI]Failed to get js scene session object"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), "InputInvalid")); + return NapiGetUndefined(env); + } + void* pointerResult = nullptr; + napi_unwrap(env, jsSceneSessionObj, &pointerResult); + auto jsSceneSession = static_cast(pointerResult); + if (jsSceneSession == nullptr) { + WLOGFE("[NAPI]Failed to get scene session from js object"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), "InputInvalid")); + return NapiGetUndefined(env); + } + sptr sceneSession = jsSceneSession->GetNativeSession(); + if (sceneSession == nullptr) { + WLOGFE("[NAPI]sceneSession is nullptr"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_SYSTEM_ABNORMALLY), + "sceneSession is nullptr")); + return NapiGetUndefined(env); + } + + bool interactive = true; + ConvertFromJsValue(env, argv[1], interactive); + + SceneSessionManager::GetInstance().NotifyForegroundInteractiveStatus(sceneSession, interactive); + return NapiGetUndefined(env); +} + void JsSceneSessionManager::SetIsClearSession(napi_env env, napi_value jsSceneSessionObj, sptr& sceneSession) { if (sceneSession == nullptr) { 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 6359a0772f..81d1d38e81 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 @@ -40,6 +40,7 @@ public: static napi_value RequestSceneSessionActivation(napi_env env, napi_callback_info info); static napi_value RequestSceneSessionBackground(napi_env env, napi_callback_info info); static napi_value RequestSceneSessionDestruction(napi_env env, napi_callback_info info); + static napi_value NotifyForegroundInteractiveStatus(napi_env env, napi_callback_info info); static napi_value RequestSceneSessionByCall(napi_env env, napi_callback_info info); static napi_value StartAbilityBySpecified(napi_env env, napi_callback_info info); static napi_value RegisterCallback(napi_env env, napi_callback_info info); @@ -64,6 +65,7 @@ private: napi_value OnRequestSceneSessionActivation(napi_env env, napi_callback_info info); napi_value OnRequestSceneSessionBackground(napi_env env, napi_callback_info info); napi_value OnRequestSceneSessionDestruction(napi_env env, napi_callback_info info); + napi_value OnNotifyForegroundInteractiveStatus(napi_env env, napi_callback_info info); napi_value OnRequestSceneSessionByCall(napi_env env, napi_callback_info info); napi_value OnStartAbilityBySpecified(napi_env env, napi_callback_info info); napi_value OnGetWindowSceneConfig(napi_env env, napi_callback_info info); diff --git a/window_scene/session/container/include/zidl/session_stage_interface.h b/window_scene/session/container/include/zidl/session_stage_interface.h index 76838f7982..53fe0e1bf5 100644 --- a/window_scene/session/container/include/zidl/session_stage_interface.h +++ b/window_scene/session/container/include/zidl/session_stage_interface.h @@ -63,6 +63,7 @@ public: virtual void DumpSessionElementInfo(const std::vector& params) = 0; virtual WSError NotifyTouchOutside() = 0; virtual WSError UpdateWindowMode(WindowMode mode) = 0; + virtual void NotifyForegroundInteractiveStatus(bool interactive) = 0; }; } // namespace OHOS::Rosen #endif // OHOS_WINDOW_SCENE_SESSION_STAGE_INTERFACE_H diff --git a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h index 71f8e99e20..114e616833 100644 --- a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h +++ b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h @@ -33,7 +33,8 @@ enum class SessionStageInterfaceCode { TRANS_ID_DUMP_SESSSION_ELEMENT_INFO, TRANS_ID_NOTIFY_TOUCH_OUTSIDE, TRANS_ID_NOTIFY_WINDOW_MODE_CHANGE, - TRANS_ID_NOTIFY_DENSITY_CHANGE + TRANS_ID_NOTIFY_DENSITY_CHANGE, + TRANS_ID_NOTIFY_FOREGROUND_INTERACTIVE_STATUS, }; } // namespace Rosen } // namespace OHOS diff --git a/window_scene/session/container/include/zidl/session_stage_proxy.h b/window_scene/session/container/include/zidl/session_stage_proxy.h index 83a52ef144..390fb2bfbb 100644 --- a/window_scene/session/container/include/zidl/session_stage_proxy.h +++ b/window_scene/session/container/include/zidl/session_stage_proxy.h @@ -45,6 +45,7 @@ public: void DumpSessionElementInfo(const std::vector& params) override; WSError NotifyTouchOutside() override; WSError UpdateWindowMode(WindowMode mode) override; + void NotifyForegroundInteractiveStatus(bool interactive) override; private: static inline BrokerDelegator delegator_; diff --git a/window_scene/session/container/include/zidl/session_stage_stub.h b/window_scene/session/container/include/zidl/session_stage_stub.h index 01a3405712..43def55b82 100644 --- a/window_scene/session/container/include/zidl/session_stage_stub.h +++ b/window_scene/session/container/include/zidl/session_stage_stub.h @@ -51,6 +51,7 @@ private: int HandleDumpSessionElementInfo(MessageParcel& data, MessageParcel& reply); int HandleNotifyTouchOutside(MessageParcel& data, MessageParcel& reply); int HandleUpdateWindowMode(MessageParcel& data, MessageParcel& reply); + int HandleNotifyForegroundInteractiveStatus(MessageParcel& data, MessageParcel& reply); }; } // namespace OHOS::Rosen #endif // OHOS_WINDOW_SCENE_SESSION_STAGE_STUB_H diff --git a/window_scene/session/container/src/zidl/session_stage_proxy.cpp b/window_scene/session/container/src/zidl/session_stage_proxy.cpp index 922ce4557d..35607f3696 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -345,4 +345,27 @@ WSError SessionStageProxy::UpdateWindowMode(WindowMode mode) int32_t ret = reply.ReadInt32(); return static_cast(ret); } + +void SessionStageProxy::NotifyForegroundInteractiveStatus(bool interactive) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + + if (!data.WriteBool(interactive)) { + WLOGFE("Write interactive failed"); + return; + } + + if (Remote()->SendRequest( + static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_FOREGROUND_INTERACTIVE_STATUS), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} + } // namespace OHOS::Rosen diff --git a/window_scene/session/container/src/zidl/session_stage_stub.cpp b/window_scene/session/container/src/zidl/session_stage_stub.cpp index 735fbf0b24..086623ef94 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -55,6 +55,8 @@ const std::map SessionStageStub::stubFuncMap_{ &SessionStageStub::HandleNotifyTouchOutside), std::make_pair(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_WINDOW_MODE_CHANGE), &SessionStageStub::HandleUpdateWindowMode), + std::make_pair(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_FOREGROUND_INTERACTIVE_STATUS), + &SessionStageStub::HandleNotifyForegroundInteractiveStatus), }; int SessionStageStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) @@ -215,4 +217,13 @@ int SessionStageStub::HandleUpdateWindowMode(MessageParcel& data, MessageParcel& reply.WriteInt32(static_cast(errCode)); return ERR_NONE; } + +int SessionStageStub::HandleNotifyForegroundInteractiveStatus(MessageParcel& data, MessageParcel& reply) +{ + WLOGFD("NotifyForegroundInteractiveStatus!"); + bool interactive = data.ReadBool(); + NotifyForegroundInteractiveStatus(interactive); + return ERR_NONE; +} + } // namespace OHOS::Rosen diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index e42429d697..ba4ff54a7d 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -262,6 +262,8 @@ public: WSRectF UpdateHotRect(const WSRect& rect); WSError RaiseToAppTopForPointDown(); + void NotifyForegroundInteractiveStatus(bool interactive); + protected: void GeneratePersistentId(bool isExtension, int32_t persistentId); void UpdateSessionState(SessionState state); diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 776c8bc685..65e21713a2 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -788,6 +788,15 @@ WSError Session::SetActive(bool active) return WSError::WS_OK; } +void Session::NotifyForegroundInteractiveStatus(bool interactive) +{ + if (!IsSessionValid() || !sessionStage_) { + return; + } + WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive); + sessionStage_->NotifyForegroundInteractiveStatus(interactive); +} + void Session::SetPendingSessionActivationEventListener(const NotifyPendingSessionActivationFunc& func) { pendingSessionActivationFunc_ = func; diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index dfe7bac74e..8c5a86378f 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -85,6 +85,7 @@ public: WSError RequestSceneSessionBackground(const sptr& sceneSession, const bool isDelegator = false); WSError RequestSceneSessionDestruction( const sptr& sceneSession, const bool needRemoveSession = true); + void NotifyForegroundInteractiveStatus(const sptr& sceneSession, bool interactive); WSError RequestSceneSessionByCall(const sptr& sceneSession); void StartAbilityBySpecified(const SessionInfo& sessionInfo); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 109331af94..fce2a6e343 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -1143,6 +1143,32 @@ WSError SceneSessionManager::RequestSceneSessionBackground(const sptr& sceneSession, bool interactive) +{ + wptr weakSceneSession(sceneSession); + auto task = [this, weakSceneSession, interactive]() { + auto scnSession = weakSceneSession.promote(); + if (scnSession == nullptr) { + WLOGFE("session is nullptr"); + return; + } + auto persistentId = scnSession->GetPersistentId(); + WLOGFI("notify interactive session persistentId: %{public}d", persistentId); + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId); + if (!GetSceneSession(persistentId)) { + WLOGFE("session is invalid with %{public}d", persistentId); + return; + } + const auto& state = scnSession->GetSessionState(); + if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && + (scnSession->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) { + scnSession->NotifyForegroundInteractiveStatus(interactive); + } + }; + + taskScheduler_->PostAsyncTask(task); +} + WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr& scnSession) { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow"); diff --git a/window_scene/test/mock/mock_session_stage.h b/window_scene/test/mock/mock_session_stage.h index 48d240946a..72dceeb0fd 100644 --- a/window_scene/test/mock/mock_session_stage.h +++ b/window_scene/test/mock/mock_session_stage.h @@ -42,6 +42,7 @@ public: MOCK_METHOD0(NotifyScreenshot, void(void)); MOCK_METHOD0(NotifyTouchOutside, WSError(void)); MOCK_METHOD1(UpdateWindowMode, WSError(WindowMode mode)); + MOCK_METHOD1(NotifyForegroundInteractiveStatus, void(bool interactive)); }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index add26e72e9..12a30a3403 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -104,6 +104,7 @@ public: void NotifyPointerEvent(const std::shared_ptr& pointerEvent) override; void NotifyKeyEvent(const std::shared_ptr& keyEvent, bool& isConsumed) override; void NotifyOccupiedAreaChangeInfo(sptr info) override; + void NotifyForegroundInteractiveStatus(bool interactive) override; WMError RegisterLifeCycleListener(const sptr& listener) override; WMError UnregisterLifeCycleListener(const sptr& listener) override; @@ -218,6 +219,8 @@ private: RSSurfaceNode::SharedPtr CreateSurfaceNode(std::string name, WindowType type); void NotifyAfterFocused(); void NotifyAfterUnfocused(bool needNotifyUiContent = true); + void NotifyAfterResumed(); + void NotifyAfterPaused(); WMError SetUIContentInner(const std::string& contentInfo, napi_env env, napi_value storage, bool isdistributed, bool isLoadedByName, AppExecFwk::Ability* ability); diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 0678ad510e..ef8ada1379 100755 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -473,6 +473,22 @@ WSError WindowSessionImpl::UpdateFocus(bool isFocused) return WSError::WS_OK; } +void WindowSessionImpl::NotifyForegroundInteractiveStatus(bool interactive) +{ + WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive); + if (IsWindowSessionInvalid()) { + WLOGFE("session is invalid"); + return; + } + if (state_ == WindowState::STATE_SHOWN) { + if (interactive) { + NotifyAfterResumed(); + } else { + NotifyAfterPaused(); + } + } +} + WSError WindowSessionImpl::UpdateWindowMode(WindowMode mode) { return WSError::WS_OK; @@ -1082,6 +1098,18 @@ void WindowSessionImpl::NotifyBackgroundFailed(WMError ret) CALL_LIFECYCLE_LISTENER_WITH_PARAM(BackgroundFailed, lifecycleListeners, static_cast(ret)); } +void WindowSessionImpl::NotifyAfterResumed() +{ + auto lifecycleListeners = GetListeners(); + CALL_LIFECYCLE_LISTENER(AfterResumed, lifecycleListeners); +} + +void WindowSessionImpl::NotifyAfterPaused() +{ + auto lifecycleListeners = GetListeners(); + CALL_LIFECYCLE_LISTENER(AfterPaused, lifecycleListeners); +} + WSError WindowSessionImpl::MarkProcessed(int32_t eventId) { if (IsWindowSessionInvalid()) { -- Gitee