diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp index ee246200bf0198aec5afdb05a09ea00e693c1a2e..781363701a5d91108b9333c9a5aed3749a5789f5 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session.cpp @@ -5626,12 +5626,38 @@ napi_value JsSceneSession::OnRemoveBlank(napi_env env, napi_callback_info info) napi_value JsSceneSession::OnAddSnapshot(napi_env env, napi_callback_info info) { + size_t argc = ARGC_FOUR; + napi_value argv[ARGC_FOUR] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + bool useFfrt = false; + if (argc >= ARGC_ONE && GetType(env, argv[0]) == napi_boolean) { + if (!ConvertFromJsValue(env, argv[0], useFfrt)) { + TLOGE(WmsLogTag::WMS_PATTERN, "Failed to convert parameter to useFfrt"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + } + + bool needPersist = false; + if (argc >= ARGC_TWO && GetType(env, argv[1]) == napi_boolean) { + if (!ConvertFromJsValue(env, argv[1], needPersist)) { + TLOGE(WmsLogTag::WMS_PATTERN, "Failed to convert parameter to needPersist"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + } + + TLOGI(WmsLogTag::WMS_PATTERN, "argc: %{public}u, useFfrt: %{public}u, needPersist: %{public}u", + argc, useFfrt, needPersist); auto session = weakSession_.promote(); if (session == nullptr) { - TLOGE(WmsLogTag::WMS_PATTERN, "session is nullptr, id:%{public}d", persistentId_); + TLOGE(WmsLogTag::WMS_PATTERN, "session is null, id:%{public}d", persistentId_); return NapiGetUndefined(env); } - session->NotifyAddSnapshot(); + session->NotifyAddSnapshot(useFfrt, needPersist); return NapiGetUndefined(env); } diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index 727875027bdc313dac3308117ec16fe74d465d96..5dd92756dfb5c83ca5ad6659650da1a5a1630113 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -201,7 +201,7 @@ public: void NotifyDisconnect(); void NotifyLayoutFinished(); void NotifyRemoveBlank(); - void NotifyAddSnapshot(); + void NotifyAddSnapshot(bool useFfrt = false, bool needPersist = false); void NotifyRemoveSnapshot(); void NotifyExtensionDied() override; void NotifyExtensionTimeout(int32_t errorCode) override; @@ -245,15 +245,24 @@ public: void SetSaveSnapshotCallback(Task&& task) { if (task) { + std::lock_guard lock(saveSnapshotCallbackMutex_); saveSnapshotCallback_ = std::move(task); } } void SetRemoveSnapshotCallback(Task&& task) { if (task) { + std::lock_guard lock(removeSnapshotCallbackMutex_); removeSnapshotCallback_ = std::move(task); } } + void SetAddSnapshotCallback(Task&& task) + { + if (task) { + std::lock_guard lock(addSnapshotCallbackMutex_); + addSnapshotCallback_ = std::move(task); + } + } SessionState GetSessionState() const; virtual void SetSessionState(SessionState state); @@ -998,8 +1007,10 @@ private: */ Task saveSnapshotCallback_ = []() {}; Task removeSnapshotCallback_ = []() {}; + Task addSnapshotCallback_ = []() {}; std::mutex saveSnapshotCallbackMutex_; std::mutex removeSnapshotCallbackMutex_; + std::mutex addSnapshotCallbackMutex_; std::atomic needNotifyAttachState_ = { false }; /* diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 6dc9b8a67493a7836b5e8e17a6f8f9e9f1637579..8a58d436c0e547c56164c1a5ea8077974800d4e0 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -466,18 +466,31 @@ void Session::NotifyRemoveBlank() } } -void Session::NotifyAddSnapshot() +void Session::NotifyAddSnapshot(bool useFfrt, bool needPersist) { /* * for blankness prolems, persist snapshot could conflict with background process, * thus no need to persist snapshot here */ - SaveSnapshot(false, false); - auto lifecycleListeners = GetListeners(); - for (auto& listener : lifecycleListeners) { - if (auto listenerPtr = listener.lock()) { - listenerPtr->OnAddSnapshot(); + SaveSnapshot(useFfrt, needPersist); + auto task = [weakThis = wptr(this), where = __func__]() { + auto session = weakThis.promote(); + if (session == nullptr) { + TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s session is null", where); + return; + } + auto lifecycleListeners = session->GetListeners(); + for (auto& listener : lifecycleListeners) { + if (auto listenerPtr = listener.lock()) { + listenerPtr->OnAddSnapshot(); + } } + }; + + if (useFfrt) { + SetAddSnapshotCallback(task); + } else { + task(); } } @@ -2476,7 +2489,12 @@ void Session::SaveSnapshot(bool useFfrt, bool needPersist) session->snapshot_ = pixelMap; } { - std::lock_guard lock(session->saveSnapshotCallbackMutex_); + std::lock_guard lock(session->addSnapshotCallbackMutex_); + session->addSnapshotCallback_(); + } + session->SetAddSnapshotCallback([]() {}); + { + std::lock_guard lock(session->saveSnapshotCallbackMutex_); session->saveSnapshotCallback_(); } if (!requirePersist) { diff --git a/window_scene/test/unittest/window_pattern/window_pattern_snapshot_test.cpp b/window_scene/test/unittest/window_pattern/window_pattern_snapshot_test.cpp index 1c2b3087187d64c891a302795737cc310b7661c0..e426d5821a7ca876dc5af2b075bbac06dff469be 100644 --- a/window_scene/test/unittest/window_pattern/window_pattern_snapshot_test.cpp +++ b/window_scene/test/unittest/window_pattern/window_pattern_snapshot_test.cpp @@ -249,6 +249,74 @@ HWTEST_F(WindowPatternSnapshotTest, HasSnapshot, TestSize.Level1) scenePersistence->SetHasSnapshot(false); ASSERT_EQ(scenePersistence->HasSnapshot(), false); } + +/** + * @tc.name: SetSaveSnapshotCallback + * @tc.desc: test function: SetSaveSnapshotCallback + * @tc.type: FUNC + */ +HWTEST_F(WindowPatternSnapshotTest, SetSaveSnapshotCallback, TestSize.Level1) +{ + std::string bundleName = "testBundleName"; + SessionInfo info; + info.abilityName_ = bundleName; + info.bundleName_ = bundleName; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession->saveSnapshotCallback_); + sceneSession->SetSaveSnapshotCallback(nullptr); + ASSERT_NE(nullptr, sceneSession->saveSnapshotCallback_); +} + +/** + * @tc.name: SetRemoveSnapshotCallback + * @tc.desc: test function: SetRemoveSnapshotCallback + * @tc.type: FUNC + */ +HWTEST_F(WindowPatternSnapshotTest, SetRemoveSnapshotCallback, TestSize.Level1) +{ + std::string bundleName = "testBundleName"; + SessionInfo info; + info.abilityName_ = bundleName; + info.bundleName_ = bundleName; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession->removeSnapshotCallback_); + sceneSession->SetRemoveSnapshotCallback(nullptr); + ASSERT_NE(nullptr, sceneSession->removeSnapshotCallback_); +} + +/** + * @tc.name: SetAddSnapshotCallback + * @tc.desc: test function: SetAddSnapshotCallback + * @tc.type: FUNC + */ +HWTEST_F(WindowPatternSnapshotTest, SetAddSnapshotCallback, TestSize.Level1) +{ + std::string bundleName = "testBundleName"; + SessionInfo info; + info.abilityName_ = bundleName; + info.bundleName_ = bundleName; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession->addSnapshotCallback_); + sceneSession->SetAddSnapshotCallback(nullptr); + ASSERT_NE(nullptr, sceneSession->addSnapshotCallback_); +} + +/** + * @tc.name: NotifyAddSnapshot + * @tc.desc: test function: NotifyAddSnapshot + * @tc.type: FUNC + */ +HWTEST_F(WindowPatternSnapshotTest, NotifyAddSnapshot, TestSize.Level1) +{ + std::string bundleName = "testBundleName"; + SessionInfo info; + info.abilityName_ = bundleName; + info.bundleName_ = bundleName; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession->addSnapshotCallback_); + sceneSession->NotifyAddSnapshot(true); + ASSERT_NE(nullptr, sceneSession->addSnapshotCallback_); +} } } } \ No newline at end of file