mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add CefRegisterWidevineCdm function and remove component updater support (issue #2009)
Mac: Check in widevinecdmadapter.plugin binary until Widevine GN build errors are resolved (https://crbug.com/626436).
This commit is contained in:
@@ -7,33 +7,13 @@
|
||||
|
||||
#include "libcef/browser/browser_context_impl.h"
|
||||
#include "libcef/browser/chrome_profile_manager_stub.h"
|
||||
#include "libcef/browser/component_updater/cef_component_updater_configurator.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
|
||||
#include "chrome/browser/printing/print_job_manager.h"
|
||||
#include "components/component_updater/component_updater_service.h"
|
||||
#include "components/update_client/configurator.h"
|
||||
#include "ui/message_center/message_center.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void RegisterComponentsForUpdate(
|
||||
component_updater::ComponentUpdateService* cus) {
|
||||
base::ThreadRestrictions::ScopedAllowIO scoped_allow_io;
|
||||
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableWidevineCdm)) {
|
||||
RegisterWidevineCdmComponent(cus);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChromeBrowserProcessStub::ChromeBrowserProcessStub()
|
||||
: initialized_(false),
|
||||
shutdown_(false),
|
||||
@@ -57,19 +37,6 @@ void ChromeBrowserProcessStub::Initialize() {
|
||||
profile_manager_.reset(new ChromeProfileManagerStub());
|
||||
event_router_forwarder_ = new extensions::EventRouterForwarder();
|
||||
|
||||
// Creating the component updater does not do anything initially. Components
|
||||
// need to be registered and Start() needs to be called.
|
||||
scoped_refptr<CefBrowserContextImpl> browser_context =
|
||||
CefContentBrowserClient::Get()->browser_context();
|
||||
scoped_refptr<update_client::Configurator> configurator =
|
||||
component_updater::MakeCefComponentUpdaterConfigurator(
|
||||
base::CommandLine::ForCurrentProcess(),
|
||||
browser_context->request_context().get(),
|
||||
browser_context->GetPrefs());
|
||||
component_updater_.reset(component_updater::ComponentUpdateServiceFactory(
|
||||
configurator).release());
|
||||
RegisterComponentsForUpdate(component_updater_.get());
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
@@ -86,7 +53,6 @@ void ChromeBrowserProcessStub::Shutdown() {
|
||||
|
||||
profile_manager_.reset();
|
||||
event_router_forwarder_ = nullptr;
|
||||
component_updater_.reset();
|
||||
|
||||
shutdown_ = true;
|
||||
}
|
||||
@@ -299,7 +265,8 @@ net_log::ChromeNetLog* ChromeBrowserProcessStub::net_log() {
|
||||
|
||||
component_updater::ComponentUpdateService*
|
||||
ChromeBrowserProcessStub::component_updater() {
|
||||
return component_updater_.get();
|
||||
NOTIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CRLSetFetcher* ChromeBrowserProcessStub::crl_set_fetcher() {
|
||||
|
@@ -17,10 +17,6 @@
|
||||
#include "chrome/browser/profiles/incognito_helpers.h"
|
||||
#include "base/compiler_specific.h"
|
||||
|
||||
namespace component_updater {
|
||||
class ComponentUpdateService;
|
||||
}
|
||||
|
||||
class ChromeProfileManagerStub;
|
||||
|
||||
class BackgroundModeManager {
|
||||
@@ -126,7 +122,6 @@ class ChromeBrowserProcessStub : public BrowserProcess,
|
||||
std::unique_ptr<printing::PrintJobManager> print_job_manager_;
|
||||
std::unique_ptr<ChromeProfileManagerStub> profile_manager_;
|
||||
scoped_refptr<extensions::EventRouterForwarder> event_router_forwarder_;
|
||||
std::unique_ptr<component_updater::ComponentUpdateService> component_updater_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProcessStub);
|
||||
};
|
||||
|
@@ -1,182 +0,0 @@
|
||||
// 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 "libcef/browser/component_updater/cef_component_updater_configurator.h"
|
||||
#include "include/cef_version.h"
|
||||
|
||||
#include "base/version.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/component_updater/configurator_impl.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/update_client/component_patcher_operation.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
namespace component_updater {
|
||||
|
||||
namespace {
|
||||
|
||||
class CefConfigurator : public update_client::Configurator {
|
||||
public:
|
||||
CefConfigurator(const base::CommandLine* cmdline,
|
||||
net::URLRequestContextGetter* url_request_getter,
|
||||
PrefService* pref_service);
|
||||
|
||||
int InitialDelay() const override;
|
||||
int NextCheckDelay() const override;
|
||||
int StepDelay() const override;
|
||||
int OnDemandDelay() const override;
|
||||
int UpdateDelay() const override;
|
||||
std::vector<GURL> UpdateUrl() const override;
|
||||
std::vector<GURL> PingUrl() const override;
|
||||
base::Version GetBrowserVersion() const override;
|
||||
std::string GetChannel() const override;
|
||||
std::string GetBrand() const override;
|
||||
std::string GetLang() const override;
|
||||
std::string GetOSLongName() const override;
|
||||
std::string ExtraRequestParams() const override;
|
||||
std::string GetDownloadPreference() const override;
|
||||
net::URLRequestContextGetter* RequestContext() const override;
|
||||
scoped_refptr<update_client::OutOfProcessPatcher>
|
||||
CreateOutOfProcessPatcher() const override;
|
||||
bool EnabledDeltas() const override;
|
||||
bool EnabledComponentUpdates() const override;
|
||||
bool EnabledBackgroundDownloader() const override;
|
||||
bool EnabledCupSigning() const override;
|
||||
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
|
||||
const override;
|
||||
PrefService* GetPrefService() const override;
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<CefConfigurator>;
|
||||
|
||||
~CefConfigurator() override {}
|
||||
|
||||
ConfiguratorImpl configurator_impl_;
|
||||
PrefService* pref_service_;
|
||||
};
|
||||
|
||||
CefConfigurator::CefConfigurator(
|
||||
const base::CommandLine* cmdline,
|
||||
net::URLRequestContextGetter* url_request_getter,
|
||||
PrefService* pref_service)
|
||||
: configurator_impl_(cmdline, url_request_getter, false),
|
||||
pref_service_(pref_service) {
|
||||
DCHECK(pref_service_);
|
||||
}
|
||||
|
||||
int CefConfigurator::InitialDelay() const {
|
||||
return configurator_impl_.InitialDelay();
|
||||
}
|
||||
|
||||
int CefConfigurator::NextCheckDelay() const {
|
||||
return configurator_impl_.NextCheckDelay();
|
||||
}
|
||||
|
||||
int CefConfigurator::StepDelay() const {
|
||||
return configurator_impl_.StepDelay();
|
||||
}
|
||||
|
||||
int CefConfigurator::OnDemandDelay() const {
|
||||
return configurator_impl_.OnDemandDelay();
|
||||
}
|
||||
|
||||
int CefConfigurator::UpdateDelay() const {
|
||||
return configurator_impl_.UpdateDelay();
|
||||
}
|
||||
|
||||
std::vector<GURL> CefConfigurator::UpdateUrl() const {
|
||||
return configurator_impl_.UpdateUrl();
|
||||
}
|
||||
|
||||
std::vector<GURL> CefConfigurator::PingUrl() const {
|
||||
return configurator_impl_.PingUrl();
|
||||
}
|
||||
|
||||
base::Version CefConfigurator::GetBrowserVersion() const {
|
||||
return configurator_impl_.GetBrowserVersion();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::GetChannel() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::GetBrand() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::GetLang() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::GetOSLongName() const {
|
||||
return configurator_impl_.GetOSLongName();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::ExtraRequestParams() const {
|
||||
return configurator_impl_.ExtraRequestParams();
|
||||
}
|
||||
|
||||
std::string CefConfigurator::GetDownloadPreference() const {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
net::URLRequestContextGetter* CefConfigurator::RequestContext() const {
|
||||
return configurator_impl_.RequestContext();
|
||||
}
|
||||
|
||||
scoped_refptr<update_client::OutOfProcessPatcher>
|
||||
CefConfigurator::CreateOutOfProcessPatcher() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CefConfigurator::EnabledDeltas() const {
|
||||
return configurator_impl_.EnabledDeltas();
|
||||
}
|
||||
|
||||
bool CefConfigurator::EnabledComponentUpdates() const {
|
||||
return pref_service_->GetBoolean(prefs::kComponentUpdatesEnabled);
|
||||
}
|
||||
|
||||
bool CefConfigurator::EnabledBackgroundDownloader() const {
|
||||
return configurator_impl_.EnabledBackgroundDownloader();
|
||||
}
|
||||
|
||||
bool CefConfigurator::EnabledCupSigning() const {
|
||||
return configurator_impl_.EnabledCupSigning();
|
||||
}
|
||||
|
||||
// Returns a task runner to run blocking tasks. The task runner continues to run
|
||||
// after the browser shuts down, until the OS terminates the process. This
|
||||
// imposes certain requirements for the code using the task runner, such as
|
||||
// not accessing any global browser state while the code is running.
|
||||
scoped_refptr<base::SequencedTaskRunner>
|
||||
CefConfigurator::GetSequencedTaskRunner() const {
|
||||
return content::BrowserThread::GetBlockingPool()
|
||||
->GetSequencedTaskRunnerWithShutdownBehavior(
|
||||
base::SequencedWorkerPool::GetSequenceToken(),
|
||||
base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
|
||||
}
|
||||
|
||||
PrefService* CefConfigurator::GetPrefService() const {
|
||||
return pref_service_;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterPrefsForCefComponentUpdaterConfigurator(
|
||||
PrefRegistrySimple* registry) {
|
||||
// The component updates are enabled by default, if the preference is not set.
|
||||
registry->RegisterBooleanPref(prefs::kComponentUpdatesEnabled, true);
|
||||
}
|
||||
|
||||
scoped_refptr<update_client::Configurator>
|
||||
MakeCefComponentUpdaterConfigurator(
|
||||
const base::CommandLine* cmdline,
|
||||
net::URLRequestContextGetter* context_getter,
|
||||
PrefService* pref_service) {
|
||||
return new CefConfigurator(cmdline, context_getter, pref_service);
|
||||
}
|
||||
|
||||
} // namespace component_updater
|
@@ -1,39 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef LIBCEF_BROWSER_COMPONENT_UPDATER_CEF_COMPONENT_UPDATER_CONFIGURATOR_H_
|
||||
#define LIBCEF_BROWSER_COMPONENT_UPDATER_CEF_COMPONENT_UPDATER_CONFIGURATOR_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "components/update_client/configurator.h"
|
||||
|
||||
namespace base {
|
||||
class CommandLine;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class URLRequestContextGetter;
|
||||
}
|
||||
|
||||
class PrefRegistrySimple;
|
||||
class PrefService;
|
||||
|
||||
namespace component_updater {
|
||||
|
||||
// Registers preferences associated with the component updater configurator
|
||||
// for CEF. The preferences must be registered with the local pref store
|
||||
// before they can be queried by the configurator instance.
|
||||
// This function is called before MakeCefComponentUpdaterConfigurator.
|
||||
void RegisterPrefsForCefComponentUpdaterConfigurator(
|
||||
PrefRegistrySimple* registry);
|
||||
|
||||
scoped_refptr<update_client::Configurator>
|
||||
MakeCefComponentUpdaterConfigurator(
|
||||
const base::CommandLine* cmdline,
|
||||
net::URLRequestContextGetter* context_getter,
|
||||
PrefService* pref_service);
|
||||
|
||||
} // namespace component_updater
|
||||
|
||||
#endif // LIBCEF_BROWSER_COMPONENT_UPDATER_CEF_COMPONENT_UPDATER_CONFIGURATOR_H_
|
@@ -75,6 +75,10 @@
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include "libcef/common/widevine_loader.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "components/spellcheck/browser/spellcheck_message_filter_platform.h"
|
||||
#endif
|
||||
@@ -574,8 +578,6 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
|
||||
switches::kPpapiFlashPath,
|
||||
switches::kPpapiFlashVersion,
|
||||
switches::kUncaughtExceptionStackSize,
|
||||
switches::kWidevineCdmPath,
|
||||
switches::kWidevineCdmVersion,
|
||||
};
|
||||
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
|
||||
arraysize(kSwitchNames));
|
||||
@@ -597,17 +599,25 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
if (process_type == switches::kZygoteProcess) {
|
||||
// Propagate the following switches to the zygone command line (along with
|
||||
// Propagate the following switches to the zygote command line (along with
|
||||
// any associated values) if present in the browser command line.
|
||||
static const char* const kSwitchNames[] = {
|
||||
switches::kPpapiFlashPath,
|
||||
switches::kPpapiFlashVersion,
|
||||
switches::kWidevineCdmPath,
|
||||
switches::kWidevineCdmVersion,
|
||||
};
|
||||
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
|
||||
arraysize(kSwitchNames));
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
if (!browser_cmd->HasSwitch(switches::kNoSandbox)) {
|
||||
// Pass the Widevine CDM path to the Zygote process. See comments in
|
||||
// CefWidevineLoader::AddPepperPlugins.
|
||||
const base::FilePath& cdm_path = CefWidevineLoader::GetInstance()->path();
|
||||
if (!cdm_path.empty())
|
||||
command_line->AppendSwitchPath(switches::kWidevineCdmPath, cdm_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (browser_cmd->HasSwitch(switches::kBrowserSubprocessPath)) {
|
||||
// Force use of the sub-process executable path for the zygote process.
|
||||
const base::FilePath& subprocess_path =
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "libcef/browser/trace_subscriber.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
#include "libcef/common/main_delegate.h"
|
||||
#include "libcef/common/widevine_loader.h"
|
||||
#include "libcef/renderer/content_renderer_client.h"
|
||||
|
||||
#include "base/base_switches.h"
|
||||
@@ -376,6 +377,10 @@ void CefContext::OnContextInitialized() {
|
||||
|
||||
static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Initialize();
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
CefWidevineLoader::GetInstance()->OnContextInitialized();
|
||||
#endif
|
||||
|
||||
// Notify the handler.
|
||||
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
|
||||
if (app.get()) {
|
||||
|
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "libcef/browser/prefs/browser_prefs.h"
|
||||
|
||||
#include "libcef/browser/component_updater/cef_component_updater_configurator.h"
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/net/url_request_context_getter_impl.h"
|
||||
#include "libcef/browser/prefs/renderer_prefs.h"
|
||||
@@ -173,8 +172,6 @@ std::unique_ptr<PrefService> CreatePrefService(
|
||||
renderer_prefs::RegisterProfilePrefs(registry.get());
|
||||
update_client::RegisterPrefs(registry.get());
|
||||
content_settings::CookieSettings::RegisterProfilePrefs(registry.get());
|
||||
component_updater::RegisterPrefsForCefComponentUpdaterConfigurator(
|
||||
registry.get());
|
||||
|
||||
// Print preferences.
|
||||
registry->RegisterBooleanPref(prefs::kPrintingEnabled, true);
|
||||
|
@@ -3,8 +3,10 @@
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/web_plugin_impl.h"
|
||||
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/widevine_loader.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
@@ -28,6 +30,22 @@ void PluginsCallbackImpl(
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)) || \
|
||||
defined(OS_LINUX)
|
||||
|
||||
void DeliverWidevineCdmError(const std::string& error_message,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
LOG(ERROR) << error_message;
|
||||
if (callback.get()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefRegisterCdmCallback::OnCdmRegistrationComplete,
|
||||
callback.get(), CEF_CDM_REGISTRATION_ERROR_NOT_SUPPORTED,
|
||||
error_message));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -150,3 +168,24 @@ void CefIsWebPluginUnstable(
|
||||
CEF_POST_TASK(CEF_IOT, base::Bind(CefIsWebPluginUnstable, path, callback));
|
||||
}
|
||||
}
|
||||
|
||||
void CefRegisterWidevineCdm(const CefString& path,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
#if defined(OS_LINUX)
|
||||
// Enforce the requirement that CefRegisterWidevineCdm() is called before
|
||||
// CefInitialize() on Linux. See comments in
|
||||
// CefWidevineLoader::AddPepperPlugins for details.
|
||||
if (CONTEXT_STATE_VALID()) {
|
||||
DeliverWidevineCdmError(
|
||||
"Widevine registration is not supported after context initialization",
|
||||
callback);
|
||||
return;
|
||||
}
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
CefWidevineLoader::GetInstance()->LoadWidevineCdm(path, callback);
|
||||
#else
|
||||
DeliverWidevineCdmError("Widevine registration is not supported", callback);
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
}
|
||||
|
@@ -106,15 +106,9 @@ const char kDisableScrollBounce[] = "disable-scroll-bounce";
|
||||
// Disable the PDF extension.
|
||||
const char kDisablePdfExtension[] = "disable-pdf-extension";
|
||||
|
||||
// Enable Widevine CDM.
|
||||
const char kEnableWidevineCdm[] = "enable-widevine-cdm";
|
||||
|
||||
// Path to Widevine CDM binaries.
|
||||
const char kWidevineCdmPath[] = "widevine-cdm-path";
|
||||
|
||||
// Widevine CDM version.
|
||||
const char kWidevineCdmVersion[] = "widevine-cdm-version";
|
||||
|
||||
// Default plugin policy action.
|
||||
const char kPluginPolicy[] = "plugin-policy";
|
||||
// Allow the content. This is the default value.
|
||||
|
@@ -45,9 +45,7 @@ extern const char kOverrideSpellCheckLang[];
|
||||
extern const char kEnableSystemFlash[];
|
||||
extern const char kDisableScrollBounce[];
|
||||
extern const char kDisablePdfExtension[];
|
||||
extern const char kEnableWidevineCdm[];
|
||||
extern const char kWidevineCdmPath[];
|
||||
extern const char kWidevineCdmVersion[];
|
||||
extern const char kPluginPolicy[];
|
||||
extern const char kPluginPolicy_Allow[];
|
||||
extern const char kPluginPolicy_Detect[];
|
||||
|
@@ -37,12 +37,8 @@
|
||||
#include "ppapi/shared_impl/ppapi_permissions.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
|
||||
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
||||
|
||||
// The following must be after widevine_cdm_version.h.
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) && \
|
||||
!defined(WIDEVINE_CDM_IS_COMPONENT)
|
||||
#include "chrome/common/widevine_cdm_constants.h"
|
||||
#if defined(OS_LINUX)
|
||||
#include "libcef/common/widevine_loader.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@@ -182,67 +178,6 @@ bool GetSystemPepperFlash(content::PepperPluginInfo* plugin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddWidevineCdmFromCommandLine(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) && \
|
||||
!defined(WIDEVINE_CDM_IS_COMPONENT)
|
||||
static bool skip_widevine_cdm_file_check = false;
|
||||
|
||||
base::FilePath widevine_cdm_path =
|
||||
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
|
||||
switches::kWidevineCdmPath);
|
||||
if (!widevine_cdm_path.empty()) {
|
||||
widevine_cdm_path =
|
||||
widevine_cdm_path.AppendASCII(kWidevineCdmAdapterFileName);
|
||||
}
|
||||
|
||||
// Also get the version from the command-line. Should be something like
|
||||
// 1.4.8.824.
|
||||
const std::string& widevine_cdm_version =
|
||||
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
||||
switches::kWidevineCdmVersion);
|
||||
|
||||
if (!widevine_cdm_path.empty() && !widevine_cdm_version.empty()) {
|
||||
if (skip_widevine_cdm_file_check || base::PathExists(widevine_cdm_path)) {
|
||||
content::PepperPluginInfo widevine_cdm;
|
||||
widevine_cdm.is_out_of_process = true;
|
||||
widevine_cdm.path = widevine_cdm_path;
|
||||
widevine_cdm.name = kWidevineCdmDisplayName;
|
||||
widevine_cdm.description = kWidevineCdmDescription +
|
||||
std::string(" (version: ") +
|
||||
widevine_cdm_version + ")";
|
||||
widevine_cdm.version = widevine_cdm_version;
|
||||
content::WebPluginMimeType widevine_cdm_mime_type(
|
||||
kWidevineCdmPluginMimeType,
|
||||
kWidevineCdmPluginExtension,
|
||||
kWidevineCdmPluginMimeTypeDescription);
|
||||
|
||||
// Add the supported codecs as if they came from the component manifest.
|
||||
// This list must match the CDM that is being shipped with Chrome.
|
||||
std::vector<std::string> codecs;
|
||||
codecs.push_back(kCdmSupportedCodecVp8);
|
||||
codecs.push_back(kCdmSupportedCodecVp9);
|
||||
#if defined(USE_PROPRIETARY_CODECS)
|
||||
codecs.push_back(kCdmSupportedCodecAvc1);
|
||||
#endif // defined(USE_PROPRIETARY_CODECS)
|
||||
std::string codec_string = base::JoinString(
|
||||
codecs, std::string(1, kCdmSupportedCodecsValueDelimiter));
|
||||
widevine_cdm_mime_type.additional_param_names.push_back(
|
||||
base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
|
||||
widevine_cdm_mime_type.additional_param_values.push_back(
|
||||
base::ASCIIToUTF16(codec_string));
|
||||
|
||||
widevine_cdm.mime_types.push_back(widevine_cdm_mime_type);
|
||||
widevine_cdm.permissions = kWidevineCdmPluginPermissions;
|
||||
plugins->push_back(widevine_cdm);
|
||||
|
||||
skip_widevine_cdm_file_check = true;
|
||||
}
|
||||
}
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) &&
|
||||
// !defined(WIDEVINE_CDM_IS_COMPONENT)
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const char CefContentClient::kPDFPluginPath[] = "internal-pdf-viewer";
|
||||
@@ -269,7 +204,12 @@ void CefContentClient::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
ComputeBuiltInPlugins(plugins);
|
||||
AddPepperFlashFromCommandLine(plugins);
|
||||
AddWidevineCdmFromCommandLine(plugins);
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
CefWidevineLoader::AddPepperPlugins(plugins);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
content::PepperPluginInfo plugin;
|
||||
if (GetSystemPepperFlash(&plugin))
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "components/component_updater/component_updater_paths.h"
|
||||
#include "components/content_settings/core/common/content_settings_pattern.h"
|
||||
#include "content/public/browser/browser_main_runner.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
@@ -41,8 +40,6 @@
|
||||
#include "ui/base/ui_base_paths.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
|
||||
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
||||
|
||||
#include "ipc/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED.
|
||||
|
||||
#if defined(IPC_MESSAGE_LOG_ENABLED)
|
||||
@@ -559,26 +556,6 @@ void CefMainDelegate::PreSandboxStartup() {
|
||||
user_data_path.AppendASCII("Dictionaries"),
|
||||
false, // May not be an absolute path.
|
||||
true); // Create if necessary.
|
||||
|
||||
const base::FilePath& resources_path = GetResourcesFilePath();
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
const base::FilePath& widevine_plugin_path =
|
||||
resources_path.AppendASCII(kWidevineCdmAdapterFileName);
|
||||
if (base::PathExists(widevine_plugin_path)) {
|
||||
PathService::Override(chrome::FILE_WIDEVINE_CDM_ADAPTER,
|
||||
widevine_plugin_path);
|
||||
}
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
|
||||
// Paths to find pre-installed components.
|
||||
PathService::Override(chrome::DIR_COMPONENTS, resources_path);
|
||||
PathService::Override(chrome::DIR_INTERNAL_PLUGINS, resources_path);
|
||||
|
||||
// Register paths to be used by the component updater.
|
||||
component_updater::RegisterPathProvider(chrome::DIR_COMPONENTS,
|
||||
chrome::DIR_INTERNAL_PLUGINS,
|
||||
chrome::DIR_USER_DATA);
|
||||
}
|
||||
|
||||
if (command_line->HasSwitch(switches::kDisablePackLoading))
|
||||
|
406
libcef/common/widevine_loader.cc
Normal file
406
libcef/common/widevine_loader.cc
Normal file
@@ -0,0 +1,406 @@
|
||||
// Copyright 2016 The Chromium Embedded Framework Authors. Portions copyright
|
||||
// 2013 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 "libcef/common/widevine_loader.h"
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/cef_switches.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/json/json_string_value_serializer.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/native_library.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/widevine_cdm_constants.h"
|
||||
#include "content/browser/plugin_service_impl.h"
|
||||
#include "content/public/browser/cdm_service.h"
|
||||
#include "content/public/common/cdm_info.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/cdm/supported_cdm_versions.h"
|
||||
|
||||
namespace {
|
||||
|
||||
base::LazyInstance<CefWidevineLoader>::Leaky g_widevine_loader =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
|
||||
// Based on chrome/browser/component_updater/widevine_cdm_component_installer.cc
|
||||
|
||||
// Name of the Widevine CDM OS in the component manifest.
|
||||
const char kWidevineCdmOs[] =
|
||||
#if defined(OS_MACOSX)
|
||||
"mac";
|
||||
#elif defined(OS_WIN)
|
||||
"win";
|
||||
#else // OS_LINUX, etc. TODO(viettrungluu): Separate out Chrome OS and Android?
|
||||
"linux";
|
||||
#endif
|
||||
|
||||
// Name of the Widevine CDM architecture in the component manifest.
|
||||
const char kWidevineCdmArch[] =
|
||||
#if defined(ARCH_CPU_X86)
|
||||
"ia32"; // This differs from the component updater which uses "x86".
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
"x64";
|
||||
#else // TODO(viettrungluu): Support an ARM check?
|
||||
"???";
|
||||
#endif
|
||||
|
||||
// The CDM OS and architecture.
|
||||
const char kCdmOsName[] = "os";
|
||||
const char kCdmArchName[] = "arch";
|
||||
|
||||
// The CDM version (e.g. "1.4.8.903").
|
||||
const char kCdmVersionName[] = "version";
|
||||
|
||||
// The CDM manifest includes several custom values, all beginning with "x-cdm-".
|
||||
// All values are strings.
|
||||
// All values that are lists are delimited by commas. No trailing commas.
|
||||
// For example, "1,2,4".
|
||||
const char kCdmValueDelimiter = ',';
|
||||
static_assert(kCdmValueDelimiter == kCdmSupportedCodecsValueDelimiter,
|
||||
"cdm delimiters must match");
|
||||
// The following entries are required.
|
||||
// Interface versions are lists of integers (e.g. "1" or "1,2,4").
|
||||
// These are checked in this file before registering the CDM.
|
||||
// All match the interface versions from content_decryption_module.h that the
|
||||
// CDM supports.
|
||||
// Matches CDM_MODULE_VERSION.
|
||||
const char kCdmModuleVersionsName[] = "x-cdm-module-versions";
|
||||
// Matches supported ContentDecryptionModule_* version(s).
|
||||
const char kCdmInterfaceVersionsName[] = "x-cdm-interface-versions";
|
||||
// Matches supported Host_* version(s).
|
||||
const char kCdmHostVersionsName[] = "x-cdm-host-versions";
|
||||
// The codecs list is a list of simple codec names (e.g. "vp8,vorbis").
|
||||
// The list is passed to other parts of Chrome.
|
||||
const char kCdmCodecsListName[] = "x-cdm-codecs";
|
||||
|
||||
std::unique_ptr<base::DictionaryValue> ParseManifestFile(
|
||||
const base::FilePath& manifest_path) {
|
||||
CEF_REQUIRE_FILET();
|
||||
|
||||
// Manifest file should be < 1kb. Read at most 2kb.
|
||||
std::string manifest_contents;
|
||||
if (!base::ReadFileToStringWithMaxSize(manifest_path, &manifest_contents,
|
||||
2048)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSONStringValueDeserializer deserializer(manifest_contents);
|
||||
std::unique_ptr<base::Value> manifest(deserializer.Deserialize(NULL, NULL));
|
||||
|
||||
if (!manifest.get() || !manifest->IsType(base::Value::TYPE_DICTIONARY))
|
||||
return nullptr;
|
||||
|
||||
// Transfer ownership to the caller.
|
||||
return base::WrapUnique(
|
||||
static_cast<base::DictionaryValue*>(manifest.release()));
|
||||
}
|
||||
|
||||
std::string GetManifestValue(const base::DictionaryValue& manifest,
|
||||
const std::string& key,
|
||||
std::string* error_message) {
|
||||
std::stringstream ss;
|
||||
std::string value;
|
||||
if (!manifest.GetString(key, &value)) {
|
||||
ss << "Manifest missing " << key;
|
||||
*error_message = ss.str();
|
||||
} else if (value.empty()) {
|
||||
ss << "Manifest has empty " << key;
|
||||
*error_message = ss.str();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
typedef bool (*VersionCheckFunc)(int version);
|
||||
|
||||
bool CheckForCompatibleVersion(const base::DictionaryValue& manifest,
|
||||
const std::string version_name,
|
||||
VersionCheckFunc version_check_func,
|
||||
std::string* error_message) {
|
||||
std::string versions_string =
|
||||
GetManifestValue(manifest, version_name, error_message);
|
||||
if (versions_string.empty())
|
||||
return false;
|
||||
|
||||
for (const base::StringPiece& ver_str : base::SplitStringPiece(
|
||||
versions_string, std::string(1, kCdmValueDelimiter),
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
|
||||
int version = 0;
|
||||
if (base::StringToInt(ver_str, &version))
|
||||
if (version_check_func(version))
|
||||
return true;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Manifest has no supported " << version_name << " in '" <<
|
||||
versions_string << "'";
|
||||
*error_message = ss.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether the CDM's OS/platform and module/interface/host API versions,
|
||||
// as specified in the manifest, are compatible with this Chromium binary.
|
||||
bool IsCompatibleWithChrome(const base::DictionaryValue& manifest,
|
||||
std::string* error_message) {
|
||||
return GetManifestValue(manifest, kCdmOsName, error_message) ==
|
||||
kWidevineCdmOs &&
|
||||
GetManifestValue(manifest, kCdmArchName, error_message) ==
|
||||
kWidevineCdmArch &&
|
||||
CheckForCompatibleVersion(manifest,
|
||||
kCdmModuleVersionsName,
|
||||
media::IsSupportedCdmModuleVersion,
|
||||
error_message) &&
|
||||
CheckForCompatibleVersion(manifest,
|
||||
kCdmInterfaceVersionsName,
|
||||
media::IsSupportedCdmInterfaceVersion,
|
||||
error_message) &&
|
||||
CheckForCompatibleVersion(manifest,
|
||||
kCdmHostVersionsName,
|
||||
media::IsSupportedCdmHostVersion,
|
||||
error_message);
|
||||
}
|
||||
|
||||
// Populate the PepperPluginInfo structure.
|
||||
void GetPluginInfo(const base::FilePath& cdm_adapter_path,
|
||||
const base::FilePath& cdm_path,
|
||||
const std::string& cdm_version,
|
||||
const std::string& cdm_codecs,
|
||||
content::PepperPluginInfo* widevine_cdm) {
|
||||
widevine_cdm->is_out_of_process = true;
|
||||
widevine_cdm->path = cdm_adapter_path;
|
||||
widevine_cdm->name = kWidevineCdmDisplayName;
|
||||
widevine_cdm->description = kWidevineCdmDescription +
|
||||
std::string(" (version: ") +
|
||||
cdm_version + ")";
|
||||
widevine_cdm->version = cdm_version;
|
||||
content::WebPluginMimeType widevine_cdm_mime_type(
|
||||
kWidevineCdmPluginMimeType,
|
||||
kWidevineCdmPluginExtension,
|
||||
kWidevineCdmPluginMimeTypeDescription);
|
||||
|
||||
widevine_cdm_mime_type.additional_param_names.push_back(
|
||||
base::ASCIIToUTF16(kCdmSupportedCodecsParamName));
|
||||
widevine_cdm_mime_type.additional_param_values.push_back(
|
||||
base::ASCIIToUTF16(cdm_codecs));
|
||||
|
||||
widevine_cdm->mime_types.push_back(widevine_cdm_mime_type);
|
||||
widevine_cdm->permissions = kWidevineCdmPluginPermissions;
|
||||
}
|
||||
|
||||
// Verify and load the contents of |base_path|.
|
||||
cef_cdm_registration_error_t LoadWidevineCdmInfo(
|
||||
const base::FilePath& base_path,
|
||||
base::FilePath* cdm_adapter_path,
|
||||
base::FilePath* cdm_path,
|
||||
std::string* cdm_version,
|
||||
std::string* cdm_codecs,
|
||||
std::string* error_message) {
|
||||
std::stringstream ss;
|
||||
|
||||
*cdm_adapter_path = base_path.AppendASCII(kWidevineCdmAdapterFileName);
|
||||
if (!base::PathExists(*cdm_adapter_path)) {
|
||||
ss << "Missing adapter file " << cdm_adapter_path->value();
|
||||
*error_message = ss.str();
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
}
|
||||
|
||||
*cdm_path = base_path.AppendASCII(
|
||||
base::GetNativeLibraryName(kWidevineCdmLibraryName));
|
||||
if (!base::PathExists(*cdm_path)) {
|
||||
ss << "Missing file " << cdm_path->value();
|
||||
*error_message = ss.str();
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
}
|
||||
|
||||
base::FilePath manifest_path = base_path.AppendASCII("manifest.json");
|
||||
if (!base::PathExists(manifest_path)) {
|
||||
ss << "Missing manifest file " << manifest_path.value();
|
||||
*error_message = ss.str();
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
}
|
||||
|
||||
std::unique_ptr<base::DictionaryValue> manifest =
|
||||
ParseManifestFile(manifest_path);
|
||||
if (!manifest) {
|
||||
ss << "Failed to parse manifest file " << manifest_path.value();
|
||||
*error_message = ss.str();
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
}
|
||||
|
||||
if (!IsCompatibleWithChrome(*manifest, error_message))
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCOMPATIBLE;
|
||||
|
||||
*cdm_version = GetManifestValue(*manifest, kCdmVersionName, error_message);
|
||||
if (cdm_version->empty())
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
|
||||
*cdm_codecs = GetManifestValue(*manifest, kCdmCodecsListName, error_message);
|
||||
if (cdm_codecs->empty())
|
||||
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
|
||||
|
||||
return CEF_CDM_REGISTRATION_ERROR_NONE;
|
||||
}
|
||||
|
||||
void DeliverWidevineCdmCallback(cef_cdm_registration_error_t result,
|
||||
const std::string& error_message,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
if (result != CEF_CDM_REGISTRATION_ERROR_NONE)
|
||||
LOG(ERROR) << "Widevine CDM registration failed; " << error_message;
|
||||
|
||||
if (callback)
|
||||
callback->OnCdmRegistrationComplete(result, error_message);
|
||||
}
|
||||
|
||||
void RegisterWidevineCdmOnUIThread(
|
||||
const base::FilePath& cdm_adapter_path,
|
||||
const base::FilePath& cdm_path,
|
||||
const std::string& cdm_version,
|
||||
const std::string& cdm_codecs,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
content::PepperPluginInfo widevine_cdm;
|
||||
GetPluginInfo(cdm_adapter_path, cdm_path, cdm_version, cdm_codecs,
|
||||
&widevine_cdm);
|
||||
|
||||
// true = Add to beginning of list to override any existing registrations.
|
||||
content::PluginService::GetInstance()->RegisterInternalPlugin(
|
||||
widevine_cdm.ToWebPluginInfo(), true);
|
||||
// Tell the browser to refresh the plugin list. Then tell all renderers to
|
||||
// update their plugin list caches.
|
||||
content::PluginService::GetInstance()->RefreshPlugins();
|
||||
content::PluginService::GetInstance()->PurgePluginListCache(NULL, false);
|
||||
|
||||
// Also register Widevine with the CdmService.
|
||||
const std::vector<std::string> codecs = base::SplitString(
|
||||
cdm_codecs, std::string(1, kCdmSupportedCodecsValueDelimiter),
|
||||
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
content::CdmService::GetInstance()->RegisterCdm(content::CdmInfo(
|
||||
kWidevineCdmType, base::Version(cdm_version), cdm_path, codecs));
|
||||
|
||||
DeliverWidevineCdmCallback(CEF_CDM_REGISTRATION_ERROR_NONE, std::string(),
|
||||
callback);
|
||||
}
|
||||
|
||||
void LoadWidevineCdmInfoOnFileThread(
|
||||
const base::FilePath& base_path,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
CEF_REQUIRE_FILET();
|
||||
|
||||
base::FilePath cdm_adapter_path;
|
||||
base::FilePath cdm_path;
|
||||
std::string cdm_version;
|
||||
std::string cdm_codecs;
|
||||
std::string error_message;
|
||||
cef_cdm_registration_error_t result =
|
||||
LoadWidevineCdmInfo(base_path, &cdm_adapter_path, &cdm_path, &cdm_version,
|
||||
&cdm_codecs, &error_message);
|
||||
if (result != CEF_CDM_REGISTRATION_ERROR_NONE) {
|
||||
CEF_POST_TASK(CEF_UIT, base::Bind(DeliverWidevineCdmCallback, result,
|
||||
error_message, callback));
|
||||
return;
|
||||
}
|
||||
|
||||
// Continue execution on the UI thread.
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(RegisterWidevineCdmOnUIThread, cdm_adapter_path, cdm_path,
|
||||
cdm_version, cdm_codecs, callback));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefWidevineLoader* CefWidevineLoader::GetInstance() {
|
||||
return &g_widevine_loader.Get();
|
||||
}
|
||||
|
||||
void CefWidevineLoader::LoadWidevineCdm(
|
||||
const base::FilePath& path,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback) {
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
// Loading will proceed from OnContextInitialized().
|
||||
load_pending_ = true;
|
||||
path_ = path;
|
||||
callback_ = callback;
|
||||
return;
|
||||
}
|
||||
|
||||
// Continue execution on the FILE thread.
|
||||
CEF_POST_TASK(CEF_FILET,
|
||||
base::Bind(LoadWidevineCdmInfoOnFileThread, path, callback));
|
||||
}
|
||||
|
||||
void CefWidevineLoader::OnContextInitialized() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (load_pending_) {
|
||||
load_pending_ = false;
|
||||
LoadWidevineCdm(path_, callback_);
|
||||
callback_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
// static
|
||||
void CefWidevineLoader::AddPepperPlugins(
|
||||
std::vector<content::PepperPluginInfo>* plugins) {
|
||||
const base::CommandLine& command_line =
|
||||
*base::CommandLine::ForCurrentProcess();
|
||||
|
||||
// Perform early plugin registration in the zygote process when the sandbox is
|
||||
// enabled to avoid "cannot open shared object file: Operation not permitted"
|
||||
// errors during plugin loading. This is because the Zygote process must pre-
|
||||
// load all plugins before initializing the sandbox.
|
||||
if (command_line.GetSwitchValueASCII(switches::kProcessType) !=
|
||||
switches::kZygoteProcess ||
|
||||
command_line.HasSwitch(switches::kNoSandbox)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The Widevine CDM path is passed to the zygote process via
|
||||
// CefContentBrowserClient::AppendExtraCommandLineSwitches.
|
||||
const base::FilePath& base_path = command_line.GetSwitchValuePath(
|
||||
switches::kWidevineCdmPath);
|
||||
if (base_path.empty())
|
||||
return;
|
||||
|
||||
// Load contents of the plugin directory synchronously. This only occurs once
|
||||
// on zygote process startup so should not have a huge performance penalty.
|
||||
base::FilePath cdm_adapter_path;
|
||||
base::FilePath cdm_path;
|
||||
std::string cdm_version;
|
||||
std::string cdm_codecs;
|
||||
std::string error_message;
|
||||
cef_cdm_registration_error_t result =
|
||||
LoadWidevineCdmInfo(base_path, &cdm_adapter_path, &cdm_path, &cdm_version,
|
||||
&cdm_codecs, &error_message);
|
||||
if (result != CEF_CDM_REGISTRATION_ERROR_NONE) {
|
||||
LOG(ERROR) << "Widevine CDM registration failed; " << error_message;
|
||||
return;
|
||||
}
|
||||
|
||||
content::PepperPluginInfo widevine_cdm;
|
||||
GetPluginInfo(cdm_adapter_path, cdm_path, cdm_version, cdm_codecs,
|
||||
&widevine_cdm);
|
||||
plugins->push_back(widevine_cdm);
|
||||
}
|
||||
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
CefWidevineLoader::CefWidevineLoader() {
|
||||
}
|
||||
|
||||
CefWidevineLoader::~CefWidevineLoader() {
|
||||
}
|
||||
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
64
libcef/common/widevine_loader.h
Normal file
64
libcef/common/widevine_loader.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_COMMON_WIDEVINE_LOADER_H_
|
||||
#define CEF_LIBCEF_COMMON_WIDEVINE_LOADER_H_
|
||||
#pragma once
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
|
||||
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "include/cef_web_plugin.h"
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
|
||||
namespace content {
|
||||
struct PepperPluginInfo;
|
||||
}
|
||||
|
||||
class CefWidevineLoader {
|
||||
public:
|
||||
// Returns the singleton instance of this object.
|
||||
static CefWidevineLoader* GetInstance();
|
||||
|
||||
// Load the Widevine CDM. May be called before or after context creation. See
|
||||
// comments in cef_web_plugin.h.
|
||||
void LoadWidevineCdm(const base::FilePath& path,
|
||||
CefRefPtr<CefRegisterCdmCallback> callback);
|
||||
|
||||
// Plugin registration is triggered here if LoadWidevineCdm() was called
|
||||
// before context creation.
|
||||
void OnContextInitialized();
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// The zygote process which is used when the sandbox is enabled on Linux
|
||||
// requires early loading of pepper plugins. Other processes will receive
|
||||
// load notification in the usual way.
|
||||
// Called from CefContentClient::AddPepperPlugins.
|
||||
static void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins);
|
||||
|
||||
const base::FilePath& path() { return path_; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend struct base::DefaultLazyInstanceTraits<CefWidevineLoader>;
|
||||
|
||||
// Members are only accessed before context initialization or on the UI
|
||||
// thread.
|
||||
bool load_pending_ = false;
|
||||
base::FilePath path_;
|
||||
CefRefPtr<CefRegisterCdmCallback> callback_;
|
||||
|
||||
CefWidevineLoader();
|
||||
~CefWidevineLoader();
|
||||
};
|
||||
|
||||
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
|
||||
|
||||
#endif // CEF_LIBCEF_COMMON_WIDEVINE_LOADER_H_
|
Reference in New Issue
Block a user