diff options
Diffstat (limited to 'libcef/browser/media_stream_registrar.cc')
-rw-r--r-- | libcef/browser/media_stream_registrar.cc | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/libcef/browser/media_stream_registrar.cc b/libcef/browser/media_stream_registrar.cc new file mode 100644 index 00000000..bdf3dd92 --- /dev/null +++ b/libcef/browser/media_stream_registrar.cc @@ -0,0 +1,110 @@ +// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/media_stream_registrar.h" + +#include "libcef/browser/browser_host_base.h" +#include "libcef/browser/thread_util.h" + +class CefMediaStreamUI : public content::MediaStreamUI { + public: + CefMediaStreamUI(base::WeakPtr<CefMediaStreamRegistrar> registrar, + bool has_video, + bool has_audio) + : registrar_(registrar), has_video_(has_video), has_audio_(has_audio) {} + + ~CefMediaStreamUI() override { + if (registrar_) { + registrar_->UnregisterMediaStream(label_); + } + } + + CefMediaStreamUI(const CefMediaStreamUI&) = delete; + CefMediaStreamUI& operator=(const CefMediaStreamUI&) = delete; + + gfx::NativeViewId OnStarted( + base::RepeatingClosure stop, + SourceCallback source, + const std::string& label, + std::vector<content::DesktopMediaID> screen_capture_ids, + StateChangeCallback state_change) override { + if (registrar_) { + label_ = label; + registrar_->RegisterMediaStream(label, has_video_, has_audio_); + } + return 0; + } + + void OnDeviceStoppedForSourceChange( + const std::string& label, + const content::DesktopMediaID& old_media_id, + const content::DesktopMediaID& new_media_id) override {} + + void OnDeviceStopped(const std::string& label, + const content::DesktopMediaID& media_id) override {} + + private: + base::WeakPtr<CefMediaStreamRegistrar> registrar_; + const bool has_video_; + const bool has_audio_; + std::string label_; +}; + +CefMediaStreamRegistrar::CefMediaStreamRegistrar(CefBrowserHostBase* browser) + : browser_(browser) {} + +std::unique_ptr<content::MediaStreamUI> +CefMediaStreamRegistrar::MaybeCreateMediaStreamUI(bool has_video, + bool has_audio) { + // Only create the object if the callback will be executed. + if (auto client = browser_->GetClient()) { + if (auto handler = client->GetDisplayHandler()) { + return std::make_unique<CefMediaStreamUI>(weak_ptr_factory_.GetWeakPtr(), + has_video, has_audio); + } + } + return nullptr; +} + +void CefMediaStreamRegistrar::RegisterMediaStream(const std::string& label, + bool video, + bool audio) { + CEF_REQUIRE_UIT(); + MediaStreamInfo info = {video, audio}; + registered_streams_.insert(std::make_pair(label, info)); + NotifyMediaStreamChange(); +} + +void CefMediaStreamRegistrar::UnregisterMediaStream(const std::string& label) { + CEF_REQUIRE_UIT(); + registered_streams_.erase(label); + NotifyMediaStreamChange(); +} + +void CefMediaStreamRegistrar::NotifyMediaStreamChange() { + bool video = false; + bool audio = false; + for (const auto& media_stream : registered_streams_) { + const auto& info = media_stream.second; + if (!video) { + video = info.video; + } + if (!audio) { + audio = info.audio; + } + } + + if (audio == last_notified_info_.audio && + video == last_notified_info_.video) { + return; + } + + last_notified_info_ = {video, audio}; + + if (auto client = browser_->GetClient()) { + if (auto handler = client->GetDisplayHandler()) { + handler->OnMediaAccessChange(browser_, video, audio); + } + } +} |