blob: 3738d172ee285229b07446df60ad9f691b181f19 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/media_router/browser/presentation/local_presentation_manager.h"
#include <utility>
#include "base/containers/contains.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "url/gurl.h"
using blink::mojom::PresentationConnectionResult;
using blink::mojom::PresentationInfo;
namespace media_router {
// LocalPresentationManager implementation.
LocalPresentationManager::LocalPresentationManager() = default;
LocalPresentationManager::~LocalPresentationManager() = default;
LocalPresentationManager::LocalPresentation*
LocalPresentationManager::GetOrCreateLocalPresentation(
const PresentationInfo& presentation_info) {
auto it = local_presentations_.find(presentation_info.id);
if (it == local_presentations_.end()) {
it = local_presentations_
.insert(std::make_pair(
presentation_info.id,
std::make_unique<LocalPresentation>(presentation_info)))
.first;
}
return it->second.get();
}
void LocalPresentationManager::RegisterLocalPresentationController(
const PresentationInfo& presentation_info,
const content::GlobalRenderFrameHostId& render_frame_host_id,
mojo::PendingRemote<blink::mojom::PresentationConnection>
controller_connection_remote,
mojo::PendingReceiver<blink::mojom::PresentationConnection>
receiver_connection_receiver,
const MediaRoute& route) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto* presentation = GetOrCreateLocalPresentation(presentation_info);
presentation->RegisterController(
render_frame_host_id, std::move(controller_connection_remote),
std::move(receiver_connection_receiver), route);
}
void LocalPresentationManager::UnregisterLocalPresentationController(
const std::string& presentation_id,
const content::GlobalRenderFrameHostId& render_frame_host_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = local_presentations_.find(presentation_id);
if (it == local_presentations_.end()) {
return;
}
// Remove presentation if no controller and receiver.
it->second->UnregisterController(render_frame_host_id);
if (!it->second->IsValid()) {
local_presentations_.erase(presentation_id);
}
}
void LocalPresentationManager::OnLocalPresentationReceiverCreated(
const PresentationInfo& presentation_info,
const content::ReceiverConnectionAvailableCallback& receiver_callback,
content::WebContents* receiver_web_contents) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto* presentation = GetOrCreateLocalPresentation(presentation_info);
presentation->RegisterReceiver(receiver_callback, receiver_web_contents);
}
void LocalPresentationManager::OnLocalPresentationReceiverTerminated(
const std::string& presentation_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
local_presentations_.erase(presentation_id);
}
bool LocalPresentationManager::IsLocalPresentation(
const std::string& presentation_id) {
return base::Contains(local_presentations_, presentation_id);
}
bool LocalPresentationManager::IsLocalPresentation(
content::WebContents* web_contents) {
for (auto& local_presentation : local_presentations_) {
if (local_presentation.second->receiver_web_contents_ == web_contents) {
return true;
}
}
return false;
}
const MediaRoute* LocalPresentationManager::GetRoute(
const std::string& presentation_id) {
auto it = local_presentations_.find(presentation_id);
return (it != local_presentations_.end() && it->second->route_.has_value())
? &(it->second->route_.value())
: nullptr;
}
// LocalPresentation implementation.
LocalPresentationManager::LocalPresentation::LocalPresentation(
const PresentationInfo& presentation_info)
: presentation_info_(presentation_info) {}
LocalPresentationManager::LocalPresentation::~LocalPresentation() = default;
void LocalPresentationManager::LocalPresentation::RegisterController(
const content::GlobalRenderFrameHostId& render_frame_host_id,
mojo::PendingRemote<blink::mojom::PresentationConnection>
controller_connection_remote,
mojo::PendingReceiver<blink::mojom::PresentationConnection>
receiver_connection_receiver,
const MediaRoute& route) {
if (!receiver_callback_.is_null()) {
receiver_callback_.Run(PresentationConnectionResult::New(
PresentationInfo::New(presentation_info_),
std::move(controller_connection_remote),
std::move(receiver_connection_receiver)));
} else {
pending_controllers_.insert(std::make_pair(
render_frame_host_id, std::make_unique<ControllerConnection>(
std::move(controller_connection_remote),
std::move(receiver_connection_receiver))));
}
route_ = route;
}
void LocalPresentationManager::LocalPresentation::UnregisterController(
const content::GlobalRenderFrameHostId& render_frame_host_id) {
pending_controllers_.erase(render_frame_host_id);
}
void LocalPresentationManager::LocalPresentation::RegisterReceiver(
const content::ReceiverConnectionAvailableCallback& receiver_callback,
content::WebContents* receiver_web_contents) {
DCHECK(receiver_callback_.is_null());
DCHECK(receiver_web_contents);
for (auto& controller : pending_controllers_) {
receiver_callback.Run(PresentationConnectionResult::New(
PresentationInfo::New(presentation_info_),
std::move(controller.second->controller_connection_remote),
std::move(controller.second->receiver_connection_receiver)));
}
receiver_callback_ = receiver_callback;
receiver_web_contents_ = receiver_web_contents;
pending_controllers_.clear();
}
bool LocalPresentationManager::LocalPresentation::IsValid() const {
return !(pending_controllers_.empty() && receiver_callback_.is_null());
}
LocalPresentationManager::LocalPresentation::ControllerConnection::
ControllerConnection(
mojo::PendingRemote<blink::mojom::PresentationConnection>
controller_connection_remote,
mojo::PendingReceiver<blink::mojom::PresentationConnection>
receiver_connection_receiver)
: controller_connection_remote(std::move(controller_connection_remote)),
receiver_connection_receiver(std::move(receiver_connection_receiver)) {}
LocalPresentationManager::LocalPresentation::ControllerConnection::
~ControllerConnection() = default;
} // namespace media_router