Add Widevine CDM support (issue #1631)

- Windows/Mac: Use `--enable-widevine-cdm` command-line flag to
  enable download of CDM binaries via the component updater.
- Linux: Use `--widevide-cdm-path` and `--widevine-cdm-version`
  command-line flags to load CDM binaries that already exist on
  the system.
- A cache-path value is usually required when CDM is enabled.
This commit is contained in:
Marshall Greenblatt 2015-08-31 13:28:07 +02:00
parent 4a8546efd7
commit 3640f81f01
23 changed files with 1002 additions and 2 deletions

18
cef.gyp
View File

@ -936,6 +936,8 @@
# Generate chrome/common/safe_browsing/csd.pb.h required by
# zip_analyzer_results.h via chrome_utility_messages.h
'<(DEPTH)/chrome/chrome.gyp:safe_browsing_proto',
'<(DEPTH)/components/components.gyp:cdm_renderer',
'<(DEPTH)/components/components.gyp:component_updater',
'<(DEPTH)/components/components.gyp:crash_component_breakpad_mac_to_be_deleted',
'<(DEPTH)/components/components.gyp:crx_file',
'<(DEPTH)/components/components.gyp:devtools_discovery',
@ -953,6 +955,7 @@
'<(DEPTH)/components/components.gyp:proxy_config',
'<(DEPTH)/components/components.gyp:update_client',
'<(DEPTH)/components/components.gyp:user_prefs',
'<(DEPTH)/components/components.gyp:version_info',
'<(DEPTH)/components/components.gyp:web_cache_renderer',
'<(DEPTH)/components/url_formatter/url_formatter.gyp:url_formatter',
'<(DEPTH)/content/content.gyp:content_app_both',
@ -988,6 +991,8 @@
'<(DEPTH)/third_party/libxml/libxml.gyp:libxml',
'<(DEPTH)/third_party/WebKit/public/blink.gyp:blink',
'<(DEPTH)/third_party/WebKit/Source/core/core.gyp:webcore',
'<(DEPTH)/third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
'<(DEPTH)/third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h',
'<(DEPTH)/third_party/zlib/zlib.gyp:minizip',
'<(DEPTH)/ui/gl/gl.gyp:gl',
'<(DEPTH)/ui/base/ime/ui_base_ime.gyp:ui_base_ime',
@ -1047,6 +1052,8 @@
'libcef/browser/download_item_impl.h',
'libcef/browser/download_manager_delegate.cc',
'libcef/browser/download_manager_delegate.h',
'libcef/browser/component_updater/cef_component_updater_configurator.cc',
'libcef/browser/component_updater/cef_component_updater_configurator.h',
'libcef/browser/extensions/api/streams_private/streams_private_api.cc',
'libcef/browser/extensions/api/streams_private/streams_private_api.h',
'libcef/browser/extensions/browser_context_keyed_service_factories.cc',
@ -1102,6 +1109,8 @@
'libcef/browser/pepper/browser_pepper_host_factory.h',
'libcef/browser/pepper/pepper_flash_browser_host.cc',
'libcef/browser/pepper/pepper_flash_browser_host.h',
'libcef/browser/pepper/pepper_isolated_file_system_message_filter.cc',
'libcef/browser/pepper/pepper_isolated_file_system_message_filter.h',
'libcef/browser/pepper/device_id_fetcher.cc',
'libcef/browser/permission_manager.cc',
'libcef/browser/permission_manager.h',
@ -1246,6 +1255,8 @@
'libcef/renderer/extensions/print_web_view_helper_delegate.h',
'libcef/renderer/frame_impl.cc',
'libcef/renderer/frame_impl.h',
'libcef/renderer/media/cef_key_systems.cc',
'libcef/renderer/media/cef_key_systems.h',
'libcef/renderer/pepper/pepper_helper.cc',
'libcef/renderer/pepper/pepper_helper.h',
'libcef/renderer/pepper/pepper_uma_host.cc',
@ -1386,6 +1397,12 @@
'<(DEPTH)/extensions/shell/browser/shell_display_info_provider.h',
'<(DEPTH)/extensions/shell/browser/shell_web_contents_modal_dialog_manager.cc',
'<(grit_out_dir)/grit/component_extension_resources_map.cc',
# Include sources for component-updater support.
'<(DEPTH)/chrome/browser/component_updater/widevine_cdm_component_installer.cc',
'<(DEPTH)/chrome/browser/component_updater/widevine_cdm_component_installer.h',
# Include sources for widevine support.
'<(DEPTH)/chrome/common/widevine_cdm_constants.cc',
'<(DEPTH)/chrome/common/widevine_cdm_constants.h',
],
'conditions': [
['OS=="win"', {
@ -1497,6 +1514,7 @@
'<(PRODUCT_DIR)/icudtl.dat',
'<(PRODUCT_DIR)/natives_blob.bin',
'<(PRODUCT_DIR)/snapshot_blob.bin',
'<(PRODUCT_DIR)/widevinecdmadapter.plugin',
'libcef/resources/framework-Info.plist',
],
'mac_bundle_resources!': [

View File

@ -9,6 +9,8 @@
# Set ENABLE_PRINTING=1 ENABLE_BASIC_PRINTING=1.
'enable_basic_printing': 1,
'enable_print_preview': 0,
# Enable support for Widevine CDM.
'enable_widevine': 1,
'conditions': [
# Directory for CEF source files.
[ 'OS=="win"', {

View File

@ -224,8 +224,7 @@ ChromeNetLog* ChromeBrowserProcessStub::net_log() {
component_updater::ComponentUpdateService*
ChromeBrowserProcessStub::component_updater() {
NOTIMPLEMENTED();
return NULL;
return CefContext::Get()->component_updater();
}
CRLSetFetcher* ChromeBrowserProcessStub::crl_set_fetcher() {

View File

@ -0,0 +1,307 @@
// 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 <algorithm>
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/strings/stringprintf.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
#include "components/update_client/component_patcher_operation.h"
#include "components/component_updater/component_updater_switches.h"
#include "components/component_updater/component_updater_url_constants.h"
#include "components/update_client/configurator.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
#if defined(OS_WIN)
#include "base/win/win_util.h"
#endif // OS_WIN
using update_client::Configurator;
namespace component_updater {
namespace {
// Default time constants.
const int kDelayOneMinute = 60;
const int kDelayOneHour = kDelayOneMinute * 60;
// Debug values you can pass to --component-updater=value1,value2.
// Speed up component checking.
const char kSwitchFastUpdate[] = "fast-update";
// Add "testrequest=1" attribute to the update check request.
const char kSwitchRequestParam[] = "test-request";
// Disables pings. Pings are the requests sent to the update server that report
// the success or the failure of component install or update attempts.
extern const char kSwitchDisablePings[] = "disable-pings";
// Sets the URL for updates.
const char kSwitchUrlSource[] = "url-source";
// Disables differential updates.
const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates";
#if defined(OS_WIN)
// Disables background downloads.
const char kSwitchDisableBackgroundDownloads[] = "disable-background-downloads";
#endif // defined(OS_WIN)
// Returns true if and only if |test| is contained in |vec|.
bool HasSwitchValue(const std::vector<std::string>& vec, const char* test) {
if (vec.empty())
return 0;
return (std::find(vec.begin(), vec.end(), test) != vec.end());
}
// Returns true if falling back on an alternate, unsafe, service URL is
// allowed. In the fallback case, the security of the component update relies
// only on the integrity of the CRX payloads, which is self-validating.
// This is allowed only for some of the pre-Windows Vista versions not including
// Windows XP SP3. As a side note, pings could be sent to the alternate URL too.
bool CanUseAltUrlSource() {
#if defined(OS_WIN)
return !base::win::MaybeHasSHA256Support();
#else
return false;
#endif // OS_WIN
}
// If there is an element of |vec| of the form |test|=.*, returns the right-
// hand side of that assignment. Otherwise, returns an empty string.
// The right-hand side may contain additional '=' characters, allowing for
// further nesting of switch arguments.
std::string GetSwitchArgument(const std::vector<std::string>& vec,
const char* test) {
if (vec.empty())
return std::string();
for (std::vector<std::string>::const_iterator it = vec.begin();
it != vec.end();
++it) {
const std::size_t found = it->find("=");
if (found != std::string::npos) {
if (it->substr(0, found) == test) {
return it->substr(found + 1);
}
}
}
return std::string();
}
class CefConfigurator : public Configurator {
public:
CefConfigurator(const base::CommandLine* cmdline,
net::URLRequestContextGetter* url_request_getter);
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 GetLang() const override;
std::string GetOSLongName() const override;
std::string ExtraRequestParams() const override;
net::URLRequestContextGetter* RequestContext() const override;
scoped_refptr<update_client::OutOfProcessPatcher>
CreateOutOfProcessPatcher() const override;
bool DeltasEnabled() const override;
bool UseBackgroundDownloader() const override;
scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner()
const override;
scoped_refptr<base::SingleThreadTaskRunner> GetSingleThreadTaskRunner()
const override;
private:
friend class base::RefCountedThreadSafe<CefConfigurator>;
~CefConfigurator() override {}
net::URLRequestContextGetter* url_request_getter_;
std::string extra_info_;
GURL url_source_override_;
bool fast_update_;
bool pings_enabled_;
bool deltas_enabled_;
bool background_downloads_enabled_;
bool fallback_to_alt_source_url_enabled_;
};
CefConfigurator::CefConfigurator(
const base::CommandLine* cmdline,
net::URLRequestContextGetter* url_request_getter)
: url_request_getter_(url_request_getter),
fast_update_(false),
pings_enabled_(false),
deltas_enabled_(false),
background_downloads_enabled_(false),
fallback_to_alt_source_url_enabled_(false) {
// Parse comma-delimited debug flags.
std::vector<std::string> switch_values = base::SplitString(
cmdline->GetSwitchValueASCII(switches::kComponentUpdater),
",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate);
pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings);
deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates);
// TODO(dberger): Pull this (and possibly the various hard-coded
// delay params in this file) from cef settings.
fast_update_ = true;
#if defined(OS_WIN)
background_downloads_enabled_ =
!HasSwitchValue(switch_values, kSwitchDisableBackgroundDownloads);
#else
background_downloads_enabled_ = false;
#endif
const std::string switch_url_source =
GetSwitchArgument(switch_values, kSwitchUrlSource);
if (!switch_url_source.empty()) {
url_source_override_ = GURL(switch_url_source);
DCHECK(url_source_override_.is_valid());
}
if (HasSwitchValue(switch_values, kSwitchRequestParam))
extra_info_ += "testrequest=\"1\"";
fallback_to_alt_source_url_enabled_ = CanUseAltUrlSource();
}
int CefConfigurator::InitialDelay() const {
return fast_update_ ? 10 : (6 * kDelayOneMinute);
}
int CefConfigurator::NextCheckDelay() const {
return fast_update_ ? 60 : (6 * kDelayOneHour);
}
int CefConfigurator::StepDelay() const {
return fast_update_ ? 1 : 1;
}
int CefConfigurator::OnDemandDelay() const {
return fast_update_ ? 2 : (30 * kDelayOneMinute);
}
int CefConfigurator::UpdateDelay() const {
return fast_update_ ? 10 : (15 * kDelayOneMinute);
}
std::vector<GURL> CefConfigurator::UpdateUrl() const {
std::vector<GURL> urls;
if (url_source_override_.is_valid()) {
urls.push_back(GURL(url_source_override_));
} else {
urls.push_back(GURL(kUpdaterDefaultUrl));
if (fallback_to_alt_source_url_enabled_) {
urls.push_back(GURL(kUpdaterAltUrl));
}
}
return urls;
}
std::vector<GURL> CefConfigurator::PingUrl() const {
return pings_enabled_ ? UpdateUrl() : std::vector<GURL>();
}
base::Version CefConfigurator::GetBrowserVersion() const {
return base::Version(base::StringPrintf("%d.%d.%d.%d",
CHROME_VERSION_MAJOR,
CHROME_VERSION_MINOR,
CHROME_VERSION_BUILD,
CHROME_VERSION_PATCH));
}
std::string CefConfigurator::GetChannel() const {
return "";
}
std::string CefConfigurator::GetLang() const {
return "";
}
std::string CefConfigurator::GetOSLongName() const {
#if defined(OS_WIN)
return "Windows";
#elif defined(OS_MACOSX)
return "Mac OS X";
#elif defined(OS_CHROMEOS)
return "Chromium OS";
#elif defined(OS_ANDROID)
return "Android";
#elif defined(OS_LINUX)
return "Linux";
#elif defined(OS_FREEBSD)
return "FreeBSD";
#elif defined(OS_OPENBSD)
return "OpenBSD";
#elif defined(OS_SOLARIS)
return "Solaris";
#else
return "Unknown";
#endif
}
std::string CefConfigurator::ExtraRequestParams() const {
return extra_info_;
}
net::URLRequestContextGetter* CefConfigurator::RequestContext() const {
return url_request_getter_;
}
scoped_refptr<update_client::OutOfProcessPatcher>
CefConfigurator::CreateOutOfProcessPatcher() const {
return NULL;
}
bool CefConfigurator::DeltasEnabled() const {
return deltas_enabled_;
}
bool CefConfigurator::UseBackgroundDownloader() const {
return background_downloads_enabled_;
}
scoped_refptr<base::SequencedTaskRunner>
CefConfigurator::GetSequencedTaskRunner() const {
return content::BrowserThread::GetBlockingPool()
->GetSequencedTaskRunnerWithShutdownBehavior(
content::BrowserThread::GetBlockingPool()->GetSequenceToken(),
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
}
scoped_refptr<base::SingleThreadTaskRunner>
CefConfigurator::GetSingleThreadTaskRunner() const {
return content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE);
}
} // namespace
scoped_refptr<update_client::Configurator>
MakeCefComponentUpdaterConfigurator(
const base::CommandLine* cmdline,
net::URLRequestContextGetter* context_getter) {
return new CefConfigurator(cmdline, context_getter);
}
} // namespace component_updater

View File

@ -0,0 +1,28 @@
// 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;
}
namespace component_updater {
scoped_refptr<update_client::Configurator>
MakeCefComponentUpdaterConfigurator(
const base::CommandLine* cmdline,
net::URLRequestContextGetter* context_getter);
} // namespace component_updater
#endif // LIBCEF_BROWSER_COMPONENT_UPDATER_CEF_COMPONENT_UPDATER_CONFIGURATOR_H_

View File

@ -722,6 +722,8 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
switches::kPpapiFlashPath,
switches::kPpapiFlashVersion,
switches::kUncaughtExceptionStackSize,
switches::kWidevineCdmPath,
switches::kWidevineCdmVersion,
};
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
@ -734,6 +736,8 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
static const char* const kSwitchNames[] = {
switches::kPpapiFlashPath,
switches::kPpapiFlashVersion,
switches::kWidevineCdmPath,
switches::kWidevineCdmVersion,
};
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames,
arraysize(kSwitchNames));

View File

@ -9,6 +9,7 @@
#include "libcef/browser/browser_main.h"
#include "libcef/browser/browser_message_loop.h"
#include "libcef/browser/chrome_browser_process_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/browser/trace_subscriber.h"
@ -22,7 +23,11 @@
#include "base/debug/debugger.h"
#include "base/files/file_util.h"
#include "base/synchronization/waitable_event.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 "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/browser/notification_service.h"
@ -330,6 +335,23 @@ CefTraceSubscriber* CefContext::GetTraceSubscriber() {
return trace_subscriber_.get();
}
component_updater::ComponentUpdateService*
CefContext::component_updater() {
if (!component_updater_.get()) {
CEF_REQUIRE_UIT_RETURN(NULL);
scoped_refptr<update_client::Configurator> configurator =
component_updater::MakeCefComponentUpdaterConfigurator(
base::CommandLine::ForCurrentProcess(),
CefContentBrowserClient::Get()->browser_context()->
request_context().get());
// Creating the component updater does not do anything, components
// need to be registered and Start() needs to be called.
component_updater_.reset(component_updater::ComponentUpdateServiceFactory(
configurator).release());
}
return component_updater_.get();
}
void CefContext::PopulateRequestContextSettings(
CefRequestContextSettings* settings) {
CefRefPtr<CefCommandLine> command_line =
@ -345,12 +367,31 @@ void CefContext::PopulateRequestContextSettings(
CefString(&settings_.accept_language_list);
}
void RegisterComponentsForUpdate() {
component_updater::ComponentUpdateService* cus =
CefContext::Get()->component_updater();
// Registration can be before or after cus->Start() so it is ok to post
// a task to the UI thread to do registration once you done the necessary
// file IO to know you existing component version.
#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableWidevineCdm)) {
RegisterWidevineCdmComponent(cus);
}
#endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
}
void CefContext::OnContextInitialized() {
CEF_REQUIRE_UIT();
// Must be created after the NotificationService.
print_job_manager_.reset(new printing::PrintJobManager());
bool io_was_allowed = base::ThreadRestrictions::SetIOAllowed(true);
RegisterComponentsForUpdate();
base::ThreadRestrictions::SetIOAllowed(io_was_allowed);
// Notify the handler.
CefRefPtr<CefApp> app = CefContentClient::Get()->application();
if (app.get()) {

View File

@ -19,6 +19,10 @@ namespace base {
class WaitableEvent;
}
namespace component_updater {
class ComponentUpdateService;
}
namespace content {
class ContentMainRunner;
}
@ -63,6 +67,8 @@ class CefContext {
return print_job_manager_.get();
}
component_updater::ComponentUpdateService* component_updater();
CefTraceSubscriber* GetTraceSubscriber();
// Populate the request context settings based on CefSettings and command-
@ -94,6 +100,9 @@ class CefContext {
// Only accessed on the UI Thread.
scoped_ptr<printing::PrintJobManager> print_job_manager_;
// Initially only for Widevine components.
scoped_ptr<component_updater::ComponentUpdateService> component_updater_;
};
// Helper macro that returns true if the global context is in a valid state.

View File

@ -67,6 +67,8 @@ bool CefPluginInfoMessageFilter::OnMessageReceived(const IPC::Message& message)
IPC_BEGIN_MESSAGE_MAP(CefPluginInfoMessageFilter, message)
IPC_MESSAGE_HANDLER_DELAY_REPLY(CefViewHostMsg_GetPluginInfo,
OnGetPluginInfo)
IPC_MESSAGE_HANDLER(CefViewHostMsg_IsInternalPluginAvailableForMimeType,
OnIsInternalPluginAvailableForMimeType)
IPC_MESSAGE_UNHANDLED(return false)
IPC_END_MESSAGE_MAP()
return true;
@ -214,4 +216,30 @@ bool CefPluginInfoMessageFilter::Context::FindEnabledPlugin(
return enabled;
}
void CefPluginInfoMessageFilter::OnIsInternalPluginAvailableForMimeType(
const std::string& mime_type,
bool* is_available,
std::vector<base::string16>* additional_param_names,
std::vector<base::string16>* additional_param_values) {
std::vector<WebPluginInfo> plugins;
PluginService::GetInstance()->GetInternalPlugins(&plugins);
for (size_t i = 0; i < plugins.size(); ++i) {
const WebPluginInfo& plugin = plugins[i];
const std::vector<content::WebPluginMimeType>& mime_types =
plugin.mime_types;
for (size_t j = 0; j < mime_types.size(); ++j) {
if (mime_types[j].mime_type == mime_type) {
// TODO(cef): Maybe allow plugins to be disabled here.
*is_available = true;
*additional_param_names = mime_types[j].additional_param_names;
*additional_param_values = mime_types[j].additional_param_values;
return;
}
}
}
*is_available = false;
}
} // namespace extensions

View File

@ -76,6 +76,11 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter {
const GURL& top_origin_url,
const std::string& mime_type,
IPC::Message* reply_msg);
void OnIsInternalPluginAvailableForMimeType(
const std::string& mime_type,
bool* is_available,
std::vector<base::string16>* additional_param_names,
std::vector<base::string16>* additional_param_values);
// |params| wraps the parameters passed to |OnGetPluginInfo|, because
// |base::Bind| doesn't support the required arity <http://crbug.com/98542>.

View File

@ -5,6 +5,7 @@
#include "libcef/browser/pepper/browser_pepper_host_factory.h"
#include "libcef/browser/pepper/pepper_flash_browser_host.h"
#include "libcef/browser/pepper/pepper_isolated_file_system_message_filter.h"
#include "build/build_config.h"
#include "chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h"
@ -56,6 +57,21 @@ scoped_ptr<ResourceHost> CefBrowserPepperHostFactory::CreateResourceHost(
}
}
// Permissions for the following interfaces will be checked at the
// time of the corresponding instance's methods calls (because
// permission check can be performed only on the UI
// thread). Currently these interfaces are available only for
// whitelisted apps which may not have access to the other private
// interfaces.
if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) {
PepperIsolatedFileSystemMessageFilter* isolated_fs_filter =
PepperIsolatedFileSystemMessageFilter::Create(instance, host_);
if (!isolated_fs_filter)
return scoped_ptr<ResourceHost>();
return scoped_ptr<ResourceHost>(
new MessageFilterHost(host, instance, resource, isolated_fs_filter));
}
NOTREACHED() << "Unhandled message type: " << message.type();
return scoped_ptr<ResourceHost>();
}

View File

@ -0,0 +1,192 @@
// 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/browser/pepper/pepper_isolated_file_system_message_filter.h"
#include "libcef/browser/browser_context_impl.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pepper_permission_util.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_view_host.h"
#if defined(ENABLE_EXTENSIONS)
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#endif
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/file_system_util.h"
#include "storage/browser/fileapi/isolated_context.h"
namespace {
const char* kPredefinedAllowedCrxFsOrigins[] = {
"6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see crbug.com/234789
"4EB74897CB187C7633357C2FE832E0AD6A44883A" // see crbug.com/234789
};
} // namespace
// static
PepperIsolatedFileSystemMessageFilter*
PepperIsolatedFileSystemMessageFilter::Create(PP_Instance instance,
content::BrowserPpapiHost* host) {
int render_process_id;
int unused_render_frame_id;
if (!host->GetRenderFrameIDsForInstance(
instance, &render_process_id, &unused_render_frame_id)) {
return NULL;
}
return new PepperIsolatedFileSystemMessageFilter(
render_process_id,
host->GetProfileDataDirectory(),
host->GetDocumentURLForInstance(instance),
host->GetPpapiHost());
}
PepperIsolatedFileSystemMessageFilter::PepperIsolatedFileSystemMessageFilter(
int render_process_id,
const base::FilePath& profile_directory,
const GURL& document_url,
ppapi::host::PpapiHost* ppapi_host)
: render_process_id_(render_process_id),
profile_directory_(profile_directory),
document_url_(document_url),
ppapi_host_(ppapi_host) {
for (size_t i = 0; i < arraysize(kPredefinedAllowedCrxFsOrigins); ++i)
allowed_crxfs_origins_.insert(kPredefinedAllowedCrxFsOrigins[i]);
}
PepperIsolatedFileSystemMessageFilter::
~PepperIsolatedFileSystemMessageFilter() {}
scoped_refptr<base::TaskRunner>
PepperIsolatedFileSystemMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& msg) {
// In order to reach ExtensionSystem, we need to get ProfileManager first.
// ProfileManager lives in UI thread, so we need to do this in UI thread.
return content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::UI);
}
int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) {
PPAPI_BEGIN_MESSAGE_MAP(PepperIsolatedFileSystemMessageFilter, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
PpapiHostMsg_IsolatedFileSystem_BrowserOpen,
OnOpenFileSystem)
PPAPI_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
std::string PepperIsolatedFileSystemMessageFilter::CreateCrxFileSystem(
content::BrowserContext* profile) {
#if defined(ENABLE_EXTENSIONS)
const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(profile)->enabled_extensions().GetByID(
document_url_.host());
if (!extension)
return std::string();
// First level directory for isolated filesystem to lookup.
std::string kFirstLevelDirectory("crxfs");
return storage::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
storage::kFileSystemTypeNativeLocal,
std::string(),
extension->path(),
&kFirstLevelDirectory);
#else
return std::string();
#endif
}
int32_t PepperIsolatedFileSystemMessageFilter::OnOpenFileSystem(
ppapi::host::HostMessageContext* context,
PP_IsolatedFileSystemType_Private type) {
switch (type) {
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID:
break;
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
return OpenCrxFileSystem(context);
case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
return OpenPluginPrivateFileSystem(context);
}
NOTREACHED();
context->reply_msg =
PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string());
return PP_ERROR_FAILED;
}
int32_t PepperIsolatedFileSystemMessageFilter::OpenCrxFileSystem(
ppapi::host::HostMessageContext* context) {
#if defined(ENABLE_EXTENSIONS)
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
scoped_refptr<CefBrowserContextImpl> browser_context =
CefBrowserContextImpl::GetForCachePath(profile_directory_);
DCHECK(browser_context);
const extensions::ExtensionSet* extension_set = NULL;
if (browser_context) {
extension_set = &extensions::ExtensionRegistry::Get(browser_context.get())->
enabled_extensions();
}
if (!chrome::IsExtensionOrSharedModuleWhitelisted(
document_url_, extension_set, allowed_crxfs_origins_) &&
!chrome::IsHostAllowedByCommandLine(
document_url_, extension_set, switches::kAllowNaClCrxFsAPI)) {
LOG(ERROR) << "Host " << document_url_.host() << " cannot use CrxFs API.";
return PP_ERROR_NOACCESS;
}
// TODO(raymes): When we remove FileSystem from the renderer, we should create
// a pending PepperFileSystemBrowserHost here with the fsid and send the
// pending host ID back to the plugin.
const std::string fsid = CreateCrxFileSystem(browser_context.get());
if (fsid.empty()) {
context->reply_msg =
PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(std::string());
return PP_ERROR_NOTSUPPORTED;
}
// Grant readonly access of isolated filesystem to renderer process.
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
policy->GrantReadFileSystem(render_process_id_, fsid);
context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid);
return PP_OK;
#else
return PP_ERROR_NOTSUPPORTED;
#endif
}
int32_t PepperIsolatedFileSystemMessageFilter::OpenPluginPrivateFileSystem(
ppapi::host::HostMessageContext* context) {
DCHECK(ppapi_host_);
// Only plugins with private permission can open the filesystem.
if (!ppapi_host_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
return PP_ERROR_NOACCESS;
const std::string& root_name = ppapi::IsolatedFileSystemTypeToRootName(
PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE);
const std::string& fsid =
storage::IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
storage::kFileSystemTypePluginPrivate, root_name, base::FilePath());
// Grant full access of isolated filesystem to renderer process.
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
policy->GrantCreateReadWriteFileSystem(render_process_id_, fsid);
context->reply_msg = PpapiPluginMsg_IsolatedFileSystem_BrowserOpenReply(fsid);
return PP_OK;
}

