diff --git a/frameworks/native/capi/screencapture/native_avscreen_capture.cpp b/frameworks/native/capi/screencapture/native_avscreen_capture.cpp index 96e066eee3a0b58767b096b6924a688cce32208a..dfbc2de5ac6c618fef833602acef4e93c0ddf16d 100644 --- a/frameworks/native/capi/screencapture/native_avscreen_capture.cpp +++ b/frameworks/native/capi/screencapture/native_avscreen_capture.cpp @@ -67,6 +67,23 @@ private: void *userData_; }; +class NativeScreenCaptureContentChangedCallback { + public: + NativeScreenCaptureContentChangedCallback(OH_AVScreenCapture_OnCaptureContentChanged callback, void *userData) + : callback_(callback), userData_(userData) {} + virtual ~NativeScreenCaptureContentChangedCallback() = default; + + void OnCaptureContentChanged(struct OH_AVScreenCapture *capture, AVScreenCaptureContentChangedEvent event) + { + CHECK_AND_RETURN(capture != nullptr && callback_ != nullptr); + callback_(capture, static_cast(event), nullptr, userData_); + } + + private: + OH_AVScreenCapture_OnCaptureContentChanged callback_; + void *userData_; +}; + class NativeScreenCaptureDisplaySelectedCallback { public: NativeScreenCaptureDisplaySelectedCallback(OH_AVScreenCapture_OnDisplaySelected callback, void *userData) @@ -279,6 +296,18 @@ public: } } + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) override + { + MEDIA_LOGI("OnCaptureContentChanged() is called, event: %{public}d", event); + std::shared_lock lock(mutex_); + CHECK_AND_RETURN(capture_ != nullptr); + + if (contentChangedCallback_ != nullptr) { + contentChangedCallback_->OnCaptureContentChanged(capture_, event); + return; + } + } + void OnDisplaySelected(uint64_t displayId) override { MEDIA_LOGI("OnDisplaySelected() is called, displayId (%{public}" PRIu64 ")", displayId); @@ -378,6 +407,13 @@ public: return stateChangeCallback_ != nullptr; } + bool SetCaptureContentChangedCallback(OH_AVScreenCapture_OnCaptureContentChanged callback, void *userData) + { + std::unique_lock lock(mutex_); + contentChangedCallback_ = std::make_shared(callback, userData); + return contentChangedCallback_ != nullptr; + } + bool SetErrorCallback(OH_AVScreenCapture_OnError callback, void *userData) { std::unique_lock lock(mutex_); @@ -410,6 +446,7 @@ private: std::shared_ptr errorCallback_ = nullptr; std::shared_ptr dataCallback_ = nullptr; std::shared_ptr displaySelectedCallback_ = nullptr; + std::shared_ptr contentChangedCallback_ = nullptr; }; struct ScreenCaptureContentFilterObject : public OH_AVScreenCapture_ContentFilter { @@ -863,6 +900,29 @@ OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetStateCallback(struct OH_AVScre return AV_SCREEN_CAPTURE_ERR_OK; } +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetCaptureContentChangedCallback(struct OH_AVScreenCapture *capture, + OH_AVScreenCapture_OnCaptureContentChanged callback, void *userData) +{ + MEDIA_LOGD("OH_AVScreenCapture_SetCaptureContentChangedCallback S"); + CHECK_AND_RETURN_RET_LOG(capture != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "input capture is nullptr!"); + CHECK_AND_RETURN_RET_LOG(callback != nullptr, AV_SCREEN_CAPTURE_ERR_INVALID_VAL, + "input contentChangedCallback is nullptr!"); + struct ScreenCaptureObject *screenCaptureObj = reinterpret_cast(capture); + CHECK_AND_RETURN_RET_LOG(screenCaptureObj->screenCapture_ != nullptr, + AV_SCREEN_CAPTURE_ERR_INVALID_VAL, "screenCapture_ is null"); + + OH_AVSCREEN_CAPTURE_ErrCode errCode = AVScreenCaptureSetCallback(capture, screenCaptureObj); + CHECK_AND_RETURN_RET_LOG(errCode == AV_SCREEN_CAPTURE_ERR_OK, errCode, "SetCaptureContentChangedCallback is null"); + + if (screenCaptureObj->callback_ == nullptr || + !screenCaptureObj->callback_->SetCaptureContentChangedCallback(callback, userData)) { + MEDIA_LOGE("OH_AVScreenCapture_SetCaptureContentChangedCallback error"); + return AV_SCREEN_CAPTURE_ERR_NO_MEMORY; + } + MEDIA_LOGD("OH_AVScreenCapture_SetCaptureContentChangedCallback E"); + return AV_SCREEN_CAPTURE_ERR_OK; +} + OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetErrorCallback(struct OH_AVScreenCapture *capture, OH_AVScreenCapture_OnError callback, void *userData) { diff --git a/interfaces/inner_api/native/screen_capture.h b/interfaces/inner_api/native/screen_capture.h index 5a8605d5803fb92e2bcf13b1fedb095ea454b8e4..eb8dd615c12800696c9a35b544757c1dda907aef 100644 --- a/interfaces/inner_api/native/screen_capture.h +++ b/interfaces/inner_api/native/screen_capture.h @@ -127,6 +127,15 @@ enum AVScreenCaptureBufferType { SCREEN_CAPTURE_BUFFERTYPE_AUDIO_MIC = 2, }; +enum AVScreenCaptureContentChangedEvent { + /* Content is hiden */ + SCREEN_CAPTURE_CONTENT_HIDE = 0, + /* Content is visible */ + SCREEN_CAPTURE_CONTENT_VISIBLE = 1, + /* ScreenCapture stopped by user */ + SCREEN_CAPTURE_CONTENT_UNAVAILABLE = 2, +}; + enum AVScreenCaptureFilterableAudioContent { /* Audio content of notification sound */ SCREEN_CAPTURE_NOTIFICATION_AUDIO = 0, @@ -253,6 +262,12 @@ public: (void)displayId; return; } + + virtual void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) + { + (void)event; + return; + } }; class ScreenCapture { diff --git a/interfaces/kits/c/native_avscreen_capture.h b/interfaces/kits/c/native_avscreen_capture.h index c0b800255476381788f3bcdb2821c26db2828fe7..1c4cdfd36041b41bcf108ec5ae3c324825e7a197 100644 --- a/interfaces/kits/c/native_avscreen_capture.h +++ b/interfaces/kits/c/native_avscreen_capture.h @@ -403,6 +403,22 @@ OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_ShowCursor(struct OH_AVScreenCapt */ OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetDisplayCallback(struct OH_AVScreenCapture *capture, OH_AVScreenCapture_OnDisplaySelected callback, void *userData); + +/** + * @brief Set the Capture Content Changed callback function so that your application can + * customize event handler generated by the av screen capture. This interface must be called before Start is called. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param callback contentchanged callback function, see {@link OH_AVScreenCapture_OnCaptureContentChanged} + * @param userData Pointer to user specific data + * @return Function result code. + * {@link AV_SCREEN_CAPTURE_ERR_OK} if the execution is successful. + * {@link AV_SCREEN_CAPTURE_ERR_INVALID_VAL} input capture is nullptr or input callback is nullptr. + * {@link AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT} opertation not be permitted, set ErrorCallback failed. + * @since 20 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetCaptureContentChangedCallback(struct OH_AVScreenCapture *capture, + OH_AVScreenCapture_OnCaptureContentChanged callback, void *userData); #ifdef __cplusplus } #endif diff --git a/interfaces/kits/c/native_avscreen_capture_base.h b/interfaces/kits/c/native_avscreen_capture_base.h index 0c3e0e8a8613e26b34b91076ec22ebcf1a36f819..e4d57415b266b40c7c355f39a644ea3a5ac3e5ff 100644 --- a/interfaces/kits/c/native_avscreen_capture_base.h +++ b/interfaces/kits/c/native_avscreen_capture_base.h @@ -481,6 +481,21 @@ typedef enum OH_AVScreenCaptureFilterableAudioContent { OH_SCREEN_CAPTURE_CURRENT_APP_AUDIO = 1, } OH_AVScreenCaptureFilterableAudioContent; +/** + * @brief Enumerates screen capture content state. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 20 + */ +typedef enum OH_AVScreenCaptureContentChangedEvent { + /* Content is hiden */ + OH_SCREEN_CAPTURE_CONTENT_HIDE = 0, + /* Content is visible */ + OH_SCREEN_CAPTURE_CONTENT_VISIBLE = 1, + /* ScreenCapture stopped by user */ + OH_SCREEN_CAPTURE_CONTENT_UNAVAILABLE = 2, +} OH_AVScreenCaptureContentChangedEvent; + /** * @brief When state of OH_AVScreenCapture is changed, the function pointer will be called. * @syscap SystemCapability.Multimedia.Media.AVScreenCapture @@ -532,6 +547,20 @@ typedef void (*OH_AVScreenCapture_OnBufferAvailable)(OH_AVScreenCapture *capture */ typedef void (*OH_AVScreenCapture_OnDisplaySelected)(OH_AVScreenCapture *capture, uint64_t displayId, void *userData); +/** + * @brief When Capture Content info changes, the function will be called to notify user + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param {OH_AVScreenCapture*} capture Pointer to an OH_AVScreenCapture instance + * @param {OH_AVScreenCaptureContentChangedEvent} event enum for content change event + * @param {OH_Rect*} area capture content rect position + * @param { void*} userData Pointer to user specific data + * + * @since 20 + * @version 1.0 + */ +typedef void (*OH_AVScreenCapture_OnCaptureContentChanged)(OH_AVScreenCapture* capture, + OH_AVScreenCaptureContentChangedEvent event, OH_Rect* area, void *userData); + #ifdef __cplusplus } #endif diff --git a/services/services/BUILD.gn b/services/services/BUILD.gn index 49d0d7281ed9a1a17a9e2d9e0d170f6df887bb30..7e0b8b854b7ee76e23039edf92e958e5f1e15aa0 100644 --- a/services/services/BUILD.gn +++ b/services/services/BUILD.gn @@ -289,6 +289,9 @@ ohos_shared_library("media_service") { "graphic_surface:sync_fence", "relational_store:native_rdb", "window_manager:libdm", + "window_manager:scene_session", + "window_manager:scene_session_manager", + "window_manager:session_manager_lite", ] } diff --git a/services/services/screen_capture/ipc/i_standard_screen_capture_listener.h b/services/services/screen_capture/ipc/i_standard_screen_capture_listener.h index 4b839e9037ca9a27b6049dde10257abc922c8aa5..b91ca0b3ca1ae900d36ed89be83706d7c0f78e97 100644 --- a/services/services/screen_capture/ipc/i_standard_screen_capture_listener.h +++ b/services/services/screen_capture/ipc/i_standard_screen_capture_listener.h @@ -32,6 +32,7 @@ public: virtual void OnVideoBufferAvailable(bool isReady) = 0; virtual void OnStateChange(AVScreenCaptureStateCode stateCode) = 0; virtual void OnDisplaySelected(uint64_t displayId) = 0; + virtual void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) = 0; /** * IPC code ID */ @@ -40,7 +41,8 @@ public: ON_AUDIO_AVAILABLE = 1, ON_VIDEO_AVAILABLE = 2, ON_STAGE_CHANGE = 3, - ON_DISPLAY_SELECTED = 4 + ON_DISPLAY_SELECTED = 4, + ON_CONTENT_CHANGED = 5 }; DECLARE_INTERFACE_DESCRIPTOR(u"IStandardScreenCaptureListener"); diff --git a/services/services/screen_capture/ipc/screen_capture_listener_proxy.cpp b/services/services/screen_capture/ipc/screen_capture_listener_proxy.cpp index 520cebb4af947bd4f38c9e8d41cff51155cc0217..e3f8ab92bd0c9cb6a5395fdbf7047b616ff06c2a 100644 --- a/services/services/screen_capture/ipc/screen_capture_listener_proxy.cpp +++ b/services/services/screen_capture/ipc/screen_capture_listener_proxy.cpp @@ -93,6 +93,21 @@ void ScreenCaptureListenerProxy::OnStateChange(AVScreenCaptureStateCode stateCod error, stateCode); } +void ScreenCaptureListenerProxy::OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + + bool token = data.WriteInterfaceToken(ScreenCaptureListenerProxy::GetDescriptor()); + CHECK_AND_RETURN_LOG(token, "Failed to write descriptor!"); + + data.WriteInt32(event); + int error = Remote()->SendRequest(ScreenCaptureListenerMsg::ON_CONTENT_CHANGED, data, reply, option); + CHECK_AND_RETURN_LOG(error == MSERR_OK, "OnCaptureContentChanged failed, error: %{public}d, event: %{public}d", + error, event); +} + void ScreenCaptureListenerProxy::OnDisplaySelected(uint64_t displayId) { MessageParcel data; @@ -166,5 +181,14 @@ void ScreenCaptureListenerCallback::OnDisplaySelected(uint64_t displayId) listener_->OnDisplaySelected(displayId); } } + +void ScreenCaptureListenerCallback::OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances isStopped:%{public}d, event: %{public}d", + FAKE_POINTER(this), isStopped_.load(), event); + if (listener_ != nullptr) { + listener_->OnCaptureContentChanged(event); + } +} } // namespace Media } // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_listener_proxy.h b/services/services/screen_capture/ipc/screen_capture_listener_proxy.h index d40dfe860c4566a429b2921e31697cfa76825597..c60017e2c6809e29cd12b46464a831fd9433ab94 100644 --- a/services/services/screen_capture/ipc/screen_capture_listener_proxy.h +++ b/services/services/screen_capture/ipc/screen_capture_listener_proxy.h @@ -33,6 +33,7 @@ public: void OnVideoBufferAvailable(bool isReady) override; void OnStateChange(AVScreenCaptureStateCode stateCode) override; void OnDisplaySelected(uint64_t displayId) override; + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) override; void Stop() { isStopped_ = true; @@ -53,6 +54,7 @@ public: void OnVideoBufferAvailable(bool isReady) override; void OnStateChange(AVScreenCaptureStateCode stateCode) override; void OnDisplaySelected(uint64_t displayId) override; + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) override; private: static inline BrokerDelegator delegator_; diff --git a/services/services/screen_capture/ipc/screen_capture_listener_stub.cpp b/services/services/screen_capture/ipc/screen_capture_listener_stub.cpp index 5ea8df34913b83bba717a959bf432c115a1236e6..7361cc3b531f98b2a24e20e2391f9a903d43b0f2 100644 --- a/services/services/screen_capture/ipc/screen_capture_listener_stub.cpp +++ b/services/services/screen_capture/ipc/screen_capture_listener_stub.cpp @@ -70,6 +70,12 @@ int ScreenCaptureListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &dat OnDisplaySelected(displayId); return MSERR_OK; } + case ScreenCaptureListenerMsg::ON_CONTENT_CHANGED: { + AVScreenCaptureContentChangedEvent event = + static_cast(data.ReadInt32()); + OnCaptureContentChanged(event); + return MSERR_OK; + } default: { MEDIA_LOGE("default case, need check ScreenCaptureListenerStub"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -116,5 +122,12 @@ void ScreenCaptureListenerStub::OnDisplaySelected(uint64_t displayId) callback_->OnDisplaySelected(displayId); } } + +void ScreenCaptureListenerStub::OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) +{ + if (callback_ != nullptr) { + callback_->OnCaptureContentChanged(event); + } +} } // namespace Media } // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_listener_stub.h b/services/services/screen_capture/ipc/screen_capture_listener_stub.h index 7c6c9f36ee7f3b8445af9739119695a1312dbbc9..84a705ac466ca06ed58b0246a84c2a6f7c4616c2 100644 --- a/services/services/screen_capture/ipc/screen_capture_listener_stub.h +++ b/services/services/screen_capture/ipc/screen_capture_listener_stub.h @@ -31,6 +31,7 @@ public: void OnVideoBufferAvailable(bool isReady) override; void OnStateChange(AVScreenCaptureStateCode stateCode) override; void OnDisplaySelected(uint64_t displayId) override; + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) override; void SetScreenCaptureCallback(const std::shared_ptr &callback); private: diff --git a/services/services/screen_capture/server/screen_capture_server.cpp b/services/services/screen_capture/server/screen_capture_server.cpp index c07b776e18973202b5a102b1994ce2ec3a50941d..c25f71a91dd1cae12191dcc50c19209d9fdc60fe 100644 --- a/services/services/screen_capture/server/screen_capture_server.cpp +++ b/services/services/screen_capture/server/screen_capture_server.cpp @@ -42,6 +42,8 @@ #include #include #include +#include "session_manager_lite.h" +#include "window_manager_lite.h" #ifdef PC_STANDARD #include #endif @@ -221,7 +223,9 @@ void ScreenConnectListenerForSC::OnDisconnect(Rosen::ScreenId screenId) MEDIA_LOGI("ScreenConnectListenerForSC OnDisconnect screenId: %{public}" PRIu64, screenId); auto callbackPtr = screenCaptureServer_.lock(); if (callbackPtr && screenId == screenId_) { - MEDIA_LOGI("ScreenConnectListenerForSC OnDisconnect NotifyStateChange: %{public}" PRIu64, screenId_); + MEDIA_LOGI("ScreenConnectListenerForSC OnDisconnect NotifyCaptureContentChanged: %{public}" PRIu64, screenId_); + callbackPtr->NotifyCaptureContentChanged( + AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_UNAVAILABLE); } } @@ -393,6 +397,154 @@ void ScreenCaptureServer::OnDMPrivateWindowChange(bool hasPrivate) AVScreenCaptureStateCode::SCREEN_CAPTURE_STATE_EXIT_PRIVATE_SCENE); } +void ScreenCaptureServer::SetWindowIdList(int32_t windowId) +{ + windowIdList_.push_back(windowId); +} + +std::vector ScreenCaptureServer::GetWindowIdList() +{ + return windowIdList_; +} + +void ScreenCaptureServer::OnSceneSessionManagerDied(const wptr& remote) +{ + MEDIA_LOGI("OnSceneSessionManagerDied Start"); + windowLifecycleListener_ = nullptr; + + auto remoteObj = remote.promote(); + if (!remoteObj) { + MEDIA_LOGD("invalid remote object"); + return; + } + remoteObj->RemoveDeathRecipient(lifecycleListenerDeathRecipient_); + lifecycleListenerDeathRecipient_ = nullptr; + MEDIA_LOGI("SCB Crash! Please Check!"); + + int32_t ret = RegisterWindowLifecycleListener(GetWindowIdList()); + CHECK_AND_RETURN_LOG(ret == MSERR_OK, "OnSceneSessionManagerDied: RegisterWindowLifecycleListener failed."); + MEDIA_LOGI("OnSceneSessionManagerDied End"); +} + +int32_t ScreenCaptureServer::RegisterWindowLifecycleListener(std::vector windowIdList) +{ + MEDIA_LOGI("RegisterWindowLifecycleListener start, windowIdListSize: %{public}d", + static_cast(windowIdList.size())); + + auto sceneSessionManager = SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); + CHECK_AND_RETURN_RET_LOG(sceneSessionManager != nullptr, MSERR_INVALID_OPERATION, + "sceneSessionManager is nullptr, RegisterWindowLifecycleListener failed."); + + if (!lifecycleListenerDeathRecipient_) { + MEDIA_LOGD("RegisterWindowLifecycleListener lifecycleListenerDeathRecipient_ is nullptr"); + auto task = [weakThis = weak_from_this()] (const wptr& remote) { + if (weakThis.lock()) { + auto SCServer = weakThis.lock(); + SCServer->OnSceneSessionManagerDied(remote); + } + }; + lifecycleListenerDeathRecipient_ = sptr::MakeSptr(task); + + auto listenerObject = sceneSessionManager->AsObject(); + if (listenerObject) { + listenerObject->AddDeathRecipient(lifecycleListenerDeathRecipient_); + MEDIA_LOGD("RegisterWindowLifecycleListener AddDeathRecipient success."); + } + } + + if (windowLifecycleListener_ != nullptr) { + MEDIA_LOGI("RegisterWindowLifecycleListener windowLifecycleListener already registered"); + return MSERR_OK; + } + std::weak_ptr screenCaptureServer(shared_from_this()); + sptr listener(new (std::nothrow) SCWindowLifecycleListener(screenCaptureServer)); + CHECK_AND_RETURN_RET_LOG(listener != nullptr, MSERR_INVALID_OPERATION, + "create new windowLifecycleListener failed."); + windowLifecycleListener_ = listener; + + Rosen::WMError ret = sceneSessionManager->RegisterSessionLifecycleListenerByIds(windowLifecycleListener_, + windowIdList); + CHECK_AND_RETURN_RET_LOG(ret == Rosen::WMError::WM_OK, MSERR_INVALID_OPERATION, + "RegisterSessionLifecycleListenerByIds failed."); + + MEDIA_LOGI("RegisterWindowLifecycleListener end."); + return MSERR_OK; +} + +int32_t ScreenCaptureServer::UnRegisterWindowLifecycleListener() +{ + MEDIA_LOGI("UnRegisterWindowLifecycleListener start."); + auto sceneSessionManager = SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); + CHECK_AND_RETURN_RET_LOG(sceneSessionManager != nullptr, MSERR_INVALID_OPERATION, + "sceneSessionManager is nullptr, UnRegisterWindowLifecycleListener failed."); + + if (lifecycleListenerDeathRecipient_) { + MEDIA_LOGD("UnRegisterWindowLifecycleListener lifecycleListenerDeathRecipient_ != nullptr"); + auto listenerObject = sceneSessionManager->AsObject(); + if (listenerObject) { + listenerObject->RemoveDeathRecipient(lifecycleListenerDeathRecipient_); + MEDIA_LOGD("UnRegisterWindowLifecycleListener RemoveDeathRecipient success."); + } + lifecycleListenerDeathRecipient_ = nullptr; + } + + if (!windowLifecycleListener_) { + MEDIA_LOGI("windowLifecycleListener already unregistered"); + return MSERR_OK; + } + Rosen::WMError ret = sceneSessionManager->UnregisterSessionLifecycleListener(windowLifecycleListener_); + CHECK_AND_RETURN_RET_LOG(ret == Rosen::WMError::WM_OK, MSERR_INVALID_OPERATION, + "UnRegisterWindowLifecycleListener failed."); + windowLifecycleListener_ = nullptr; + + MEDIA_LOGI("UnRegisterWindowLifecycleListener end."); + return MSERR_OK; +} + +void ScreenCaptureServer::NotifyCaptureContentChanged(AVScreenCaptureContentChangedEvent event) +{ + if (screenCaptureCb_ != nullptr) { + MEDIA_LOGI("NotifyCaptureContentChanged event: %{public}d", event); + screenCaptureCb_->OnCaptureContentChanged(event); + } +} + +SCWindowLifecycleListener::SCWindowLifecycleListener(std::weak_ptr screenCaptureServer) +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); + screenCaptureServer_ = screenCaptureServer; +} + +void SCWindowLifecycleListener::OnLifecycleEvent(SessionLifecycleEvent event, const LifecycleEventPayload& payload) +{ + MEDIA_LOGD("SCWindowLifecycleListener::OnLifecycleEvent Start."); + auto SCServer = screenCaptureServer_.lock(); + CHECK_AND_RETURN_LOG(SCServer != nullptr, "screenCaptureServer is nullptr"); + switch (event) { + case SessionLifecycleEvent::FOREGROUND: { + MEDIA_LOGI("OnLifecycleEvent: SessionLifecycleEvent::FOREGROUND"); + SCServer->NotifyCaptureContentChanged(AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_VISIBLE); + break; + } + case SessionLifecycleEvent::BACKGROUND: { + MEDIA_LOGI("OnLifecycleEvent: SessionLifecycleEvent::BACKGROUND"); + SCServer->NotifyCaptureContentChanged(AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_HIDE); + break; + } + case SessionLifecycleEvent::DESTROYED: { + MEDIA_LOGI("OnLifecycleEvent: SessionLifecycleEvent::DESTROYED"); + SCServer->NotifyCaptureContentChanged( + AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_UNAVAILABLE); + break; + } + default: { + MEDIA_LOGD("OnLifecycleEvent: other event"); + break; + } + } + MEDIA_LOGD("SCWindowLifecycleListener::OnLifecycleEvent End."); +} + bool ScreenCaptureServer::CanScreenCaptureInstanceBeCreate(int32_t appUid) { MEDIA_LOGI("CanScreenCaptureInstanceBeCreate start."); @@ -574,7 +726,7 @@ void ScreenCaptureServer::SetCaptureConfig(CaptureMode captureMode, int32_t miss { captureConfig_.captureMode = captureMode; if (missionId != -1) { // -1 无效值 - captureConfig_.videoInfo.videoCapInfo.taskIDs.push_back(missionId); + captureConfig_.videoInfo.videoCapInfo.taskIDs = { missionId }; } else { captureConfig_.videoInfo.videoCapInfo.taskIDs = {}; } @@ -1682,6 +1834,10 @@ void ScreenCaptureServer::PostStartScreenCapture(bool isSuccess) } RegisterPrivateWindowListener(); RegisterScreenConnectListener(); + if (captureConfig_.captureMode == CAPTURE_SPECIFIED_WINDOW && missionIds_.size() == 1) { + SetWindowIdList(missionIds_[0]); + RegisterWindowLifecycleListener(GetWindowIdList()); + } MEDIA_LOGI("ScreenCaptureServer: 0x%{public}06" PRIXPTR " PostStartScreenCapture end.", FAKE_POINTER(this)); } @@ -3538,6 +3694,7 @@ int32_t ScreenCaptureServer::StopScreenCaptureInner(AVScreenCaptureStateCode sta screenCaptureObserverCb_->Release(); } ScreenManager::GetInstance().UnregisterScreenListener(screenConnectListener_); + UnRegisterWindowLifecycleListener(); MEDIA_LOGI("ScreenCaptureServer: 0x%{public}06" PRIXPTR " StopScreenCaptureInner end.", FAKE_POINTER(this)); return ret; } diff --git a/services/services/screen_capture/server/screen_capture_server.h b/services/services/screen_capture/server/screen_capture_server.h index ef902a3f22c249cea7b0e93478d08c1bf8f7c964..406751f4f4d1a2dd6fafa46498a3c5513fe10d52 100644 --- a/services/services/screen_capture/server/screen_capture_server.h +++ b/services/services/screen_capture/server/screen_capture_server.h @@ -123,12 +123,16 @@ public: int32_t GetAppUid(); void NotifyStateChange(AVScreenCaptureStateCode stateCode); void NotifyDisplaySelected(uint64_t displayId); + void NotifyCaptureContentChanged(AVScreenCaptureContentChangedEvent event); void SetMouseChangeListener(std::shared_ptr listener); std::shared_ptr GetMouseChangeListener(); int32_t SetAndCheckAppInfo(OHOS::AudioStandard::AppInfo &appInfo); void SetSCServerSaUid(int32_t saUid); int32_t GetSCServerSaUid(); DataType GetSCServerDataType(); + void SetWindowIdList(int32_t windowId); + std::vector GetWindowIdList(); + void OnSceneSessionManagerDied(const wptr& remote); private: int32_t StartScreenCaptureInner(bool isPrivacyAuthorityEnabled); @@ -236,6 +240,8 @@ private: #endif bool DestroyPopWindow(); void StopNotStartedScreenCapture(AVScreenCaptureStateCode stateCode); + int32_t RegisterWindowLifecycleListener(std::vector windowIdList); + int32_t UnRegisterWindowLifecycleListener(); private: std::mutex mutex_; @@ -272,6 +278,7 @@ private: ScreenId virtualScreenId_ = SCREEN_ID_INVALID; ScreenId displayScreenId_ = SCREEN_ID_INVALID; std::vector missionIds_; + std::vector windowIdList_ = {}; ScreenCaptureContentFilter contentFilter_; AVScreenCaptureState captureState_ = AVScreenCaptureState::CREATED; std::shared_ptr localLiveViewContent_; @@ -279,6 +286,8 @@ private: sptr mmiListener_ = nullptr; std::shared_ptr mouseChangeListener_ = nullptr; sptr connection_ = nullptr; + sptr windowLifecycleListener_ = nullptr; + sptr lifecycleListenerDeathRecipient_ = nullptr; /* used for CAPTURE STREAM */ sptr surfaceCb_ = nullptr; diff --git a/services/services/screen_capture/server/screen_capture_server_base.h b/services/services/screen_capture/server/screen_capture_server_base.h index 8fe66041257ab9e7126b64415f1a748d53d8edfc..96d6eb2a55a95538d29bc3b41eadd2930bd9c54a 100644 --- a/services/services/screen_capture/server/screen_capture_server_base.h +++ b/services/services/screen_capture/server/screen_capture_server_base.h @@ -64,6 +64,7 @@ #include "system_ability_status_change_stub.h" #include "i_input_device_listener.h" #include "input_manager.h" +#include "session_lifecycle_listener_stub.h" namespace OHOS { namespace Media { @@ -326,6 +327,32 @@ private: uint64_t screenId_ = SCREEN_ID_INVALID; std::weak_ptr screenCaptureServer_; }; + +class SCWindowLifecycleListener : public Rosen::SessionLifecycleListenerStub { +public: + explicit SCWindowLifecycleListener(std::weak_ptr screenCaptureServer); + ~SCWindowLifecycleListener() override = default; + void OnLifecycleEvent(SessionLifecycleEvent event, const LifecycleEventPayload& payload) override; + +private: + std::weak_ptr screenCaptureServer_; +}; + +class SCDeathRecipientListener : public IRemoteObject::DeathRecipient { +public: + using ListenerDiedHandler = std::function&)>; + explicit SCDeathRecipientListener(ListenerDiedHandler handler) : diedHandler_(std::move(handler)) {} + ~SCDeathRecipientListener() override = default; + void OnRemoteDied(const wptr& remote) final + { + if (diedHandler_) { + diedHandler_(remote); + } + } + +private: + ListenerDiedHandler diedHandler_; +}; } // namespace Media } // namespace OHOS #endif // SCREEN_CAPTURE_SERVICE_SERVER_BASE_H diff --git a/test/fuzztest/screen_capture_fuzztest/screencaptureserverstartcase_fuzzer/BUILD.gn b/test/fuzztest/screen_capture_fuzztest/screencaptureserverstartcase_fuzzer/BUILD.gn index abca599e659ff93281fcb0043fec08541dafdbbf..f627bd640a33c92c2b14a9e429b6c43ff229068d 100644 --- a/test/fuzztest/screen_capture_fuzztest/screencaptureserverstartcase_fuzzer/BUILD.gn +++ b/test/fuzztest/screen_capture_fuzztest/screencaptureserverstartcase_fuzzer/BUILD.gn @@ -140,6 +140,9 @@ ohos_fuzztest("ScreenCaptureServerStartCaseFuzzTest") { "safwk:system_ability_fwk", "samgr:samgr_proxy", "window_manager:libdm", + "window_manager:scene_session", + "window_manager:scene_session_manager", + "window_manager:session_manager_lite", ] if (player_framework_support_screen_capture_stopbycall) { external_deps += [ diff --git a/test/unittest/screen_capture_test/BUILD.gn b/test/unittest/screen_capture_test/BUILD.gn index 4a86dd4c84b037410d052f4a4a7877a0b7a9c0b3..ccb18c29ca4b5717b41e9aff221cccc9a57bb111 100644 --- a/test/unittest/screen_capture_test/BUILD.gn +++ b/test/unittest/screen_capture_test/BUILD.gn @@ -298,6 +298,9 @@ ohos_unittest("screen_capture_server_function_unit_test") { "resource_management:global_resmgr", "state_registry:tel_state_registry_api", "window_manager:libdm", + "window_manager:scene_session", + "window_manager:scene_session_manager", + "window_manager:session_manager_lite", ] if (player_framework_support_power_manager) { diff --git a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/include/screen_capture_server_function_unittest.h b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/include/screen_capture_server_function_unittest.h index 66c36135e1fa7b29b477f117dfafa2b4a8f77c54..ecbf36784abf9448c97a5d1d33e047f5e06c34e6 100644 --- a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/include/screen_capture_server_function_unittest.h +++ b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/include/screen_capture_server_function_unittest.h @@ -118,6 +118,7 @@ public: void OnVideoBufferAvailable(bool isReady) {}; void OnStateChange(AVScreenCaptureStateCode stateCode) {}; void OnDisplaySelected(uint64_t displayId) {}; + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) {}; }; class ScreenCaptureServerUnittestCallbackMock : public ScreenCaptureListenerCallback { @@ -130,6 +131,7 @@ public: void OnVideoBufferAvailable(bool isReady); void OnStateChange(AVScreenCaptureStateCode stateCode); void OnDisplaySelected(uint64_t displayId); + void OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event); void Stop(); }; } // Media diff --git a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_multiInstance.cpp b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_multiInstance.cpp index e74d585384d067532f615c706347be2144663772..c70461abfee1ceaf5470f9306a876ce7144c2170 100644 --- a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_multiInstance.cpp +++ b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_multiInstance.cpp @@ -812,5 +812,75 @@ HWTEST_F(ScreenCaptureServerFunctionTest, CheckSpecifiedDataTypeNum_002, TestSiz ASSERT_EQ(ScreenCaptureServer::CheckSCServerSpecifiedDataTypeNum(server->appInfo_.appUid, server->captureConfig_.dataType), false); } + +HWTEST_F(ScreenCaptureServerFunctionTest, ProcessWindowIdList_001, TestSize.Level2) +{ + screenCaptureServer_->windowIdList_ = {}; + int32_t windowId = 0; + screenCaptureServer_->SetWindowIdList(windowId); + ASSERT_EQ((screenCaptureServer_->GetWindowIdList()).size(), 1); +} + +HWTEST_F(ScreenCaptureServerFunctionTest, NotifyCaptureContentChanged_001, TestSize.Level2) +{ + screenCaptureServer_->NotifyCaptureContentChanged(AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_HIDE); + screenCaptureServer_->NotifyCaptureContentChanged( + AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_VISIBLE); + screenCaptureServer_->NotifyCaptureContentChanged( + AVScreenCaptureContentChangedEvent::SCREEN_CAPTURE_CONTENT_UNAVAILABLE); +} + +#ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION +HWTEST_F(ScreenCaptureServerFunctionTest, WindowLifecycleListener_001, TestSize.Level2) +{ + screenCaptureServer_->windowIdList_ = {}; + int32_t windowId = 70; + screenCaptureServer_->SetWindowIdList(windowId); + screenCaptureServer_->windowLifecycleListener_ = nullptr; + screenCaptureServer_->lifecycleListenerDeathRecipient_ = nullptr; + screenCaptureServer_->RegisterWindowLifecycleListener(screenCaptureServer_->GetWindowIdList()); + ASSERT_NE(screenCaptureServer_->lifecycleListenerDeathRecipient_, nullptr); + ASSERT_NE(screenCaptureServer_->windowLifecycleListener_, nullptr); + screenCaptureServer_->UnRegisterWindowLifecycleListener(); + ASSERT_EQ(screenCaptureServer_->lifecycleListenerDeathRecipient_, nullptr); + ASSERT_EQ(screenCaptureServer_->windowLifecycleListener_, nullptr); +} + +HWTEST_F(ScreenCaptureServerFunctionTest, StartScreenCaptureRegisterListener_001, TestSize.Level2) +{ + screenCaptureServer_->isPrivacyAuthorityEnabled_ = true; + screenCaptureServer_->isScreenCaptureAuthority_ = true; + screenCaptureServer_->captureConfig_.captureMode = CaptureMode::CAPTURE_SPECIFIED_WINDOW; + screenCaptureServer_->windowLifecycleListener_ = nullptr; + screenCaptureServer_->lifecycleListenerDeathRecipient_ = nullptr; + + screenCaptureServer_->missionIds_ = {}; + screenCaptureServer_->missionIds_.push_back(70); + ASSERT_EQ(screenCaptureServer_->missionIds_.size(), 1); + screenCaptureServer_->PostStartScreenCapture(true); + + ASSERT_EQ((screenCaptureServer_->GetWindowIdList()).size(), 1); + ASSERT_NE(screenCaptureServer_->lifecycleListenerDeathRecipient_, nullptr); + ASSERT_NE(screenCaptureServer_->windowLifecycleListener_, nullptr); +} + +HWTEST_F(ScreenCaptureServerFunctionTest, StartScreenCaptureRegisterListener_002, TestSize.Level2) +{ + screenCaptureServer_->isPrivacyAuthorityEnabled_ = true; + screenCaptureServer_->isScreenCaptureAuthority_ = true; + screenCaptureServer_->captureConfig_.captureMode = CaptureMode::CAPTURE_SPECIFIED_SCREEN; + screenCaptureServer_->windowLifecycleListener_ = nullptr; + screenCaptureServer_->lifecycleListenerDeathRecipient_ = nullptr; + + screenCaptureServer_->missionIds_ = {}; + screenCaptureServer_->missionIds_.push_back(70); + ASSERT_EQ(screenCaptureServer_->missionIds_.size(), 1); + screenCaptureServer_->PostStartScreenCapture(true); + + ASSERT_EQ((screenCaptureServer_->GetWindowIdList()).size(), 0); + ASSERT_EQ(screenCaptureServer_->lifecycleListenerDeathRecipient_, nullptr); + ASSERT_EQ(screenCaptureServer_->windowLifecycleListener_, nullptr); +} +#endif } // Media } // OHOS \ No newline at end of file diff --git a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_recorder.cpp b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_recorder.cpp index 98b3ffaa2bcc6314129b18449626272e8853283f..8834d643762603c2d7c2088ea735f19dd0804da1 100644 --- a/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_recorder.cpp +++ b/test/unittest/screen_capture_test/screen_capture_service_function_unittest/server/src/screen_capture_server_function_unittest_recorder.cpp @@ -64,6 +64,11 @@ void ScreenCaptureServerUnittestCallbackMock::OnDisplaySelected(uint64_t display MEDIA_LOGI("OnDisplaySelected() is called, displayId %{public}" PRIu64, displayId); } +void ScreenCaptureServerUnittestCallbackMock::OnCaptureContentChanged(AVScreenCaptureContentChangedEvent event) +{ + MEDIA_LOGI("OnCaptureContentChanged() is called, event: %{public}d", event); +} + void ScreenCaptureServerUnittestCallbackMock::Stop() { MEDIA_LOGD("Stop() is called");