blob: fbb3b101866e99f0c841eaa8e93b61f9a15fd9e3 [file] [log] [blame]
// Copyright 2016 The Chromium 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 "content/browser/media/session/media_session_service_impl.h"
#include "content/browser/media/session/media_metadata_sanitizer.h"
#include "content/browser/media/session/media_session_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
namespace content {
MediaSessionServiceImpl::MediaSessionServiceImpl(
RenderFrameHost* render_frame_host)
: render_frame_process_id_(render_frame_host->GetProcess()->GetID()),
render_frame_routing_id_(render_frame_host->GetRoutingID()),
playback_state_(blink::mojom::MediaSessionPlaybackState::NONE) {
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnServiceCreated(this);
}
MediaSessionServiceImpl::~MediaSessionServiceImpl() {
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnServiceDestroyed(this);
}
// static
void MediaSessionServiceImpl::Create(
RenderFrameHost* render_frame_host,
blink::mojom::MediaSessionServiceRequest request) {
MediaSessionServiceImpl* impl =
new MediaSessionServiceImpl(render_frame_host);
impl->Bind(std::move(request));
}
RenderFrameHost* MediaSessionServiceImpl::GetRenderFrameHost() {
return RenderFrameHost::FromID(render_frame_process_id_,
render_frame_routing_id_);
}
void MediaSessionServiceImpl::DidFinishNavigation() {
// At this point the BrowsingContext of the frame has changed, so the members
// need to be reset, and notify MediaSessionImpl.
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE);
SetMetadata(base::nullopt);
ClearActions();
}
void MediaSessionServiceImpl::FlushForTesting() {
client_.FlushForTesting();
}
void MediaSessionServiceImpl::SetClient(
blink::mojom::MediaSessionClientPtr client) {
client_ = std::move(client);
}
void MediaSessionServiceImpl::SetPlaybackState(
blink::mojom::MediaSessionPlaybackState state) {
playback_state_ = state;
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionPlaybackStateChanged(this);
}
void MediaSessionServiceImpl::SetMetadata(
const base::Optional<media_session::MediaMetadata>& metadata) {
// When receiving a MediaMetadata, the browser process can't trust that it is
// coming from a known and secure source. It must be processed accordingly.
if (metadata.has_value() &&
!MediaMetadataSanitizer::CheckSanity(metadata.value())) {
RenderFrameHost* rfh = GetRenderFrameHost();
if (rfh) {
rfh->GetProcess()->ShutdownForBadMessage(
RenderProcessHost::CrashReportMode::GENERATE_CRASH_DUMP);
}
return;
}
metadata_ = metadata;
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionMetadataChanged(this);
}
void MediaSessionServiceImpl::EnableAction(
media_session::mojom::MediaSessionAction action) {
actions_.insert(action);
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionActionsChanged(this);
}
void MediaSessionServiceImpl::DisableAction(
media_session::mojom::MediaSessionAction action) {
actions_.erase(action);
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionActionsChanged(this);
}
void MediaSessionServiceImpl::ClearActions() {
actions_.clear();
MediaSessionImpl* session = GetMediaSession();
if (session)
session->OnMediaSessionActionsChanged(this);
}
MediaSessionImpl* MediaSessionServiceImpl::GetMediaSession() {
RenderFrameHost* rfh = GetRenderFrameHost();
if (!rfh)
return nullptr;
WebContentsImpl* contents =
static_cast<WebContentsImpl*>(WebContentsImpl::FromRenderFrameHost(rfh));
if (!contents)
return nullptr;
return MediaSessionImpl::Get(contents);
}
void MediaSessionServiceImpl::Bind(
blink::mojom::MediaSessionServiceRequest request) {
binding_.reset(new mojo::Binding<blink::mojom::MediaSessionService>(
this, std::move(request)));
}
} // namespace content