View File

@ -0,0 +1,76 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_
#define CEF_LIBCEF_BROWSER_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_
#include <set>
#include <string>
#include "base/files/file_path.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/private/ppb_isolated_file_system_private.h"
#include "ppapi/host/resource_host.h"
#include "ppapi/host/resource_message_filter.h"
#include "url/gurl.h"
namespace content {
class BrowserContext;
class BrowserPpapiHost;
}
namespace ppapi {
namespace host {
struct HostMessageContext;
} // namespace host
} // namespace ppapi
class PepperIsolatedFileSystemMessageFilter
: public ppapi::host::ResourceMessageFilter {
public:
static PepperIsolatedFileSystemMessageFilter* Create(
PP_Instance instance,
content::BrowserPpapiHost* host);
// ppapi::host::ResourceMessageFilter implementation.
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
const IPC::Message& msg) override;
int32_t OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) override;
private:
PepperIsolatedFileSystemMessageFilter(int render_process_id,
const base::FilePath& profile_directory,
const GURL& document_url,
ppapi::host::PpapiHost* ppapi_host_);
~PepperIsolatedFileSystemMessageFilter() override;
// Returns filesystem id of isolated filesystem if valid, or empty string
// otherwise. This must run on the UI thread because ProfileManager only
// allows access on that thread.
std::string CreateCrxFileSystem(content::BrowserContext* profile);
int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context,
PP_IsolatedFileSystemType_Private type);
int32_t OpenCrxFileSystem(ppapi::host::HostMessageContext* context);
int32_t OpenPluginPrivateFileSystem(ppapi::host::HostMessageContext* context);
const int render_process_id_;
// Keep a copy from original thread.
const base::FilePath profile_directory_;
const GURL document_url_;
// Not owned by this object.
ppapi::host::PpapiHost* ppapi_host_;
// Set of origins that can use CrxFs private APIs from NaCl.
std::set<std::string> allowed_crxfs_origins_;
DISALLOW_COPY_AND_ASSIGN(PepperIsolatedFileSystemMessageFilter);
};
#endif // CEF_LIBCEF_BROWSER_PEPPER_PEPPER_ISOLATED_FILE_SYSTEM_MESSAGE_FILTER_H_

