diff --git a/bundle.json b/bundle.json index c4f08514982468dfad6eb24568a3f4df6e4740e8..86e4d5c70c5ab23c39e0eb15b9d056861f2a3d50 100644 --- a/bundle.json +++ b/bundle.json @@ -64,6 +64,7 @@ "ability_base", "ability_runtime", "bundle_framework", + "distributed_notification_service", "relational_store", "resource_management", "av_codec", diff --git a/frameworks/native/screen_capture/screen_capture_controller_impl.cpp b/frameworks/native/screen_capture/screen_capture_controller_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..929b04118c002942ccfdf56b8739eacbbc0597f7 --- /dev/null +++ b/frameworks/native/screen_capture/screen_capture_controller_impl.cpp @@ -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. + */ + +#include "screen_capture_controller_impl.h" +#include "media_log.h" +#include "media_errors.h" +#include "i_media_service.h" + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureController"}; +} +namespace OHOS { +namespace Media { +std::shared_ptr ScreenCaptureControllerFactory::CreateScreenCaptureController() +{ + std::shared_ptr impl = std::make_shared(); + CHECK_AND_RETURN_RET_LOG(impl != nullptr, nullptr, "failed to new ScreenCaptureControllerImpl"); + + return impl; +} + +void ScreenCaptureControllerImpl::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + MEDIA_LOGI("ScreenCaptureController::ReportAVScreenCaptureUserChoice start"); + std::shared_ptr controllerClient = + MediaServiceFactory::GetInstance().CreateScreenCaptureControllerClient(); + + int32_t ret = controllerClient->ReportAVScreenCaptureUserChoice(sessionId, choice); + MEDIA_LOGI("ScreenCaptureController::ReportAVScreenCaptureUserChoice Report result: %{public}d", ret); + + (void)MediaServiceFactory::GetInstance().DestroyScreenCaptureControllerClient(controllerClient); + controllerClient = nullptr; +} + +ScreenCaptureControllerImpl::ScreenCaptureControllerImpl() +{ + MEDIA_LOGD("ScreenCaptureControllerImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); +} + +ScreenCaptureControllerImpl::~ScreenCaptureControllerImpl() +{ + MEDIA_LOGD("ScreenCaptureControllerImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this)); +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/screen_capture/screen_capture_controller_impl.h b/frameworks/native/screen_capture/screen_capture_controller_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d268f128f43cb16e05299432b92fb70244a51630 --- /dev/null +++ b/frameworks/native/screen_capture/screen_capture_controller_impl.h @@ -0,0 +1,32 @@ +/* + * 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 SCREEN_CAPTURE_CONTROLLER_IMPL_H +#define SCREEN_CAPTURE_CONTROLLER_IMPL_H + +#include "screen_capture_controller.h" +#include "nocopyable.h" +#include "i_screen_capture_controller.h" + +namespace OHOS { +namespace Media { +class ScreenCaptureControllerImpl : public ScreenCaptureController, public NoCopyable { +public: + void ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) override; + ScreenCaptureControllerImpl(); + ~ScreenCaptureControllerImpl(); +}; +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_CONTROLLER_IMPL_H \ No newline at end of file diff --git a/interfaces/inner_api/native/BUILD.gn b/interfaces/inner_api/native/BUILD.gn index e81c116a736ff472d9ddeb1fe6f77fa84a49c7f7..cf510a0151c2ad81ada30ad279ce42cc305cba44 100644 --- a/interfaces/inner_api/native/BUILD.gn +++ b/interfaces/inner_api/native/BUILD.gn @@ -159,8 +159,11 @@ ohos_shared_library("media_client") { } if (multimedia_player_framework_support_screen_capture) { sources += [ + "$MEDIA_ROOT_DIR/frameworks/native/screen_capture/screen_capture_controller_impl.cpp", "$MEDIA_ROOT_DIR/frameworks/native/screen_capture/screen_capture_impl.cpp", "$MEDIA_ROOT_DIR/services/services/screen_capture/client/screen_capture_client.cpp", + "$MEDIA_ROOT_DIR/services/services/screen_capture/client/screen_capture_controller_client.cpp", + "$MEDIA_ROOT_DIR/services/services/screen_capture/ipc/screen_capture_controller_proxy.cpp", "$MEDIA_ROOT_DIR/services/services/screen_capture/ipc/screen_capture_listener_stub.cpp", "$MEDIA_ROOT_DIR/services/services/screen_capture/ipc/screen_capture_service_proxy.cpp", ] diff --git a/interfaces/inner_api/native/player_framework.versionscript b/interfaces/inner_api/native/player_framework.versionscript index 588bfc66d5e4eb65c6412645d9d1577daff5c726..d300f0c73072ed94c750b8e9ee59dc882fe1eea2 100644 --- a/interfaces/inner_api/native/player_framework.versionscript +++ b/interfaces/inner_api/native/player_framework.versionscript @@ -23,6 +23,7 @@ *OHOS::Media::AVMetadataHelperFactory::Create*; *OHOS::Media::RecorderProfilesFactory::Create*; *OHOS::Media::ScreenCaptureFactory::CreateScreenCapture*; + *OHOS::Media::ScreenCaptureControllerFactory::CreateScreenCaptureController*; *OHOS::Media::Format::*; *OHOS::Media::VideoCaps::*; *OHOS::Media::AudioCaps::*; diff --git a/interfaces/inner_api/native/screen_capture_controller.h b/interfaces/inner_api/native/screen_capture_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..c783680ff08426276e03fd39600904ea628f400c --- /dev/null +++ b/interfaces/inner_api/native/screen_capture_controller.h @@ -0,0 +1,50 @@ +/* + * 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 SCREEN_CAPTURE_CONTROLLER_H +#define SCREEN_CAPTURE_CONTROLLER_H + +#include +#include +#include + +namespace OHOS { +namespace Media { + +class ScreenCaptureController { +public: + virtual void ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) = 0; + virtual ~ScreenCaptureController() = default; +}; + +class __attribute__((visibility("default"))) ScreenCaptureControllerFactory { +public: +#ifdef UNSUPPORT_SCREEN_CAPTURE + static std::shared_ptr CreateScreenCaptureController() + { + return nullptr; + } +#else + static std::shared_ptr CreateScreenCaptureController(); +#endif + +private: + ScreenCaptureControllerFactory() = default; + ~ScreenCaptureControllerFactory() = default; +}; + +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_CONTROLLER_H \ No newline at end of file diff --git a/services/include/i_media_service.h b/services/include/i_media_service.h index 82b844424741a24b944b3c63f4ef79231505346a..7db7c54422ac72e46d1195231941e325df88b1c8 100644 --- a/services/include/i_media_service.h +++ b/services/include/i_media_service.h @@ -33,6 +33,7 @@ #endif #ifdef SUPPORT_SCREEN_CAPTURE #include "i_screen_capture_service.h" +#include "i_screen_capture_controller.h" #endif #include "i_standard_monitor_service.h" @@ -211,6 +212,29 @@ public: * @version 1.0 */ virtual int32_t DestroyScreenCaptureService(std::shared_ptr screenCaptureHelper) = 0; + + /** + * @brief Create an ScreenCaptureControllerClient service. + * + * All player functions must be created and obtained first. + * + * @return Returns a valid pointer if the setting is successful; + * @since 1.0 + * @version 1.0 + */ + virtual std::shared_ptr CreateScreenCaptureControllerClient() = 0; + + /** + * @brief Destroy a ScreenCaptureControllerClient service. + * + * call the API to destroy the ScreenCaptureControllerClient service. + * + * @param pointer to the ScreenCaptureControllerClient service. + * @return Returns a valid pointer if the setting is successful; + * @since 1.0 + * @version 1.0 + */ + virtual int32_t DestroyScreenCaptureControllerClient(std::shared_ptr controller) = 0; #endif /** diff --git a/services/include/i_screen_capture_controller.h b/services/include/i_screen_capture_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..143a456911ce6355a02aade639c40419292f5279 --- /dev/null +++ b/services/include/i_screen_capture_controller.h @@ -0,0 +1,30 @@ +/* + * 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 I_SCREEN_CAPTURE_CONTROLLER_H +#define I_SCREEN_CAPTURE_CONTROLLER_H + +#include +#include "refbase.h" + +namespace OHOS { +namespace Media { +class IScreenCaptureController { +public: + virtual int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) = 0; +}; +} // namespace Media +} // namespace OHOS +#endif // I_SCREEN_CAPTURE_CONTROLLER_H \ No newline at end of file diff --git a/services/services/BUILD.gn b/services/services/BUILD.gn index b5a395d67be67987720efb7003484070d6a120c2..478864d25159557e14e9669ef27d8ff1edde346f 100644 --- a/services/services/BUILD.gn +++ b/services/services/BUILD.gn @@ -168,9 +168,12 @@ ohos_shared_library("media_service") { if (multimedia_player_framework_support_screen_capture) { sources += [ + "screen_capture/ipc/screen_capture_controller_stub.cpp", "screen_capture/ipc/screen_capture_listener_proxy.cpp", "screen_capture/ipc/screen_capture_service_stub.cpp", + "screen_capture/server/screen_capture_controller_server.cpp", "screen_capture/server/screen_capture_server.cpp", + "screen_capture/server/ui_extension_ability_connection.cpp", ] } @@ -211,12 +214,20 @@ ohos_shared_library("media_service") { if (multimedia_player_framework_support_screen_capture) { external_deps += [ + "ability_base:base", + "ability_base:want", + "ability_base:zuri", + "ability_runtime:ability_context_native", + "ability_runtime:abilitykit_native", + "ability_runtime:extension_manager", "ability_runtime:runtime", "access_token:libnativetoken", "access_token:libprivacy_sdk", "access_token:libtoken_setproc", "audio_framework:audio_capturer", "audio_framework:audio_client", + "distributed_notification_service:ans_innerkits", + "relational_store:native_rdb", "window_manager:libdm", ] } diff --git a/services/services/sa_media/client/media_client.cpp b/services/services/sa_media/client/media_client.cpp index 48655bdf8ae48221cbad624ec210873882df28db..bb86645c8031855ac7e4c56fff590c4713dab11c 100644 --- a/services/services/sa_media/client/media_client.cpp +++ b/services/services/sa_media/client/media_client.cpp @@ -266,6 +266,36 @@ int32_t MediaClient::DestroyScreenCaptureService(std::shared_ptr MediaClient::CreateScreenCaptureControllerClient() +{ + std::lock_guard lock(mutex_); + MEDIA_LOGI("MediaClient::CreateScreenCaptureControllerClient() start"); + CHECK_AND_RETURN_RET_LOG(IsAlived(), nullptr, "media service does not exist."); + + sptr object = mediaProxy_->GetSubSystemAbility( + IStandardMediaService::MediaSystemAbility::MEDIA_SCREEN_CAPTURE_CONTROLLER, listenerStub_->AsObject()); + CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "screenCapture controller proxy object is nullptr."); + + sptr controllerProxy = iface_cast(object); + CHECK_AND_RETURN_RET_LOG(controllerProxy != nullptr, nullptr, "controllerProxy is nullptr."); + + std::shared_ptr controller = ScreenCaptureControllerClient::Create(controllerProxy); + CHECK_AND_RETURN_RET_LOG(controller != nullptr, nullptr, "failed to create screenCapture controller."); + + screenCaptureControllerList_.push_back(controller); + MEDIA_LOGI("MediaClient::CreateScreenCaptureControllerClient() end"); + return controller; +} + +int32_t MediaClient::DestroyScreenCaptureControllerClient(std::shared_ptr controller) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(controller != nullptr, MSERR_NO_MEMORY, + "input screenCapture controller is nullptr."); + screenCaptureControllerList_.remove(controller); + return MSERR_OK; +} #endif sptr MediaClient::GetMonitorProxy() diff --git a/services/services/sa_media/client/media_client.h b/services/services/sa_media/client/media_client.h index 3fbeb1292f01e4c776274f25b86769b5de66cc86..fa2cb808d8ba04dd9e6e75ae4779eb073519c706 100644 --- a/services/services/sa_media/client/media_client.h +++ b/services/services/sa_media/client/media_client.h @@ -36,6 +36,7 @@ #endif #ifdef SUPPORT_SCREEN_CAPTURE #include "screen_capture_client.h" +#include "screen_capture_controller_client.h" #endif #include "nocopyable.h" @@ -70,6 +71,8 @@ public: #ifdef SUPPORT_SCREEN_CAPTURE std::shared_ptr CreateScreenCaptureService() override; int32_t DestroyScreenCaptureService(std::shared_ptr screenCapture) override; + std::shared_ptr CreateScreenCaptureControllerClient() override; + int32_t DestroyScreenCaptureControllerClient(std::shared_ptr controller) override; #endif private: @@ -99,6 +102,7 @@ private: #endif #ifdef SUPPORT_SCREEN_CAPTURE std::list> screenCaptureClientList_; + std::list> screenCaptureControllerList_; #endif std::mutex mutex_; }; diff --git a/services/services/sa_media/ipc/i_standard_media_service.h b/services/services/sa_media/ipc/i_standard_media_service.h index 4f3cf7b54d2bbc701b73b5ae1db8b29771db1dcb..449f7db46177fc172a3a676905b2719d76d8aa99 100644 --- a/services/services/sa_media/ipc/i_standard_media_service.h +++ b/services/services/sa_media/ipc/i_standard_media_service.h @@ -38,6 +38,7 @@ public: RECORDER_PROFILES = 6, MEDIA_MONITOR = 7, MEDIA_SCREEN_CAPTURE = 8, + MEDIA_SCREEN_CAPTURE_CONTROLLER = 9, }; /** diff --git a/services/services/sa_media/server/media_server.cpp b/services/services/sa_media/server/media_server.cpp index a74458893780abfa9fda29c70d32cf73be33819d..81c5f8a077afc3200ed9ee618141b3a5cbe139a5 100644 --- a/services/services/sa_media/server/media_server.cpp +++ b/services/services/sa_media/server/media_server.cpp @@ -86,6 +86,9 @@ sptr MediaServer::GetSubSystemAbility(IStandardMediaService::Medi case MediaSystemAbility::MEDIA_SCREEN_CAPTURE: { return MediaServerManager::GetInstance().CreateStubObject(MediaServerManager::SCREEN_CAPTURE); } + case MediaSystemAbility::MEDIA_SCREEN_CAPTURE_CONTROLLER: { + return MediaServerManager::GetInstance().CreateStubObject(MediaServerManager::SCREEN_CAPTURE_CONTROLLER); + } default: { MEDIA_LOGE("default case, media client need check subSystemId"); return nullptr; diff --git a/services/services/sa_media/server/media_server_manager.cpp b/services/services/sa_media/server/media_server_manager.cpp index 35ed136b838280963bbe685bad209ee471bc72b1..f6c41fb257d9c9ea3ee6858866502bcaa8af70ef 100644 --- a/services/services/sa_media/server/media_server_manager.cpp +++ b/services/services/sa_media/server/media_server_manager.cpp @@ -34,6 +34,7 @@ #endif #ifdef SUPPORT_SCREEN_CAPTURE #include "screen_capture_service_stub.h" +#include "screen_capture_controller_stub.h" #endif #include "monitor_service_stub.h" #include "media_log.h" @@ -167,6 +168,8 @@ sptr MediaServerManager::CreateStubObject(StubType type) #ifdef SUPPORT_SCREEN_CAPTURE case SCREEN_CAPTURE: return CreateScreenCaptureStubObject(); + case SCREEN_CAPTURE_CONTROLLER: + return CreateScreenCaptureControllerStubObject(); #endif case MONITOR: return GetMonitorStubObject(); @@ -364,6 +367,27 @@ sptr MediaServerManager::CreateScreenCaptureStubObject() MEDIA_LOGD("The number of screen capture services(%{public}zu).", screenCaptureStubMap_.size()); return object; } + +sptr MediaServerManager::CreateScreenCaptureControllerStubObject() +{ + MEDIA_LOGI("MediaServerManager::CreateScreenCaptureControllerStubObject() start"); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerStubMap_.size() < SERVER_MAX_NUMBER, + nullptr, "The number of screen capture controller services(%{public}zu) has reached the upper limit." + "Please release the applied resources.", screenCaptureControllerStubMap_.size()); + + sptr screenCaptureControllerStub = ScreenCaptureControllerStub::Create(); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerStub != nullptr, nullptr, + "failed to create ScreenCaptureControllerStub"); + + sptr object = screenCaptureControllerStub->AsObject(); + CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to create screenCaptureControllerStub"); + + pid_t pid = IPCSkeleton::GetCallingPid(); + screenCaptureControllerStubMap_[object] = pid; + MEDIA_LOGD("The number of screen capture services(%{public}zu).", screenCaptureControllerStubMap_.size()); + MEDIA_LOGI("MediaServerManager::CreateScreenCaptureControllerStubObject() end"); + return object; +} #endif sptr MediaServerManager::GetMonitorStubObject() @@ -501,6 +525,19 @@ void MediaServerManager::DestroyStubObject(StubType type, sptr ob MEDIA_LOGE("find screen capture object failed, pid(%{public}d).", pid); break; } + case SCREEN_CAPTURE_CONTROLLER: { + for (auto it = screenCaptureControllerStubMap_.begin(); + it != screenCaptureControllerStubMap_.end(); it++) { + if (it->first == object) { + MEDIA_LOGD("destroy screen capture controller stub services(%{public}zu) pid(%{public}d).", + screenCaptureControllerStubMap_.size(), pid); + (void)screenCaptureControllerStubMap_.erase(it); + return; + } + } + MEDIA_LOGE("find screen capture controller object failed, pid(%{public}d).", pid); + break; + } default: { MEDIA_LOGE("default case, media server manager failed, pid(%{public}d).", pid); break; diff --git a/services/services/sa_media/server/media_server_manager.h b/services/services/sa_media/server/media_server_manager.h index 6babca50d03a676e72ec237bebd55f30eb734980..d36b932e3bf45b7ed379575ab72cafbb1e0b4906 100644 --- a/services/services/sa_media/server/media_server_manager.h +++ b/services/services/sa_media/server/media_server_manager.h @@ -48,6 +48,7 @@ public: RECORDERPROFILES, MONITOR, SCREEN_CAPTURE, + SCREEN_CAPTURE_CONTROLLER, }; sptr CreateStubObject(StubType type); void DestroyStubObject(StubType type, sptr object); @@ -74,6 +75,7 @@ private: #endif #ifdef SUPPORT_SCREEN_CAPTURE sptr CreateScreenCaptureStubObject(); + sptr CreateScreenCaptureControllerStubObject(); #endif sptr GetMonitorStubObject(); @@ -102,6 +104,7 @@ private: std::map, pid_t> avCodecStubMap_; std::map, pid_t> recorderProfilesStubMap_; std::map, pid_t> screenCaptureStubMap_; + std::map, pid_t> screenCaptureControllerStubMap_; std::map> dumperTbl_; AsyncExecutor executor_; diff --git a/services/services/screen_capture/client/screen_capture_controller_client.cpp b/services/services/screen_capture/client/screen_capture_controller_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b1248a8013187380e94f6d353b23bdeaf3776ce8 --- /dev/null +++ b/services/services/screen_capture/client/screen_capture_controller_client.cpp @@ -0,0 +1,69 @@ +/* + * 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 "screen_capture_controller_client.h" +#include "media_log.h" +#include "media_errors.h" + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureControllerClient"}; +} + +namespace OHOS { +namespace Media { + +std::shared_ptr ScreenCaptureControllerClient::Create( + const sptr &ipcProxy) +{ + MEDIA_LOGI("ScreenCaptureControllerClient::Create() start"); + std::shared_ptr client = + std::make_shared(ipcProxy); + + CHECK_AND_RETURN_RET_LOG(client != nullptr, nullptr, "failed to new Screen Capture Controller"); + + return client; +} + +ScreenCaptureControllerClient::ScreenCaptureControllerClient(const sptr &ipcProxy) + : screenCaptureControllerProxy_(ipcProxy) +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); +} + +ScreenCaptureControllerClient::~ScreenCaptureControllerClient() +{ + std::lock_guard lock(mutex_); + if (screenCaptureControllerProxy_ != nullptr) { + (void)screenCaptureControllerProxy_->DestroyStub(); + } + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this)); +} + +void ScreenCaptureControllerClient::MediaServerDied() +{ + std::lock_guard lock(mutex_); + screenCaptureControllerProxy_ = nullptr; +} + +int32_t ScreenCaptureControllerClient::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + MEDIA_LOGI("ScreenCaptureControllerClient::ReportAVScreenCaptureUserChoice start"); + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerProxy_ != nullptr, MSERR_NO_MEMORY, "proxy does not exist."); + return screenCaptureControllerProxy_->ReportAVScreenCaptureUserChoice(sessionId, choice); +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/client/screen_capture_controller_client.h b/services/services/screen_capture/client/screen_capture_controller_client.h new file mode 100644 index 0000000000000000000000000000000000000000..01666a157609a6db134227c932d083b325e3a225 --- /dev/null +++ b/services/services/screen_capture/client/screen_capture_controller_client.h @@ -0,0 +1,41 @@ +/* + * 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 SCREEN_CAPTURE_CONTROLLER_CLIENT_H +#define SCREEN_CAPTURE_CONTROLLER_CLIENT_H + +#include "i_screen_capture_controller.h" +#include "i_standard_screen_capture_controller.h" + +namespace OHOS { +namespace Media { +class ScreenCaptureControllerClient : public IScreenCaptureController, public NoCopyable { +public: + static std::shared_ptr + Create(const sptr &ipcProxy); + explicit ScreenCaptureControllerClient(const sptr &ipcProxy); + ~ScreenCaptureControllerClient(); + + // ScreenCaptureControllerClient + void MediaServerDied(); + int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) override; + +private: + sptr screenCaptureControllerProxy_ = nullptr; + std::mutex mutex_; +}; +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_CONTROLLER_CLIENT_H \ No newline at end of file diff --git a/services/services/screen_capture/ipc/i_standard_screen_capture_controller.h b/services/services/screen_capture/ipc/i_standard_screen_capture_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..d2c4ca2e3eea7af285185db29b0ea28568b8ccc9 --- /dev/null +++ b/services/services/screen_capture/ipc/i_standard_screen_capture_controller.h @@ -0,0 +1,48 @@ +/* + * 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 I_STANDARD_SCREEN_CAPTURE_CONTROLLER_H +#define I_STANDARD_SCREEN_CAPTURE_CONTROLLER_H + +#include +#include +#include "securec.h" +#include "ipc_types.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iremote_stub.h" +#include "i_screen_capture_controller.h" + +namespace OHOS { +namespace Media { +class IStandardScreenCaptureController : public IRemoteBroker { +public: + virtual ~IStandardScreenCaptureController() = default; + virtual int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) = 0; + virtual int32_t DestroyStub() = 0; + + /** + * IPC code ID + */ + enum ScreenCaptureControllerMsg { + REPORT_USER_CHOICE, + DESTROY, + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"IStandardScreenCaptureController"); +}; +} // namespace Media +} // namespace OHOS +#endif // I_STANDARD_SCREEN_CAPTURE_CONTROLLER_H \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_controller_proxy.cpp b/services/services/screen_capture/ipc/screen_capture_controller_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ddf9644bce57d94d569db082b2a67a5f1235d97d --- /dev/null +++ b/services/services/screen_capture/ipc/screen_capture_controller_proxy.cpp @@ -0,0 +1,80 @@ +/* + * 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 "screen_capture_controller_proxy.h" +#include "media_log.h" +#include "media_errors.h" +#include "avsharedmemory_ipc.h" + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureControllerProxy"}; +} + +namespace OHOS { +namespace Media { + +ScreenCaptureControllerProxy::ScreenCaptureControllerProxy(const sptr &impl) + : IRemoteProxy(impl) +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); +} + +ScreenCaptureControllerProxy::~ScreenCaptureControllerProxy() +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this)); +} + +int32_t ScreenCaptureControllerProxy::DestroyStub() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(ScreenCaptureControllerProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + int error = Remote()->SendRequest(DESTROY, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "DestroyStub failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + +int32_t ScreenCaptureControllerProxy::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + MEDIA_LOGI("ScreenCaptureControllerProxy::ReportAVScreenCaptureUserChoice start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(ScreenCaptureControllerProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + token = data.WriteInt32(sessionId); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write sessionId!"); + + token = data.WriteString(choice); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write choice!"); + + int error = Remote()->SendRequest(REPORT_USER_CHOICE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "ReportAVScreenCaptureUserChoice failed, error: %{public}d", error); + + return reply.ReadInt32(); +} + + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_controller_proxy.h b/services/services/screen_capture/ipc/screen_capture_controller_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..1e40661aacf27cb4f4eeb8313d6e0ad83cda8043 --- /dev/null +++ b/services/services/screen_capture/ipc/screen_capture_controller_proxy.h @@ -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. + */ + +#ifndef SCREEN_CAPTURE_SERVICE_PROXY_H +#define SCREEN_CAPTURE_SERVICE_PROXY_H + +#include "i_standard_screen_capture_controller.h" + +namespace OHOS { +namespace Media { +class ScreenCaptureControllerProxy : public IRemoteProxy, public NoCopyable { +public: + explicit ScreenCaptureControllerProxy(const sptr &impl); + virtual ~ScreenCaptureControllerProxy(); + + int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) override; + int32_t DestroyStub() override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_SERVICE_PROXY_H \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_controller_stub.cpp b/services/services/screen_capture/ipc/screen_capture_controller_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..903e5a1db718e6490b95efd406cb807dd4151a5a --- /dev/null +++ b/services/services/screen_capture/ipc/screen_capture_controller_stub.cpp @@ -0,0 +1,128 @@ +/* + * 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 "screen_capture_controller_stub.h" +#include "media_server_manager.h" +#include "media_log.h" +#include "media_errors.h" +#include "avsharedmemory_ipc.h" + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureControllerStub"}; +} + +namespace OHOS { +namespace Media { + +sptr ScreenCaptureControllerStub::Create() +{ + MEDIA_LOGI("ScreenCaptureControllerStub::Create() start"); + sptr screenCaptureControllerStub = new(std::nothrow) ScreenCaptureControllerStub(); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerStub != nullptr, nullptr, + "failed to new ScreenCaptureControllerStub"); + + int32_t ret = screenCaptureControllerStub->Init(); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to screenCapture controller stub init"); + return screenCaptureControllerStub; +} + +ScreenCaptureControllerStub::ScreenCaptureControllerStub() +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); +} + +ScreenCaptureControllerStub::~ScreenCaptureControllerStub() +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this)); +} + +int32_t ScreenCaptureControllerStub::Init() +{ + MEDIA_LOGI("ScreenCaptureControllerStub::Init() start"); + screenCaptureControllerServer_ = ScreenCaptureControllerServer::Create(); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerServer_ != nullptr, MSERR_NO_MEMORY, + "failed to create screenCaptureControllerServer Service"); + screenCaptureControllerStubFuncs_[REPORT_USER_CHOICE] = + &ScreenCaptureControllerStub::ReportAVScreenCaptureUserChoice; + screenCaptureControllerStubFuncs_[DESTROY] = &ScreenCaptureControllerStub::DestroyStub; + + return MSERR_OK; +} + +int ScreenCaptureControllerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + MEDIA_LOGD("ScreenCaptureControllerStub: OnRemoteRequest of code: %{public}u is received", code); + + auto remoteDescriptor = data.ReadInterfaceToken(); + if (ScreenCaptureControllerStub::GetDescriptor() != remoteDescriptor) { + MEDIA_LOGE("Invalid descriptor"); + return MSERR_INVALID_OPERATION; + } + + auto itFunc = screenCaptureControllerStubFuncs_.find(code); + if (itFunc != screenCaptureControllerStubFuncs_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + int32_t ret = (this->*memberFunc)(data, reply); + if (ret != MSERR_OK) { + MEDIA_LOGE("Calling memberFunc is failed."); + } + return MSERR_OK; + } + } + MEDIA_LOGW("ScreenCaptureControllerStub: no member func supporting, applying default process"); + + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); +} + +int32_t ScreenCaptureControllerStub::DestroyStub() +{ + screenCaptureControllerServer_ = nullptr; + MediaServerManager::GetInstance().DestroyStubObject(MediaServerManager::SCREEN_CAPTURE_CONTROLLER, AsObject()); + return MSERR_OK; +} + +int32_t ScreenCaptureControllerStub::DestroyStub(MessageParcel &data, MessageParcel &reply) +{ + (void)data; + reply.WriteInt32(DestroyStub()); + return MSERR_OK; +} + +int32_t ScreenCaptureControllerStub::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + MEDIA_LOGI("ScreenCaptureControllerStub::ReportAVScreenCaptureUserChoice start 2"); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerServer_ != nullptr, false, + "screen capture controller server is nullptr"); + return screenCaptureControllerServer_->ReportAVScreenCaptureUserChoice(sessionId, choice); +} + +int32_t ScreenCaptureControllerStub::ReportAVScreenCaptureUserChoice(MessageParcel &data, MessageParcel &reply) +{ + MEDIA_LOGI("ScreenCaptureControllerStub::ReportAVScreenCaptureUserChoice start 1"); + CHECK_AND_RETURN_RET_LOG(screenCaptureControllerServer_ != nullptr, MSERR_INVALID_STATE, + "screen capture controller server is nullptr"); + (void)data; + int32_t sessionId = data.ReadInt32(); + std::string choice = data.ReadString(); + int32_t ret = ReportAVScreenCaptureUserChoice(sessionId, choice); + reply.WriteInt32(ret); + return MSERR_OK; +} + + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/ipc/screen_capture_controller_stub.h b/services/services/screen_capture/ipc/screen_capture_controller_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..c06dbcfbfa32590b2cb3f8a10938a015e0005ec0 --- /dev/null +++ b/services/services/screen_capture/ipc/screen_capture_controller_stub.h @@ -0,0 +1,49 @@ +/* + * 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 SCREEN_CAPTURE_CONTROLLER_STUB_H +#define SCREEN_CAPTURE_CONTROLLER_STUB_H + +#include +#include "i_standard_screen_capture_controller.h" +#include "screen_capture_controller_server.h" +#include "media_death_recipient.h" + +namespace OHOS { +namespace Media { +class ScreenCaptureControllerStub : public IRemoteStub, public NoCopyable { +public: + static sptr Create(); + virtual ~ScreenCaptureControllerStub(); + + int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) override; + int32_t DestroyStub() override; + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + ScreenCaptureControllerStub(); + int32_t Init(); + int32_t ReportAVScreenCaptureUserChoice(MessageParcel &data, MessageParcel &reply); + int32_t DestroyStub(MessageParcel &data, MessageParcel &reply); + + std::mutex mutex_; + std::shared_ptr screenCaptureControllerServer_ = nullptr; + using screenCaptureControllerStubFuncs = + int32_t(ScreenCaptureControllerStub::*)(MessageParcel &data, MessageParcel &reply); + std::map screenCaptureControllerStubFuncs_; +}; +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_CONTROLLER_STUB_H \ No newline at end of file diff --git a/services/services/screen_capture/server/screen_capture_controller_server.cpp b/services/services/screen_capture/server/screen_capture_controller_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da79c937704d250f06edcdbc7a9bb6043adb7878 --- /dev/null +++ b/services/services/screen_capture/server/screen_capture_controller_server.cpp @@ -0,0 +1,60 @@ +/* + * 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 "screen_capture_controller_server.h" +#include "media_log.h" +#include "media_errors.h" +#include "uri_helper.h" +#include "media_dfx.h" +#include "screen_capture_server.h" + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureControllerServer"}; +} + +namespace OHOS { +namespace Media { + +std::shared_ptr ScreenCaptureControllerServer::Create() +{ + MEDIA_LOGI("ScreenCaptureControllerServer::Create() start"); + std::shared_ptr controllerServerTemp = + std::make_shared(); + CHECK_AND_RETURN_RET_LOG(controllerServerTemp != nullptr, nullptr, "Failed to new ScreenCaptureControllerServer"); + + std::shared_ptr controllerServer = + std::static_pointer_cast(controllerServerTemp); + return controllerServer; +} + +ScreenCaptureControllerServer::ScreenCaptureControllerServer() +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); +} + +ScreenCaptureControllerServer::~ScreenCaptureControllerServer() +{ + MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this)); +} + +int32_t ScreenCaptureControllerServer::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + MEDIA_LOGI("ScreenCaptureControllerServer::ReportAVScreenCaptureUserChoice start"); + int32_t ret = ScreenCaptureServer::ReportAVScreenCaptureUserChoice(sessionId, choice); + return ret; +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/server/screen_capture_controller_server.h b/services/services/screen_capture/server/screen_capture_controller_server.h new file mode 100644 index 0000000000000000000000000000000000000000..bda62db6eabf2707cc17d32f3577fb7f27bb9722 --- /dev/null +++ b/services/services/screen_capture/server/screen_capture_controller_server.h @@ -0,0 +1,41 @@ +/* + * 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 SCREEN_CAPTURE_CONTROLLER_SERVER_H +#define SCREEN_CAPTURE_CONTROLLER_SERVER_H + +#include +#include +#include +#include +#include +#include +#include +#include "i_screen_capture_controller.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Media { +class ScreenCaptureControllerServer : public IScreenCaptureController, public NoCopyable { +public: + static std::shared_ptr Create(); + ScreenCaptureControllerServer(); + ~ScreenCaptureControllerServer(); + + int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) override; +}; + +} // namespace Media +} // namespace OHOS +#endif // SCREEN_CAPTURE_CONTROLLER_SERVER_H \ No newline at end of file diff --git a/services/services/screen_capture/server/screen_capture_server.cpp b/services/services/screen_capture/server/screen_capture_server.cpp index 0c5e1436091ec4f45b7beb362a094b9322d8cbef..e1a139016bd5b7e80bba1436ba2b13c6b4b887ed 100644 --- a/services/services/screen_capture/server/screen_capture_server.cpp +++ b/services/services/screen_capture/server/screen_capture_server.cpp @@ -14,6 +14,11 @@ */ #include "screen_capture_server.h" +#include "ui_extension_ability_connection.h" +#include "extension_manager_client.h" +#include "image_source.h" +#include "image_type.h" +#include "pixel_map.h" #include "media_log.h" #include "media_errors.h" #include "uri_helper.h" @@ -22,18 +27,96 @@ using OHOS::Rosen::DMError; namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ScreenCaptureServer"}; +static std::map> serverMap; +std::atomic activeSessionId(-1); +std::mutex mutex_global; } namespace OHOS { namespace Media { const int32_t ROOT_UID = 0; +static const std::string USER_CHOICE_TRUE = "true"; +static const int32_t MaxSessionId = 256; +static const auto NOTIFICATION_SUBSCRIBER = NotificationSubscriber(); + +void NotificationSubscriber::OnConnected() +{ + MEDIA_LOGI("NotificationSubscriber OnConnected"); +} + +void NotificationSubscriber::OnDisconnected() +{ + MEDIA_LOGI("NotificationSubscriber OnDisconnected"); +} + +void NotificationSubscriber::OnResponse(int32_t notificationId, + OHOS::sptr buttonOption) +{ + MEDIA_LOGI("NotificationSubscriber OnResponse notificationId : %{public}d ", notificationId); + MEDIA_LOGI("NotificationSubscriber OnResponse ButtonName : %{public}s ", (buttonOption->GetButtonName()).c_str()); + if (buttonNameStop_.compare(buttonOption->GetButtonName()) == 0) { + std::shared_ptr server = serverMap.at(notificationId); + server->StopScreenCapture(); + } +} + +void NotificationSubscriber::OnDied() +{ + MEDIA_LOGI("NotificationSubscriber OnDied"); +} + std::shared_ptr ScreenCaptureServer::Create() { - std::shared_ptr server = std::make_shared(); - CHECK_AND_RETURN_RET_LOG(server != nullptr, nullptr, "Failed to new ScreenCaptureServer"); + std::shared_ptr serverTemp = std::make_shared(); + CHECK_AND_RETURN_RET_LOG(serverTemp != nullptr, nullptr, "Failed to new ScreenCaptureServer"); + + int32_t newSessionId = 0; + for (int32_t i = 0; i < MaxSessionId; i++) { + auto it = serverMap.find(newSessionId); + if (it != serverMap.end()) { + newSessionId++; + continue; + } + serverMap.insert(std::make_pair(newSessionId, serverTemp)); + break; + } + MEDIA_LOGI("ScreenCaptureServer::Create newSessionId: %{public}d", newSessionId); + MEDIA_LOGI("ScreenCaptureServer::Create serverMap size : %{public}s", + std::to_string(serverMap.size()).c_str()); + serverTemp->SetSessionId(newSessionId); + std::shared_ptr server = + std::static_pointer_cast(serverTemp); return server; } +int32_t ScreenCaptureServer::ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice) +{ + std::lock_guard lock(mutex_global); + MEDIA_LOGI("ScreenCaptureServer::ReportAVScreenCaptureUserChoice user sessionId is : %{public}d", sessionId); + MEDIA_LOGI("ScreenCaptureServer::ReportAVScreenCaptureUserChoice user choice is : %{public}s", choice.c_str()); + std::shared_ptr server; + auto it = serverMap.find(sessionId); + if (it != serverMap.end()) { + server = it->second; + } else { + MEDIA_LOGI("ScreenCaptureServer::ReportAVScreenCaptureUserChoice Failed to get report ScreenCaptureServer"); + return MSERR_UNKNOWN; + } + + if (USER_CHOICE_TRUE.compare(choice) == 0) { + if (activeSessionId.load() >= 0) { + std::shared_ptr currentServer = serverMap.at(activeSessionId.load()); + currentServer->StopScreenCapture(); + } + server->StartScreenCaptureInner(); + activeSessionId.store(sessionId); + MEDIA_LOGI("ScreenCaptureServer::ReportAVScreenCaptureUserChoice user choice is true"); + return MSERR_OK; + } + MEDIA_LOGI("ScreenCaptureServer::ReportAVScreenCaptureUserChoice user choice is false"); + return MSERR_OK; +} + ScreenCaptureServer::ScreenCaptureServer() { MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this)); @@ -47,6 +130,11 @@ ScreenCaptureServer::~ScreenCaptureServer() ReleaseVideoCapture(); } +void ScreenCaptureServer::SetSessionId(int32_t sessionId) +{ + sessionId_ = sessionId; +} + int32_t ScreenCaptureServer::SetCaptureMode(CaptureMode captureMode) { std::lock_guard lock(mutex_); @@ -439,6 +527,24 @@ int32_t ScreenCaptureServer::StartScreenCapture() std::lock_guard lock(mutex_); MediaTrace trace("ScreenCaptureServer::StartScreenCapture"); MEDIA_LOGI("ScreenCaptureServer::StartScreenCapture start"); + + isSurfaceMode_ = false; + #ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION + StartPrivacyWindow(); + #else + StartScreenCaptureInner(); + #endif + return MSERR_OK; +} + +int32_t ScreenCaptureServer::StartScreenCaptureInner() +{ + #ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION + std::lock_guard lock(mutex_); + #endif + MediaTrace trace("ScreenCaptureServer::StartScreenCapture"); + MEDIA_LOGI("ScreenCaptureServer::StartScreenCaptureInner start"); + isAudioStart_ = true; if (audioMicCapturer_ != nullptr) { if (!audioMicCapturer_->Start()) { @@ -467,59 +573,132 @@ int32_t ScreenCaptureServer::StartScreenCapture() readInnerAudioLoop_ = std::make_unique(&ScreenCaptureServer::StartAudioInnerCapture, this); } } - isSurfaceMode_ = false; int32_t ret = StartVideoCapture(); if (ret == MSERR_OK) { BehaviorEventWriteForScreenCapture("start", "AVScreenCapture", appinfo_.appUid, appinfo_.appPid); } + #ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION + ret = StartNotification(); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_UNKNOWN, "StartNotification failed"); + #endif return ret; } +int32_t ScreenCaptureServer::StartPrivacyWindow() +{ + std::string comStr = "{\"ability.want.params.uiExtensionType\":\"sys/commonUI\",\"sessionId\":\""; + comStr += std::to_string(sessionId_).c_str(); + auto callerUid = IPCSkeleton::GetCallingUid(); + comStr += "\",\"callerUid\":\""; + comStr += std::to_string(callerUid).c_str(); + comStr += "\"}"; + + AAFwk::Want want; + want.SetElementName(bundleName_, abilityName_); + auto connection_ = sptr(new (std::nothrow) UIExtensionAbilityConnection(comStr)); + auto ret = OHOS::AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want, connection_,\ + nullptr, -1); + MEDIA_LOGI("ConnectServiceExtensionAbility end %{public}d", ret); + return MSERR_OK; +} + +int32_t ScreenCaptureServer::StartNotification() +{ + int32_t result = NotificationHelper::SubscribeLocalLiveViewNotification(NOTIFICATION_SUBSCRIBER); + + NotificationRequest request; + std::shared_ptr localLiveViewContent = GetLocalLiveViewContent(); + + std::shared_ptr content = + std::make_shared(localLiveViewContent); + + auto uid = getuid(); + request.SetSlotType(NotificationConstant::SlotType::LIVE_VIEW); + notificationId_ = sessionId_; + request.SetNotificationId(notificationId_); + request.SetContent(content); + request.SetCreatorUid(uid); + request.SetUnremovable(true); + request.SetInProgress(true); + + std::shared_ptr pixelMapTotalSpr = GetPixelMap(ICON_PATH_SCREENCAPTURE); + request.SetLittleIcon(pixelMapTotalSpr); + request.SetBadgeIconStyle(NotificationRequest::BadgeStyle::LITTLE); + + result = NotificationHelper::PublishNotification(request); + MEDIA_LOGI("Screencapture service PublishNotification uid %{public}d, result %{public}d", uid, result); + return MSERR_OK; +} + +std::shared_ptr ScreenCaptureServer::GetLocalLiveViewContent() +{ + std::shared_ptr localLiveViewContent = + std::make_shared(); + localLiveViewContent->SetType(1); + localLiveViewContent->SetTitle("系统录屏"); + localLiveViewContent->SetText("录屏中..."); + + auto capsule = NotificationCapsule(); + std::string backgroundColor = "#E84026"; + capsule.SetBackgroundColor(backgroundColor); + std::shared_ptr pixelMapCapSpr = GetPixelMap(ICON_PATH_CAPSULE); + capsule.SetIcon(pixelMapCapSpr); + + localLiveViewContent->SetCapsule(capsule); + localLiveViewContent->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::CAPSULE); + + auto testTime = NotificationTime(); + testTime.SetInitialTime(1); + testTime.SetIsCountDown(false); + testTime.SetIsPaused(false); + testTime.SetIsInTitle(true); + + localLiveViewContent->SetTime(testTime); + localLiveViewContent->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::TIME); + + auto testButton = NotificationLocalLiveViewButton(); + testButton.addSingleButtonName(buttonNameMic_); + std::shared_ptr pixelMapSpr = GetPixelMap(ICON_PATH_MIC); + testButton.addSingleButtonIcon(pixelMapSpr); + + testButton.addSingleButtonName(buttonNameStop_); + std::shared_ptr pixelMapStopSpr = GetPixelMap(ICON_PATH_STOP); + testButton.addSingleButtonIcon(pixelMapStopSpr); + + localLiveViewContent->SetButton(testButton); + localLiveViewContent->addFlag(NotificationLocalLiveViewContent::LiveViewContentInner::BUTTON); + + return localLiveViewContent; +} + +std::shared_ptr ScreenCaptureServer::GetPixelMap(std::string path) +{ + uint32_t errorCode = 0; + SourceOptions opts; + opts.formatHint = "image/png"; + std::unique_ptr imageSource = + ImageSource::CreateImageSource(path, opts, errorCode); + DecodeOptions decodeOpts; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode); + std::shared_ptr pixelMapSpr = std::move(pixelMap); + return pixelMapSpr; +} + int32_t ScreenCaptureServer::StartScreenCaptureWithSurface(sptr surface) { std::lock_guard lock(mutex_); MediaTrace trace("ScreenCaptureServer::StartScreenCaptureWithSurface"); MEDIA_LOGI("ScreenCaptureServer::StartScreenCaptureWithSurface start"); - isAudioStart_ = true; - if (audioMicCapturer_ != nullptr) { - if (!audioMicCapturer_->Start()) { - MEDIA_LOGE("Start mic audio stream failed"); - audioMicCapturer_->Release(); - audioMicCapturer_ = nullptr; - isAudioStart_ = false; - } - if (isAudioStart_) { - MEDIA_LOGE("Capturing started"); - isRunning_.store(true); - readAudioLoop_ = std::make_unique(&ScreenCaptureServer::StartAudioCapture, this); - } - } - isAudioInnerStart_ = true; - if (audioInnerCapturer_ != nullptr) { - if (!audioInnerCapturer_->Start()) { - MEDIA_LOGE("Start inner audio stream failed"); - audioInnerCapturer_->Release(); - audioInnerCapturer_ = nullptr; - isAudioInnerStart_ = false; - } - if (isAudioInnerStart_) { - MEDIA_LOGE("Capturing started"); - isInnerRunning_.store(true); - readInnerAudioLoop_ = std::make_unique(&ScreenCaptureServer::StartAudioInnerCapture, this); - } - } - if (surface == nullptr) { - MEDIA_LOGE("surface is nullptr"); - return MSERR_INVALID_OPERATION; - } surface_ = surface; isSurfaceMode_ = true; - int32_t ret = StartVideoCapture(); - if (ret == MSERR_OK) { - BehaviorEventWriteForScreenCapture("start", "AVScreenCapture", appinfo_.appUid, appinfo_.appPid); - } - return ret; + + #ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION + StartPrivacyWindow(); + #else + StartScreenCaptureInner(); + #endif + return MSERR_OK; } int32_t ScreenCaptureServer::StartVideoCapture() @@ -956,9 +1135,14 @@ int32_t ScreenCaptureServer::StopScreenCapture() int32_t retVideo = StopVideoCapture(); stopFlagSuccess = retAudio == MSERR_OK && retVideo == MSERR_OK ? MSERR_OK : MSERR_STOP_FAILED; } + activeSessionId.store(-1); if (stopFlagSuccess == MSERR_OK) { BehaviorEventWriteForScreenCapture("stop", "AVScreenCapture", appinfo_.appUid, appinfo_.appPid); } + #ifdef SUPPORT_SCREEN_CAPTURE_WINDOW_NOTIFICATION + int32_t result = NotificationHelper::CancelNotification(notificationId_); + MEDIA_LOGI("NotificationSubscriber CancelNotification result : %{public}d ", result); + #endif MEDIA_LOGI("ScreenCaptureServer stop result :%{public}d", stopFlagSuccess); return stopFlagSuccess; } @@ -1043,6 +1227,7 @@ void ScreenCaptureServer::Release() screenCaptureCb_ = nullptr; ReleaseAudioCapture(); ReleaseVideoCapture(); + serverMap.erase(sessionId_); MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances Release", FAKE_POINTER(this)); } diff --git a/services/services/screen_capture/server/screen_capture_server.h b/services/services/screen_capture/server/screen_capture_server.h index dcadb64696270230ddd97f5b9886cbfeb4c43352..d3d030ab580ae3fd128f644a0f70b9770dec718d 100644 --- a/services/services/screen_capture/server/screen_capture_server.h +++ b/services/services/screen_capture/server/screen_capture_server.h @@ -42,13 +42,29 @@ #include "screen_manager.h" #include "i_recorder_service.h" #include "recorder_server.h" +#include "notification_content.h" +#include "notification_helper.h" +#include "notification_request.h" +#include "notification_constant.h" +#include "notification_slot.h" namespace OHOS { namespace Media { using namespace Rosen; using namespace AudioStandard; +using namespace OHOS::Notification; using OHOS::Security::AccessToken::PrivacyKit; +class NotificationSubscriber : public OHOS::Notification::NotificationLocalLiveViewSubscriber { +public: + void OnConnected() override; + void OnDisconnected() override; + void OnResponse(int32_t notificationId, + OHOS::sptr buttonOption) override; + void OnDied() override; + std::string buttonNameStop_ = "stop"; +}; + struct SurfaceBufferEntry { SurfaceBufferEntry(sptr buf, int32_t fence, int64_t timeStamp, OHOS::Rect& damage) : buffer(std::move(buf)), flushFence(fence), timeStamp(timeStamp), damageRect(damage) @@ -111,6 +127,7 @@ public: class ScreenCaptureServer : public IScreenCaptureService, public NoCopyable { public: static std::shared_ptr Create(); + static int32_t ReportAVScreenCaptureUserChoice(int32_t sessionId, std::string choice); ScreenCaptureServer(); ~ScreenCaptureServer(); @@ -134,6 +151,8 @@ public: int32_t SetMicrophoneEnabled(bool isMicrophone) override; int32_t SetScreenCanvasRotation(bool canvasRotation) override; void Release() override; + int32_t StartScreenCaptureInner(); + void SetSessionId(int32_t sessionId); private: bool CheckAudioCaptureMicPermission(); @@ -146,9 +165,7 @@ private: int32_t StartAudioCapture(); int32_t StartAudioInnerCapture(); int32_t StartVideoCapture(); - int32_t StartVideoCaptureWithSurface(sptr surface); int32_t StartHomeVideoCapture(); - int32_t StartHomeVideoCaptureWithSurface(sptr surface); int32_t StartHomeVideoCaptureFile(); int32_t CreateVirtualScreen(const std::string &name, sptr consumer); VirtualScreenOption InitVirtualScreenOption(const std::string &name, sptr consumer); @@ -158,6 +175,10 @@ private: int32_t StopScreenCaptureRecorder(); void ReleaseAudioCapture(); void ReleaseVideoCapture(); + int32_t StartPrivacyWindow(); + int32_t StartNotification(); + std::shared_ptr GetLocalLiveViewContent(); + std::shared_ptr GetPixelMap(std::string path); std::shared_ptr screenCaptureCb_ = nullptr; std::mutex mutex_; @@ -203,17 +224,27 @@ private: const int32_t audioBitrateMin_ = 8000; const int32_t audioBitrateMax_ = 384000; const int32_t videoBitrateMin_ = 1; - const int32_t videoBitrateMax_ = 3000000; + const int32_t videoBitrateMax_ = 30000000; const int32_t videoFrameRateMin_ = 1; - const int32_t videoFrameRateMax_ = 30; + const int32_t videoFrameRateMax_ = 60; const std::string MP4 = "mp4"; const std::string M4A = "m4a"; OHOS::AudioStandard::AppInfo appinfo_; sptr surface_ = nullptr; bool isSurfaceMode_ = false; + int32_t sessionId_; + int32_t notificationId_; + std::string buttonNameMic_ = "mic"; + std::string buttonNameStop_ = "stop"; + std::string ICON_PATH_CAPSULE = "/etc/window/resources/capsule.png"; + std::string ICON_PATH_MIC = "/etc/window/resources/mic.png"; + std::string ICON_PATH_STOP = "/etc/window/resources/stop.png"; + std::string ICON_PATH_SCREENCAPTURE = "/etc/window/resources/screencapture.png"; static constexpr uint32_t MAX_AUDIO_BUFFER_SIZE = 128; static constexpr uint64_t SEC_TO_NANOSECOND = 1000000000; + std::string bundleName_ = "com.ohos.systemui"; + std::string abilityName_ = "com.ohos.systemui.dialog"; }; } // namespace Media } // namespace OHOS diff --git a/services/services/screen_capture/server/ui_extension_ability_connection.cpp b/services/services/screen_capture/server/ui_extension_ability_connection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c08c30ef7c8e4c0b13c03c786fce9d0472fb1613 --- /dev/null +++ b/services/services/screen_capture/server/ui_extension_ability_connection.cpp @@ -0,0 +1,53 @@ +/* + * 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 "ui_extension_ability_connection.h" +#include "ability_connect_callback_interface.h" +#include "ability_manager_client.h" +#include "media_log.h" + +constexpr int32_t SIGNAL_NUM = 3; + +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "UIExtensionAbilityConnection"}; +} + +namespace OHOS { +namespace Media { + +void UIExtensionAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element, + const sptr &remoteObject, int32_t resultCode) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteInt32(SIGNAL_NUM); + data.WriteString16(u"bundleName"); + data.WriteString16(u"com.ohos.screenshot"); + data.WriteString16(u"abilityName"); + data.WriteString16(u"com.ohos.screenshot.DialogAbility"); + data.WriteString16(u"parameters"); + data.WriteString16(Str8ToStr16(commandStr_)); + MEDIA_LOGE("UIExtensionAbilityConnection::OnAbilityConnectDone start "); + remoteObject->SendRequest(IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option); + MEDIA_LOGE("UIExtensionAbilityConnection::OnAbilityConnectDone end "); +} + +void UIExtensionAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, + int32_t resultCode) +{ + MEDIA_LOGE("UIExtensionAbilityConnection::OnAbilityDisconnectDone start "); +} +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/services/services/screen_capture/server/ui_extension_ability_connection.h b/services/services/screen_capture/server/ui_extension_ability_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..d9092353ab4a8a450380d17bfd4c496b71762eec --- /dev/null +++ b/services/services/screen_capture/server/ui_extension_ability_connection.h @@ -0,0 +1,47 @@ +/* + * 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 UI_EXTENSION_ABILITY_CONNECTION_H +#define UI_EXTENSION_ABILITY_CONNECTION_H + +#include "ability_connection.h" +#include "ability_connect_callback_interface.h" +#include "ability_connect_callback_stub.h" +#include "iremote_object.h" +#include "iremote_proxy.h" +#include "message_parcel.h" +#include "nocopyable.h" + + +namespace OHOS { +namespace Media { +class UIExtensionAbilityConnection : public AAFwk::AbilityConnectionStub { +public: + explicit UIExtensionAbilityConnection(const std::string commandStr) + { + commandStr_ = commandStr; + } + + virtual ~UIExtensionAbilityConnection() = default; + + void OnAbilityConnectDone(const AppExecFwk::ElementName &element, + const sptr &remoteObject, int32_t resultCode) override; + void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int32_t resultCode) override; + +private: + std::string commandStr_; +}; +} // namespace Media +} // namespace OHOS +#endif // UI_EXTENSION_ABILITY_CONNECTION_H \ No newline at end of file