blob: 0de4bae9e29da5ddef353d6babe52266888ad7d0 [file] [log] [blame]
// Copyright 2014 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 "media/mojo/services/media_service.h"
#include <utility>
#include "base/memory/ptr_util.h"
#include "media/base/media_log.h"
#include "media/media_features.h"
#include "media/mojo/services/interface_factory_impl.h"
#include "media/mojo/services/mojo_media_client.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_module.h"
#if defined(OS_MACOSX)
#include "sandbox/mac/seatbelt_extension.h"
#endif // defined(OS_MACOSX)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
namespace media {
MediaService::MediaService(std::unique_ptr<MojoMediaClient> mojo_media_client)
: mojo_media_client_(std::move(mojo_media_client)) {
DCHECK(mojo_media_client_);
registry_.AddInterface<mojom::MediaService>(
base::Bind(&MediaService::Create, base::Unretained(this)));
}
MediaService::~MediaService() {}
void MediaService::OnStart() {
DVLOG(1) << __func__;
ref_factory_.reset(new service_manager::ServiceContextRefFactory(
base::Bind(&service_manager::ServiceContext::RequestQuit,
base::Unretained(context()))));
mojo_media_client_->Initialize(context()->connector(), ref_factory_.get());
}
void MediaService::OnBindInterface(
const service_manager::BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
DVLOG(1) << __func__ << ": interface_name = " << interface_name;
registry_.BindInterface(interface_name, std::move(interface_pipe));
}
bool MediaService::OnServiceManagerConnectionLost() {
interface_factory_bindings_.CloseAllBindings();
mojo_media_client_.reset();
return true;
}
void MediaService::Create(mojom::MediaServiceRequest request) {
bindings_.AddBinding(this, std::move(request));
}
#if defined(OS_MACOSX)
void MediaService::LoadCdm(
const base::FilePath& cdm_path,
mojom::SeatbeltExtensionTokenProviderPtr token_provider) {
#else
void MediaService::LoadCdm(const base::FilePath& cdm_path) {
#endif // defined(OS_MACOSX)
DVLOG(1) << __func__ << ": cdm_path = " << cdm_path.value();
// Ignore request if service has already stopped.
if (!mojo_media_client_)
return;
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
CdmModule* instance = CdmModule::GetInstance();
if (instance->was_initialize_called()) {
DCHECK_EQ(cdm_path, instance->GetCdmPath());
return;
}
#if defined(OS_MACOSX)
std::vector<sandbox::SeatbeltExtensionToken> tokens;
CHECK(token_provider->GetTokens(&tokens));
std::vector<std::unique_ptr<sandbox::SeatbeltExtension>> extensions;
for (auto&& token : tokens) {
DVLOG(3) << "token: " << token.token();
auto extension = sandbox::SeatbeltExtension::FromToken(std::move(token));
if (!extension->Consume()) {
DVLOG(1) << "Failed to comsume sandbox seatbelt extension. This could "
"happen if --no-sandbox is specified.";
}
extensions.push_back(std::move(extension));
}
#endif // defined(OS_MACOSX)
#if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
std::vector<CdmHostFilePath> cdm_host_file_paths;
mojo_media_client_->AddCdmHostFilePaths(&cdm_host_file_paths);
if (!instance->Initialize(cdm_path, cdm_host_file_paths))
return;
#else
if (!instance->Initialize(cdm_path))
return;
#endif // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
// This may trigger the sandbox to be sealed.
mojo_media_client_->EnsureSandboxed();
#if defined(OS_MACOSX)
for (auto&& extension : extensions)
extension->Revoke();
#endif // defined(OS_MACOSX)
// Always called within the sandbox.
instance->InitializeCdmModule();
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
}
void MediaService::CreateInterfaceFactory(
mojom::InterfaceFactoryRequest request,
service_manager::mojom::InterfaceProviderPtr host_interfaces) {
// Ignore request if service has already stopped.
if (!mojo_media_client_)
return;
interface_factory_bindings_.AddBinding(
base::MakeUnique<InterfaceFactoryImpl>(
std::move(host_interfaces), &media_log_, ref_factory_->CreateRef(),
mojo_media_client_.get()),
std::move(request));
}
} // namespace media