View File

@ -230,6 +230,20 @@ IPC_SYNC_MESSAGE_CONTROL4_1(CefViewHostMsg_GetPluginInfo,
std::string /* mime_type */,
CefViewHostMsg_GetPluginInfo_Output /* output */)
// Returns whether any internal plugin supporting |mime_type| is registered and
// enabled. Does not determine whether the plugin can actually be instantiated
// (e.g. whether it has all its dependencies).
// When the returned *|is_available| is true, |additional_param_names| and
// |additional_param_values| contain the name-value pairs, if any, specified
// for the *first* non-disabled plugin found that is registered for |mime_type|.
// Based on ChromeViewHostMsg_IsInternalPluginAvailableForMimeType.
IPC_SYNC_MESSAGE_CONTROL1_3(
CefViewHostMsg_IsInternalPluginAvailableForMimeType,
std::string /* mime_type */,
bool /* is_available */,
std::vector<base::string16> /* additional_param_names */,
std::vector<base::string16> /* additional_param_values */)
// Sent when a frame is identified for the first time.
IPC_MESSAGE_ROUTED3(CefHostMsg_FrameIdentified,
int64 /* frame_id */,

View File

@ -107,4 +107,13 @@ const char kDisablePdfExtension[] = "disable-pdf-extension";
// upcoming version of Chromium.
const char kEnableNPAPI[] = "enable-npapi";
// 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";
} // namespace switches

View File

@ -45,6 +45,9 @@ extern const char kEnableSystemFlash[];
extern const char kDisableScrollBounce[];
extern const char kDisablePdfExtension[];
extern const char kEnableNPAPI[];
extern const char kEnableWidevineCdm[];
extern const char kWidevineCdmPath[];
extern const char kWidevineCdmVersion[];
} // namespace switches

View File

@ -34,6 +34,14 @@
#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"
#endif
namespace {
CefContentClient* g_content_client = NULL;
@ -171,6 +179,68 @@ 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.
std::vector<std::string> codecs;
codecs.push_back(kCdmSupportedCodecVorbis);
codecs.push_back(kCdmSupportedCodecVp8);
codecs.push_back(kCdmSupportedCodecVp9);
#if defined(USE_PROPRIETARY_CODECS)
codecs.push_back(kCdmSupportedCodecAac);
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";
@ -197,6 +267,7 @@ void CefContentClient::AddPepperPlugins(
std::vector<content::PepperPluginInfo>* plugins) {
ComputeBuiltInPlugins(plugins);
AddPepperFlashFromCommandLine(plugins);
AddWidevineCdmFromCommandLine(plugins);
content::PepperPluginInfo plugin;
if (GetSystemPepperFlash(&plugin))

View File

@ -26,6 +26,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/widevine_cdm_constants.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
@ -36,6 +37,8 @@
#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)
@ -525,6 +528,18 @@ void CefMainDelegate::PreSandboxStartup() {
user_data_path.AppendASCII("Dictionaries"),
false, // May not be an absolute path.
true); // Create if necessary.
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
const base::FilePath& widevine_plugin_path = GetResourcesFilePath();
PathService::Override(chrome::FILE_WIDEVINE_CDM_ADAPTER,
widevine_plugin_path.AppendASCII(
kWidevineCdmAdapterFileName));
#if defined(WIDEVINE_CDM_IS_COMPONENT)
PathService::Override(chrome::DIR_COMPONENT_WIDEVINE_CDM,
user_data_path.Append(kWidevineCdmBaseDirectory));
#endif // defined(WIDEVINE_CDM_IS_COMPONENT)
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
}
if (command_line->HasSwitch(switches::kDisablePackLoading))

View File

@ -17,6 +17,7 @@
#include "libcef/renderer/extensions/extensions_dispatcher_delegate.h"
#include "libcef/renderer/extensions/extensions_renderer_client.h"
#include "libcef/renderer/extensions/print_web_view_helper_delegate.h"
#include "libcef/renderer/media/cef_key_systems.h"
#include "libcef/renderer/pepper/pepper_helper.h"
#include "libcef/renderer/render_frame_observer.h"
#include "libcef/renderer/render_message_filter.h"
@ -649,6 +650,11 @@ CefContentRendererClient::CreateBrowserPluginDelegate(
}
}
void CefContentRendererClient::AddKeySystems(
std::vector<media::KeySystemInfo>* key_systems) {
AddCefKeySystems(key_systems);
}
void CefContentRendererClient::WillDestroyCurrentMessageLoop() {
base::AutoLock lock_scope(single_process_cleanup_lock_);
single_process_cleanup_complete_ = true;

View File

@ -108,6 +108,7 @@ class CefContentRendererClient : public content::ContentRendererClient,
content::RenderFrame* render_frame,
const std::string& mime_type,
const GURL& original_url) override;
void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
// MessageLoop::DestructionObserver implementation.
void WillDestroyCurrentMessageLoop() override;

View File

@ -0,0 +1,141 @@
// 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/renderer/media/cef_key_systems.h"
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "components/cdm/renderer/widevine_key_systems.h"
#include "content/public/renderer/render_thread.h"
#include "libcef/common/cef_messages.h"
#include "media/base/eme_constants.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(WIDEVINE_CDM_MIN_GLIBC_VERSION)
#include <gnu/libc-version.h>
#include "base/version.h"
#endif
using media::KeySystemInfo;
using media::SupportedCodecs;
#if defined(ENABLE_PEPPER_CDMS)
static bool IsPepperCdmAvailable(
const std::string& pepper_type,
std::vector<base::string16>* additional_param_names,
std::vector<base::string16>* additional_param_values) {
bool is_available = false;
content::RenderThread::Get()->Send(
new CefViewHostMsg_IsInternalPluginAvailableForMimeType(
pepper_type,
&is_available,
additional_param_names,
additional_param_values));
return is_available;
}
#if defined(WIDEVINE_CDM_AVAILABLE)
// This function finds "codecs" and parses the value into the vector |codecs|.
// Converts the codec strings to UTF-8 since we only expect ASCII strings and
// this simplifies the rest of the code in this file.
void GetSupportedCodecsForPepperCdm(
const std::vector<base::string16>& additional_param_names,
const std::vector<base::string16>& additional_param_values,
std::vector<std::string>* codecs) {
DCHECK(codecs->empty());
DCHECK_EQ(additional_param_names.size(), additional_param_values.size());
for (size_t i = 0; i < additional_param_names.size(); ++i) {
if (additional_param_names[i] ==
base::ASCIIToUTF16(kCdmSupportedCodecsParamName)) {
const base::string16& codecs_string16 = additional_param_values[i];
std::string codecs_string;
if (!base::UTF16ToUTF8(codecs_string16.c_str(),
codecs_string16.length(),
&codecs_string)) {
DLOG(WARNING) << "Non-UTF-8 codecs string.";
// Continue using the best effort conversion.
}
*codecs = base::SplitString(
codecs_string, std::string(1, kCdmSupportedCodecsValueDelimiter),
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
break;
}
}
}
static void AddPepperBasedWidevine(
std::vector<KeySystemInfo>* concrete_key_systems) {
#if defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
Version glibc_version(gnu_get_libc_version());
DCHECK(glibc_version.IsValid());
if (glibc_version.IsOlderThan(WIDEVINE_CDM_MIN_GLIBC_VERSION))
return;
#endif // defined(WIDEVINE_CDM_MIN_GLIBC_VERSION)
std::vector<base::string16> additional_param_names;
std::vector<base::string16> additional_param_values;
if (!IsPepperCdmAvailable(kWidevineCdmPluginMimeType,
&additional_param_names,
&additional_param_values)) {
DVLOG(1) << "Widevine CDM is not currently available.";
return;
}
std::vector<std::string> codecs;
GetSupportedCodecsForPepperCdm(additional_param_names,
additional_param_values,
&codecs);
SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
// Audio codecs are always supported.
// TODO(sandersd): Distinguish these from those that are directly supported,
// as those may offer a higher level of protection.
supported_codecs |= media::EME_CODEC_WEBM_OPUS;
supported_codecs |= media::EME_CODEC_WEBM_VORBIS;
#if defined(USE_PROPRIETARY_CODECS)
supported_codecs |= media::EME_CODEC_MP4_AAC;
#endif // defined(USE_PROPRIETARY_CODECS)
for (size_t i = 0; i < codecs.size(); ++i) {
if (codecs[i] == kCdmSupportedCodecVp8)
supported_codecs |= media::EME_CODEC_WEBM_VP8;
if (codecs[i] == kCdmSupportedCodecVp9)
supported_codecs |= media::EME_CODEC_WEBM_VP9;
#if defined(USE_PROPRIETARY_CODECS)
if (codecs[i] == kCdmSupportedCodecAvc1)
supported_codecs |= media::EME_CODEC_MP4_AVC1;
#endif // defined(USE_PROPRIETARY_CODECS)
}
cdm::AddWidevineWithCodecs(
cdm::WIDEVINE, supported_codecs,
media::EmeRobustness::SW_SECURE_CRYPTO, // Maximum audio robustness.
media::EmeRobustness::SW_SECURE_DECODE, // Maximum video robustness.
media::EmeSessionTypeSupport::NOT_SUPPORTED, // persistent-license.
media::EmeSessionTypeSupport::
NOT_SUPPORTED, // persistent-release-message.
media::EmeFeatureSupport::REQUESTABLE, // Persistent state.
media::EmeFeatureSupport::NOT_SUPPORTED, // Distinctive identifier.
concrete_key_systems);
}
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#endif // defined(ENABLE_PEPPER_CDMS)
void AddCefKeySystems(std::vector<KeySystemInfo>* key_systems_info) {
#if defined(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_AVAILABLE)
AddPepperBasedWidevine(key_systems_info);
#endif // defined(WIDEVINE_CDM_AVAILABLE)
#endif // defined(ENABLE_PEPPER_CDMS)
}

View File

@ -0,0 +1,14 @@
// 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.
#ifndef CEF_LIBCEF_RENDERER_MEDIA_CEF_KEY_SYSTEMS_H_
#define CEF_LIBCEF_RENDERER_MEDIA_CEF_KEY_SYSTEMS_H_
#include <vector>
#include "media/base/key_system_info.h"
void AddCefKeySystems(std::vector<media::KeySystemInfo>* key_systems_info);
#endif // CEF_LIBCEF_RENDERER_MEDIA_CEF_KEY_SYSTEMS_H_

View File

@ -423,6 +423,7 @@ if platform == 'windows':
'libGLESv2.dll',
'natives_blob.bin',
'snapshot_blob.bin',
'widevinecdmadapter.dll',
]
if not options.x64build:
binaries.append('wow_helper.exe')