widevine: Use component updater with the Alloy runtime (fixes issue #3149)

Widevine CDM binaries will be downloaded on supported platforms shortly after
application startup. Widevine support will then become available within a few
seconds after successful installation on Windows or after the next application
restart on other platforms. The CDM files will be downloaded to a "WidevineCdm"
directory inside the `CefSettings.user_data_path` directory.

Pass the `--disable-component-update` command-line flag to disable Widevine
download and installation. Pass the `--component-updater=fast-update` command-
line flag to force Widevine download immediately after application startup.

See the related issue for additional usage details.
This commit is contained in:
Marshall Greenblatt
2021-08-09 17:18:43 -04:00
parent eaf581e544
commit 240b869db5
45 changed files with 201 additions and 1459 deletions

View File

@ -758,8 +758,6 @@ static_library("libcef_static") {
"libcef/common/values_impl.h", "libcef/common/values_impl.h",
"libcef/common/waitable_event_impl.cc", "libcef/common/waitable_event_impl.cc",
"libcef/common/waitable_event_impl.h", "libcef/common/waitable_event_impl.h",
"libcef/common/widevine_loader.cc",
"libcef/common/widevine_loader.h",
"libcef/features/runtime.h", "libcef/features/runtime.h",
"libcef/features/runtime_checks.h", "libcef/features/runtime_checks.h",
"libcef/renderer/alloy/alloy_content_renderer_client.cc", "libcef/renderer/alloy/alloy_content_renderer_client.cc",
@ -850,6 +848,7 @@ static_library("libcef_static") {
"//chrome/services/printing:lib", "//chrome/services/printing:lib",
"//components/cdm/renderer", "//components/cdm/renderer",
"//components/certificate_transparency", "//components/certificate_transparency",
"//components/component_updater",
"//components/content_settings/core/browser", "//components/content_settings/core/browser",
"//components/content_settings/core/common", "//components/content_settings/core/common",
"//components/crx_file", "//components/crx_file",

View File

@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for # by hand. See the translator.README.txt file in the tools directory for
# more information. # more information.
# #
# $hash=d723a9f6637cec523b158a6750d3a64698b407c3$ # $hash=f6950d026a9c92fbb58da3fe0cbcf0050c12ecf0$
# #
{ {
@ -374,8 +374,6 @@
'libcef_dll/cpptoc/process_message_cpptoc.h', 'libcef_dll/cpptoc/process_message_cpptoc.h',
'libcef_dll/ctocpp/read_handler_ctocpp.cc', 'libcef_dll/ctocpp/read_handler_ctocpp.cc',
'libcef_dll/ctocpp/read_handler_ctocpp.h', 'libcef_dll/ctocpp/read_handler_ctocpp.h',
'libcef_dll/ctocpp/register_cdm_callback_ctocpp.cc',
'libcef_dll/ctocpp/register_cdm_callback_ctocpp.h',
'libcef_dll/cpptoc/registration_cpptoc.cc', 'libcef_dll/cpptoc/registration_cpptoc.cc',
'libcef_dll/cpptoc/registration_cpptoc.h', 'libcef_dll/cpptoc/registration_cpptoc.h',
'libcef_dll/ctocpp/render_handler_ctocpp.cc', 'libcef_dll/ctocpp/render_handler_ctocpp.cc',
@ -686,8 +684,6 @@
'libcef_dll/ctocpp/process_message_ctocpp.h', 'libcef_dll/ctocpp/process_message_ctocpp.h',
'libcef_dll/cpptoc/read_handler_cpptoc.cc', 'libcef_dll/cpptoc/read_handler_cpptoc.cc',
'libcef_dll/cpptoc/read_handler_cpptoc.h', 'libcef_dll/cpptoc/read_handler_cpptoc.h',
'libcef_dll/cpptoc/register_cdm_callback_cpptoc.cc',
'libcef_dll/cpptoc/register_cdm_callback_cpptoc.h',
'libcef_dll/ctocpp/registration_ctocpp.cc', 'libcef_dll/ctocpp/registration_ctocpp.cc',
'libcef_dll/ctocpp/registration_ctocpp.h', 'libcef_dll/ctocpp/registration_ctocpp.h',
'libcef_dll/cpptoc/render_handler_cpptoc.cc', 'libcef_dll/cpptoc/render_handler_cpptoc.cc',

View File

@ -230,8 +230,6 @@
'tests/cefclient/browser/client_types.h', 'tests/cefclient/browser/client_types.h',
'tests/cefclient/browser/dialog_test.cc', 'tests/cefclient/browser/dialog_test.cc',
'tests/cefclient/browser/dialog_test.h', 'tests/cefclient/browser/dialog_test.h',
'tests/cefclient/browser/drm_test.cc',
'tests/cefclient/browser/drm_test.h',
'tests/cefclient/browser/image_cache.cc', 'tests/cefclient/browser/image_cache.cc',
'tests/cefclient/browser/image_cache.h', 'tests/cefclient/browser/image_cache.h',
'tests/cefclient/browser/main_context.cc', 'tests/cefclient/browser/main_context.cc',
@ -296,7 +294,6 @@
'tests/cefclient/resources/binding.html', 'tests/cefclient/resources/binding.html',
'tests/cefclient/resources/dialogs.html', 'tests/cefclient/resources/dialogs.html',
'tests/cefclient/resources/draggable.html', 'tests/cefclient/resources/draggable.html',
'tests/cefclient/resources/drm.html',
'tests/cefclient/resources/localstorage.html', 'tests/cefclient/resources/localstorage.html',
'tests/cefclient/resources/logo.png', 'tests/cefclient/resources/logo.png',
'tests/cefclient/resources/media_router.html', 'tests/cefclient/resources/media_router.html',

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=f74bf4d33914d56d760f1bf5aadcf2651740c711$ // $hash=f51ad9ffc67d94b9cbfad154e7f224111c2a96fa$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_WEB_PLUGIN_CAPI_H_ #ifndef CEF_INCLUDE_CAPI_CEF_WEB_PLUGIN_CAPI_H_
@ -129,29 +129,6 @@ typedef struct _cef_web_plugin_unstable_callback_t {
int unstable); int unstable);
} cef_web_plugin_unstable_callback_t; } cef_web_plugin_unstable_callback_t;
///
// Implement this structure to receive notification when CDM registration is
// complete. The functions of this structure will be called on the browser
// process UI thread.
///
typedef struct _cef_register_cdm_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Method that will be called when CDM registration is complete. |result| will
// be CEF_CDM_REGISTRATION_ERROR_NONE if registration completed successfully.
// Otherwise, |result| and |error_message| will contain additional information
// about why registration failed.
///
void(CEF_CALLBACK* on_cdm_registration_complete)(
struct _cef_register_cdm_callback_t* self,
cef_cdm_registration_error_t result,
const cef_string_t* error_message);
} cef_register_cdm_callback_t;
/// ///
// Visit web plugin information. Can be called on any thread in the browser // Visit web plugin information. Can be called on any thread in the browser
// process. // process.
@ -187,52 +164,6 @@ CEF_EXPORT void cef_is_web_plugin_unstable(
const cef_string_t* path, const cef_string_t* path,
cef_web_plugin_unstable_callback_t* callback); cef_web_plugin_unstable_callback_t* callback);
///
// Register the Widevine CDM plugin.
//
// The client application is responsible for downloading an appropriate
// platform-specific CDM binary distribution from Google, extracting the
// contents, and building the required directory structure on the local machine.
// The cef_browser_host_t::StartDownload function and CefZipArchive structure
// can be used to implement this functionality in CEF. Contact Google via
// https://www.widevine.com/contact.html for details on CDM download.
//
// |path| is a directory that must contain the following files:
// 1. manifest.json file from the CDM binary distribution (see below).
// 2. widevinecdm file from the CDM binary distribution (e.g.
// widevinecdm.dll on on Windows, libwidevinecdm.dylib on OS X,
// libwidevinecdm.so on Linux).
//
// If any of these files are missing or if the manifest file has incorrect
// contents the registration will fail and |callback| will receive a |result|
// value of CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS.
//
// The manifest.json file must contain the following keys:
// A. "os": Supported OS (e.g. "mac", "win" or "linux").
// B. "arch": Supported architecture (e.g. "ia32" or "x64").
// C. "x-cdm-module-versions": Module API version (e.g. "4").
// D. "x-cdm-interface-versions": Interface API version (e.g. "8").
// E. "x-cdm-host-versions": Host API version (e.g. "8").
// F. "version": CDM version (e.g. "1.4.8.903").
// G. "x-cdm-codecs": List of supported codecs (e.g. "vp8,vp09,avc1").
//
// A through E are used to verify compatibility with the current Chromium
// version. If the CDM is not compatible the registration will fail and
// |callback| will receive a |result| value of
// CEF_CDM_REGISTRATION_ERROR_INCOMPATIBLE.
//
// |callback| will be executed asynchronously once registration is complete.
//
// On Linux this function must be called before cef_initialize() and the
// registration cannot be changed during runtime. If registration is not
// supported at the time that cef_register_widevine_cdm() is called then
// |callback| will receive a |result| value of
// CEF_CDM_REGISTRATION_ERROR_NOT_SUPPORTED.
///
CEF_EXPORT void cef_register_widevine_cdm(
const cef_string_t* path,
cef_register_cdm_callback_t* callback);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal // way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash // hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected. // values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "6498b029e847331e85f7fa7a8fe82434e016e316" #define CEF_API_HASH_UNIVERSAL "5625e3ce80d2bbf5b5a39f8655d96c215f7685ee"
#if defined(OS_WIN) #if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "5beb166d25cb4aa70e15ff565a0268c60cab3e0c" #define CEF_API_HASH_PLATFORM "c20e4ffc24e6267b61774f49237d0f30a581f370"
#elif defined(OS_MAC) #elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "5fa684079bfafa70cc920a1ad4e694e38c46d737" #define CEF_API_HASH_PLATFORM "65731bc654ec6e1dbd48d6ff2336c4c8573f7d35"
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "1e0cc77dabf9058f0fc118b4605fbcccda14466f" #define CEF_API_HASH_PLATFORM "4e35b9cc9735c63ac9f16fbbb49a4b8e2307f23a"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -145,68 +145,4 @@ class CefWebPluginUnstableCallback : public virtual CefBaseRefCounted {
void CefIsWebPluginUnstable(const CefString& path, void CefIsWebPluginUnstable(const CefString& path,
CefRefPtr<CefWebPluginUnstableCallback> callback); CefRefPtr<CefWebPluginUnstableCallback> callback);
///
// Implement this interface to receive notification when CDM registration is
// complete. The methods of this class will be called on the browser process
// UI thread.
///
/*--cef(source=client)--*/
class CefRegisterCdmCallback : public virtual CefBaseRefCounted {
public:
///
// Method that will be called when CDM registration is complete. |result|
// will be CEF_CDM_REGISTRATION_ERROR_NONE if registration completed
// successfully. Otherwise, |result| and |error_message| will contain
// additional information about why registration failed.
///
/*--cef(optional_param=error_message)--*/
virtual void OnCdmRegistrationComplete(cef_cdm_registration_error_t result,
const CefString& error_message) = 0;
};
///
// Register the Widevine CDM plugin.
//
// The client application is responsible for downloading an appropriate
// platform-specific CDM binary distribution from Google, extracting the
// contents, and building the required directory structure on the local machine.
// The CefBrowserHost::StartDownload method and CefZipArchive class can be used
// to implement this functionality in CEF. Contact Google via
// https://www.widevine.com/contact.html for details on CDM download.
//
// |path| is a directory that must contain the following files:
// 1. manifest.json file from the CDM binary distribution (see below).
// 2. widevinecdm file from the CDM binary distribution (e.g.
// widevinecdm.dll on on Windows, libwidevinecdm.dylib on OS X,
// libwidevinecdm.so on Linux).
//
// If any of these files are missing or if the manifest file has incorrect
// contents the registration will fail and |callback| will receive a |result|
// value of CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS.
//
// The manifest.json file must contain the following keys:
// A. "os": Supported OS (e.g. "mac", "win" or "linux").
// B. "arch": Supported architecture (e.g. "ia32" or "x64").
// C. "x-cdm-module-versions": Module API version (e.g. "4").
// D. "x-cdm-interface-versions": Interface API version (e.g. "8").
// E. "x-cdm-host-versions": Host API version (e.g. "8").
// F. "version": CDM version (e.g. "1.4.8.903").
// G. "x-cdm-codecs": List of supported codecs (e.g. "vp8,vp09,avc1").
//
// A through E are used to verify compatibility with the current Chromium
// version. If the CDM is not compatible the registration will fail and
// |callback| will receive a |result| value of
// CEF_CDM_REGISTRATION_ERROR_INCOMPATIBLE.
//
// |callback| will be executed asynchronously once registration is complete.
//
// On Linux this function must be called before CefInitialize() and the
// registration cannot be changed during runtime. If registration is not
// supported at the time that CefRegisterWidevineCdm() is called then |callback|
// will receive a |result| value of CEF_CDM_REGISTRATION_ERROR_NOT_SUPPORTED.
///
/*--cef(optional_param=callback)--*/
void CefRegisterWidevineCdm(const CefString& path,
CefRefPtr<CefRegisterCdmCallback> callback);
#endif // CEF_INCLUDE_CEF_WEB_PLUGIN_H_ #endif // CEF_INCLUDE_CEF_WEB_PLUGIN_H_

View File

@ -264,10 +264,10 @@ typedef struct _cef_settings_t {
// be stored on disk. If this value is empty then the default // be stored on disk. If this value is empty then the default
// platform-specific user data directory will be used ("~/.cef_user_data" // platform-specific user data directory will be used ("~/.cef_user_data"
// directory on Linux, "~/Library/Application Support/CEF/User Data" directory // directory on Linux, "~/Library/Application Support/CEF/User Data" directory
// on Mac OS X, "Local Settings\Application Data\CEF\User Data" directory // on Mac OS X, "AppData\Local\CEF\User Data" directory under the user profile
// under the user profile directory on Windows). If this value is non-empty // directory on Windows). If this value is non-empty then it must be an
// then it must be an absolute path. When using the Chrome runtime this value // absolute path. When using the Chrome runtime this value will be ignored in
// will be ignored in favor of the |root_cache_path| value. // favor of the |root_cache_path| value.
/// ///
cef_string_t user_data_path; cef_string_t user_data_path;
@ -2948,31 +2948,6 @@ typedef enum {
CEF_SCHEME_OPTION_FETCH_ENABLED = 1 << 6, CEF_SCHEME_OPTION_FETCH_ENABLED = 1 << 6,
} cef_scheme_options_t; } cef_scheme_options_t;
///
// Error codes for CDM registration. See cef_web_plugin.h for details.
///
typedef enum {
///
// No error. Registration completed successfully.
///
CEF_CDM_REGISTRATION_ERROR_NONE,
///
// Required files or manifest contents are missing.
///
CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS,
///
// The CDM is incompatible with the current Chromium version.
///
CEF_CDM_REGISTRATION_ERROR_INCOMPATIBLE,
///
// CDM registration is not supported at this time.
///
CEF_CDM_REGISTRATION_ERROR_NOT_SUPPORTED,
} cef_cdm_registration_error_t;
/// ///
// Composition underline style. // Composition underline style.
/// ///

View File

@ -30,6 +30,7 @@
#include "chrome/browser/media/router/chrome_media_router_factory.h" #include "chrome/browser/media/router/chrome_media_router_factory.h"
#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/common/chrome_switches.h"
#include "components/constrained_window/constrained_window_views.h" #include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/gpu_data_manager.h" #include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
@ -37,6 +38,7 @@
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "net/base/net_module.h" #include "net/base/net_module.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#if defined(USE_AURA) && defined(USE_X11) #if defined(USE_AURA) && defined(USE_X11)
@ -73,6 +75,14 @@
#include "libcef/browser/printing/print_dialog_linux.h" #include "libcef/browser/printing/print_dialog_linux.h"
#endif #endif
#if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM)
#include "chrome/browser/component_updater/media_foundation_widevine_cdm_component_installer.h"
#endif
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
#include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
#endif
AlloyBrowserMainParts::AlloyBrowserMainParts( AlloyBrowserMainParts::AlloyBrowserMainParts(
const content::MainFunctionParams& parameters) const content::MainFunctionParams& parameters)
: BrowserMainParts(), devtools_delegate_(nullptr) {} : BrowserMainParts(), devtools_delegate_(nullptr) {}
@ -207,6 +217,20 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() {
scheme::RegisterWebUIControllerFactory(); scheme::RegisterWebUIControllerFactory();
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kDisableComponentUpdate)) {
auto* const cus = g_browser_process->component_updater();
#if BUILDFLAG(ENABLE_MEDIA_FOUNDATION_WIDEVINE_CDM)
RegisterMediaFoundationWidevineCdmComponent(cus);
#endif
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
RegisterWidevineCdmComponent(cus);
#endif
}
return content::RESULT_CODE_NORMAL_EXIT; return content::RESULT_CODE_NORMAL_EXIT;
} }

View File

@ -8,6 +8,7 @@
#include "libcef/browser/request_context_impl.h" #include "libcef/browser/request_context_impl.h"
#include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "build/build_config.h" #include "build/build_config.h"

View File

@ -123,16 +123,11 @@
#include "third_party/blink/public/common/web_preferences/web_preferences.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/prerender/prerender.mojom.h" #include "third_party/blink/public/mojom/prerender/prerender.mojom.h"
#include "third_party/blink/public/web/web_window_features.h" #include "third_party/blink/public/web/web_window_features.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h" #include "ui/base/ui_base_switches.h"
#include "url/gurl.h" #include "url/gurl.h"
#if defined(OS_LINUX)
#include "libcef/common/widevine_loader.h"
#endif
#if defined(OS_POSIX) && !defined(OS_MAC) #if defined(OS_POSIX) && !defined(OS_MAC)
#include "base/debug/leak_annotations.h" #include "base/debug/leak_annotations.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
@ -734,18 +729,15 @@ void AlloyContentBrowserClient::AppendExtraCommandLineSwitches(
base::size(kSwitchNames)); base::size(kSwitchNames));
} }
// Necessary to populate DIR_USER_DATA in sub-processes.
// See resource_util.cc GetUserDataPath.
base::FilePath user_data_dir;
if (base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
}
#if defined(OS_LINUX) #if defined(OS_LINUX)
if (process_type == switches::kZygoteProcess) { if (process_type == switches::kZygoteProcess) {
#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
if (!browser_cmd->HasSwitch(sandbox::policy::switches::kNoSandbox)) {
// Pass the Widevine CDM path to the Zygote process. See comments in
// CefWidevineLoader::AddContentDecryptionModules.
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)) { if (browser_cmd->HasSwitch(switches::kBrowserSubprocessPath)) {
// Force use of the sub-process executable path for the zygote process. // Force use of the sub-process executable path for the zygote process.
const base::FilePath& subprocess_path = const base::FilePath& subprocess_path =

View File

@ -13,12 +13,15 @@
#include "libcef/common/cef_switches.h" #include "libcef/common/cef_switches.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/browser/component_updater/chrome_component_updater_configurator.h"
#include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h" #include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/ui/prefs/pref_watcher.h" #include "chrome/browser/ui/prefs/pref_watcher.h"
#include "components/component_updater/component_updater_service.h"
#include "components/component_updater/timer_update_scheduler.h"
#include "components/net_log/chrome_net_log.h" #include "components/net_log/chrome_net_log.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/browser/startup_helper.h" #include "content/browser/startup_helper.h"
@ -331,8 +334,23 @@ void ChromeBrowserProcessAlloy::StartAutoupdateTimer() {}
component_updater::ComponentUpdateService* component_updater::ComponentUpdateService*
ChromeBrowserProcessAlloy::component_updater() { ChromeBrowserProcessAlloy::component_updater() {
NOTREACHED(); if (component_updater_)
return component_updater_.get();
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
return nullptr; return nullptr;
}
std::unique_ptr<component_updater::UpdateScheduler> scheduler =
std::make_unique<component_updater::TimerUpdateScheduler>();
component_updater_ = component_updater::ComponentUpdateServiceFactory(
component_updater::MakeChromeComponentUpdaterConfigurator(
base::CommandLine::ForCurrentProcess(),
g_browser_process->local_state()),
std::move(scheduler));
return component_updater_.get();
} }
MediaFileSystemRegistry* MediaFileSystemRegistry*

View File

@ -119,6 +119,8 @@ class ChromeBrowserProcessAlloy : public BrowserProcess {
browser_policy_connector_; browser_policy_connector_;
std::unique_ptr<base::FieldTrialList> field_trial_list_; std::unique_ptr<base::FieldTrialList> field_trial_list_;
std::unique_ptr<component_updater::ComponentUpdateService> component_updater_;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProcessAlloy); DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProcessAlloy);
}; };

View File

@ -20,6 +20,7 @@
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/accessibility/accessibility_ui.h" #include "chrome/browser/accessibility/accessibility_ui.h"
#include "chrome/browser/component_updater/chrome_component_updater_configurator.h"
#include "chrome/browser/download/download_prefs.h" #include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/media/media_device_id_salt.h" #include "chrome/browser/media/media_device_id_salt.h"
#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/router/media_router_feature.h"
@ -230,6 +231,8 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
update_client::RegisterPrefs(registry.get()); update_client::RegisterPrefs(registry.get());
if (!profile) { if (!profile) {
component_updater::RegisterPrefsForChromeComponentUpdaterConfigurator(
registry.get());
SystemNetworkContextManager::RegisterPrefs(registry.get()); SystemNetworkContextManager::RegisterPrefs(registry.get());
#if defined(OS_WIN) #if defined(OS_WIN)
OSCrypt::RegisterLocalPrefs(registry.get()); OSCrypt::RegisterLocalPrefs(registry.get());

View File

@ -6,7 +6,6 @@
#include "libcef/browser/context.h" #include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h" #include "libcef/browser/thread_util.h"
#include "libcef/common/widevine_loader.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
@ -30,23 +29,6 @@ void PluginsCallbackImpl(
} }
} }
#if !(BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_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::BindOnce(&CefRegisterCdmCallback::OnCdmRegistrationComplete,
callback.get(), CEF_CDM_REGISTRATION_ERROR_NOT_SUPPORTED,
error_message));
}
}
#endif
} // namespace } // namespace
// CefWebPluginInfoImpl // CefWebPluginInfoImpl
@ -166,24 +148,3 @@ void CefIsWebPluginUnstable(const CefString& path,
base::BindOnce(CefIsWebPluginUnstable, path, callback)); base::BindOnce(CefIsWebPluginUnstable, path, callback));
} }
} }
void CefRegisterWidevineCdm(const CefString& path,
CefRefPtr<CefRegisterCdmCallback> callback) {
#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_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 // BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
}

View File

@ -27,6 +27,8 @@
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/media/cdm_registration.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_constants.h" #include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/public/common/pepper_plugin_info.h" #include "content/public/common/pepper_plugin_info.h"
@ -35,8 +37,8 @@
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#if defined(OS_LINUX) #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
#include "libcef/common/widevine_loader.h" #include "chrome/common/media/cdm_host_file_path.h"
#endif #endif
namespace { namespace {
@ -95,10 +97,12 @@ void AlloyContentClient::AddPepperPlugins(
void AlloyContentClient::AddContentDecryptionModules( void AlloyContentClient::AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms, std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) { std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
#if defined(OS_LINUX) if (cdms)
#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS) RegisterCdmInfo(cdms);
CefWidevineLoader::AddContentDecryptionModules(cdms, cdm_host_file_paths);
#endif #if BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION)
if (cdm_host_file_paths)
AddCdmHostFilePaths(cdm_host_file_paths);
#endif #endif
} }

View File

@ -29,6 +29,7 @@
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/utility/chrome_content_utility_client.h" #include "chrome/utility/chrome_content_utility_client.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/embedder_support/switches.h" #include "components/embedder_support/switches.h"
#include "components/viz/common/features.h" #include "components/viz/common/features.h"
@ -369,9 +370,10 @@ void AlloyMainDelegate::PreSandboxStartup() {
#endif #endif
resource_util::OverrideDefaultDownloadDir(); resource_util::OverrideDefaultDownloadDir();
resource_util::OverrideUserDataDir(settings_, command_line);
} }
resource_util::OverrideUserDataDir(settings_, command_line);
if (command_line->HasSwitch(switches::kDisablePackLoading)) if (command_line->HasSwitch(switches::kDisablePackLoading))
resource_bundle_delegate_.set_pack_loading_disabled(true); resource_bundle_delegate_.set_pack_loading_disabled(true);
@ -379,6 +381,11 @@ void AlloyMainDelegate::PreSandboxStartup() {
// chrome::DIR_CRASH_DUMPS must be configured before calling this function. // chrome::DIR_CRASH_DUMPS must be configured before calling this function.
crash_reporting::PreSandboxStartup(*command_line, process_type); crash_reporting::PreSandboxStartup(*command_line, process_type);
// Register the component_updater PathProvider.
component_updater::RegisterPathProvider(chrome::DIR_COMPONENTS,
chrome::DIR_INTERNAL_PLUGINS,
chrome::DIR_USER_DATA);
InitializeResourceBundle(); InitializeResourceBundle();
MaybeInitializeGDI(); MaybeInitializeGDI();
} }

View File

@ -7,7 +7,6 @@
#include "libcef/browser/alloy/chrome_browser_process_alloy.h" #include "libcef/browser/alloy/chrome_browser_process_alloy.h"
#include "libcef/common/alloy/alloy_main_delegate.h" #include "libcef/common/alloy/alloy_main_delegate.h"
#include "libcef/common/widevine_loader.h"
#include "libcef/renderer/alloy/alloy_content_renderer_client.h" #include "libcef/renderer/alloy/alloy_content_renderer_client.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
@ -38,10 +37,6 @@ void AlloyMainRunnerDelegate::BeforeMainThreadRun() {
} }
void AlloyMainRunnerDelegate::AfterUIThreadInitialize() { void AlloyMainRunnerDelegate::AfterUIThreadInitialize() {
#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
CefWidevineLoader::GetInstance()->OnContextInitialized();
#endif
static_cast<ChromeBrowserProcessAlloy*>(g_browser_process) static_cast<ChromeBrowserProcessAlloy*>(g_browser_process)
->OnContextInitialized(); ->OnContextInitialized();
} }

View File

@ -94,9 +94,6 @@ const char kDisableScrollBounce[] = "disable-scroll-bounce";
// Disable the PDF extension. // Disable the PDF extension.
const char kDisablePdfExtension[] = "disable-pdf-extension"; const char kDisablePdfExtension[] = "disable-pdf-extension";
// Path to Widevine CDM binaries.
const char kWidevineCdmPath[] = "widevine-cdm-path";
// Default plugin policy action. // Default plugin policy action.
const char kPluginPolicy[] = "plugin-policy"; const char kPluginPolicy[] = "plugin-policy";
// Allow the content. This is the default value. // Allow the content. This is the default value.

View File

@ -44,7 +44,6 @@ extern const char kEnableSpellingService[];
extern const char kOverrideSpellCheckLang[]; extern const char kOverrideSpellCheckLang[];
extern const char kDisableScrollBounce[]; extern const char kDisableScrollBounce[];
extern const char kDisablePdfExtension[]; extern const char kDisablePdfExtension[];
extern const char kWidevineCdmPath[];
extern const char kPluginPolicy[]; extern const char kPluginPolicy[];
extern const char kPluginPolicy_Allow[]; extern const char kPluginPolicy_Allow[];
extern const char kPluginPolicy_Detect[]; extern const char kPluginPolicy_Detect[];

View File

@ -1,513 +0,0 @@
// 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 BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_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_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/plugin_service_impl.h"
#include "content/public/browser/cdm_registry.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_switches.h"
#include "media/cdm/cdm_host_file.h"
#include "media/cdm/supported_cdm_versions.h"
#include "sandbox/policy/switches.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h" // nogncheck
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_MAC)
"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";
#elif defined(ARCH_CPU_ARM64)
"arm64";
#else
"???";
#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[] = ",";
// 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";
// Whether persistent license is supported by the CDM: "true" or "false".
const char kCdmPersistentLicenseSupportName[] =
"x-cdm-persistent-license-support";
const char kCdmSupportedEncryptionSchemesName[] =
"x-cdm-supported-encryption-schemes";
// The following strings are used to specify supported codecs in the
// parameter |kCdmCodecsListName|.
const char kCdmSupportedCodecVp8[] = "vp8";
const char kCdmSupportedCodecVp9[] = "vp09";
const char kCdmSupportedCodecAv1[] = "av01";
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char kCdmSupportedCodecAvc1[] = "avc1";
#endif
// The following strings are used to specify supported encryption schemes in
// the parameter |kCdmSupportedEncryptionSchemesName|.
const char kCdmSupportedEncryptionSchemeCenc[] = "cenc";
const char kCdmSupportedEncryptionSchemeCbcs[] = "cbcs";
// Arguments passed to MakeCdmInfo.
struct CdmInfoArgs {
base::FilePath path;
std::string version;
media::CdmCapability capability;
};
std::unique_ptr<base::DictionaryValue> ParseManifestFile(
const base::FilePath& manifest_path) {
CEF_REQUIRE_BLOCKING();
// 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(nullptr, nullptr));
if (!manifest.get() || !manifest->is_dict())
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, 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);
}
// Returns true and updates |video_codecs| if the appropriate manifest entry is
// valid. Returns false and does not modify |video_codecs| if the manifest entry
// is incorrectly formatted.
bool GetCodecs(const base::DictionaryValue& manifest,
media::CdmCapability::VideoCodecMap* video_codecs,
std::string* error_message) {
DCHECK(video_codecs);
const base::Value* value = manifest.FindKey(kCdmCodecsListName);
if (!value) {
std::stringstream ss;
ss << "Widevine CDM component manifest is missing codecs.";
*error_message = ss.str();
return true;
}
if (!value->is_string()) {
std::stringstream ss;
ss << "Manifest entry " << kCdmCodecsListName << " is not a string.";
*error_message = ss.str();
return false;
}
const std::string& codecs = value->GetString();
if (codecs.empty()) {
std::stringstream ss;
ss << "Widevine CDM component manifest has empty codecs list.";
*error_message = ss.str();
return true;
}
media::CdmCapability::VideoCodecMap result;
const std::vector<media::VideoCodecProfile> kAllProfiles = {};
const std::vector<base::StringPiece> supported_codecs =
base::SplitStringPiece(codecs, kCdmValueDelimiter, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
for (const auto& codec : supported_codecs) {
if (codec == kCdmSupportedCodecVp8)
result.emplace(media::VideoCodec::kCodecVP8, kAllProfiles);
else if (codec == kCdmSupportedCodecVp9)
result.emplace(media::VideoCodec::kCodecVP9, kAllProfiles);
else if (codec == kCdmSupportedCodecAv1)
result.emplace(media::VideoCodec::kCodecAV1, kAllProfiles);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
else if (codec == kCdmSupportedCodecAvc1)
result.emplace(media::VideoCodec::kCodecH264, kAllProfiles);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
}
video_codecs->swap(result);
return true;
}
// Returns true and updates |encryption_schemes| if the appropriate manifest
// entry is valid. Returns false and does not modify |encryption_schemes| if the
// manifest entry is incorrectly formatted. It is assumed that all CDMs support
// 'cenc', so if the manifest entry is missing, the result will indicate support
// for 'cenc' only. Incorrect types in the manifest entry will log the error and
// fail. Unrecognized values will be reported but otherwise ignored.
bool GetEncryptionSchemes(
const base::DictionaryValue& manifest,
base::flat_set<media::EncryptionScheme>* encryption_schemes,
std::string* error_message) {
DCHECK(encryption_schemes);
const base::Value* value =
manifest.FindKey(kCdmSupportedEncryptionSchemesName);
if (!value) {
// No manifest entry found, so assume only 'cenc' supported for backwards
// compatibility.
encryption_schemes->insert(media::EncryptionScheme::kCenc);
return true;
}
if (!value->is_list()) {
std::stringstream ss;
ss << "Manifest entry " << kCdmSupportedEncryptionSchemesName
<< " is not a list.";
*error_message = ss.str();
return false;
}
const base::span<const base::Value> list = value->GetList();
base::flat_set<media::EncryptionScheme> result;
for (const auto& item : list) {
if (!item.is_string()) {
std::stringstream ss;
ss << "Unrecognized item type in manifest entry "
<< kCdmSupportedEncryptionSchemesName;
*error_message = ss.str();
return false;
}
const std::string& scheme = item.GetString();
if (scheme == kCdmSupportedEncryptionSchemeCenc) {
result.insert(media::EncryptionScheme::kCenc);
} else if (scheme == kCdmSupportedEncryptionSchemeCbcs) {
result.insert(media::EncryptionScheme::kCbcs);
} else {
std::stringstream ss;
ss << "Unrecognized encryption scheme " << scheme << " in manifest entry "
<< kCdmSupportedEncryptionSchemesName;
*error_message = ss.str();
}
}
// As the manifest entry exists, it must specify at least one valid value.
if (result.empty())
return false;
encryption_schemes->swap(result);
return true;
}
// Returns true and updates |session_types| if the appropriate manifest entry is
// valid. Returns false if the manifest entry is incorrectly formatted.
bool GetSessionTypes(const base::DictionaryValue& manifest,
base::flat_set<media::CdmSessionType>* session_types,
std::string* error_message) {
DCHECK(session_types);
bool is_persistent_license_supported = false;
const base::Value* value = manifest.FindKey(kCdmPersistentLicenseSupportName);
if (value) {
if (!value->is_bool())
return false;
is_persistent_license_supported = value->GetBool();
}
// Temporary session is always supported.
session_types->insert(media::CdmSessionType::kTemporary);
if (is_persistent_license_supported)
session_types->insert(media::CdmSessionType::kPersistentLicense);
return true;
}
// Verify and load the contents of |base_path|.
cef_cdm_registration_error_t LoadWidevineCdmInfo(
const base::FilePath& base_path,
CdmInfoArgs* args,
std::string* error_message) {
std::stringstream ss;
args->path = base_path.AppendASCII(
base::GetNativeLibraryName(kWidevineCdmLibraryName));
if (!base::PathExists(args->path)) {
ss << "Missing file " << args->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;
args->version = GetManifestValue(*manifest, kCdmVersionName, error_message);
if (args->version.empty())
return CEF_CDM_REGISTRATION_ERROR_INCORRECT_CONTENTS;
if (!GetCodecs(*manifest, &args->capability.video_codecs, error_message) ||
!GetEncryptionSchemes(*manifest, &args->capability.encryption_schemes,
error_message) ||
!GetSessionTypes(*manifest, &args->capability.session_types,
error_message)) {
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;
else if (!error_message.empty())
LOG(WARNING) << "Widevine CDM registration warning; " << error_message;
if (callback)
callback->OnCdmRegistrationComplete(result, error_message);
}
content::CdmInfo MakeCdmInfo(const CdmInfoArgs& args) {
return content::CdmInfo(
kWidevineKeySystem, content::CdmInfo::Robustness::kSoftwareSecure,
std::move(args.capability), /*supports_sub_key_systems=*/false,
kWidevineCdmDisplayName, kWidevineCdmGuid, base::Version(args.version),
args.path, kWidevineCdmFileSystemId);
}
void RegisterWidevineCdmOnUIThread(std::unique_ptr<CdmInfoArgs> args,
CefRefPtr<CefRegisterCdmCallback> callback) {
CEF_REQUIRE_UIT();
// Register Widevine with the CdmRegistry.
content::CdmRegistry::GetInstance()->RegisterCdm(MakeCdmInfo(*args));
DeliverWidevineCdmCallback(CEF_CDM_REGISTRATION_ERROR_NONE, std::string(),
callback);
}
void LoadWidevineCdmInfoOnBlockingThread(
const base::FilePath& base_path,
CefRefPtr<CefRegisterCdmCallback> callback) {
CEF_REQUIRE_BLOCKING();
std::unique_ptr<CdmInfoArgs> args = std::make_unique<CdmInfoArgs>();
std::string error_message;
cef_cdm_registration_error_t result =
LoadWidevineCdmInfo(base_path, args.get(), &error_message);
if (result != CEF_CDM_REGISTRATION_ERROR_NONE) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(DeliverWidevineCdmCallback, result,
error_message, callback));
return;
}
// Continue execution on the UI thread.
CEF_POST_TASK(CEF_UIT, base::BindOnce(RegisterWidevineCdmOnUIThread,
std::move(args), 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;
}
CEF_POST_USER_VISIBLE_TASK(
base::BindOnce(LoadWidevineCdmInfoOnBlockingThread, 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::AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths) {
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(sandbox::policy::switches::kNoSandbox)) {
return;
}
// The Widevine CDM path is passed to the zygote process via
// AlloyContentBrowserClient::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.
CdmInfoArgs args;
std::string error_message;
cef_cdm_registration_error_t result =
LoadWidevineCdmInfo(base_path, &args, &error_message);
if (result != CEF_CDM_REGISTRATION_ERROR_NONE) {
LOG(ERROR) << "Widevine CDM registration failed; " << error_message;
return;
}
cdms->push_back(MakeCdmInfo(args));
}
#endif // defined(OS_LINUX)
CefWidevineLoader::CefWidevineLoader() {}
CefWidevineLoader::~CefWidevineLoader() {}
#endif // BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)

View File

@ -1,70 +0,0 @@
// 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 "media/media_buildflags.h"
#include "third_party/widevine/cdm/buildflags.h"
#if BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include <vector>
#include "include/cef_web_plugin.h"
#include "base/lazy_instance.h"
namespace content {
struct CdmInfo;
}
namespace media {
struct CdmHostFilePath;
}
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 CDM modules. Other processes will receive
// load notification in the usual way.
// Called from AlloyContentClient::AddContentDecryptionModules.
static void AddContentDecryptionModules(
std::vector<content::CdmInfo>* cdms,
std::vector<media::CdmHostFilePath>* cdm_host_file_paths);
const base::FilePath& path() { return path_; }
#endif
private:
friend struct base::LazyInstanceTraitsBase<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 // BUILDFLAG(ENABLE_WIDEVINE) && BUILDFLAG(ENABLE_LIBRARY_CDMS)
#endif // CEF_LIBCEF_COMMON_WIDEVINE_LOADER_H_

View File

@ -53,7 +53,6 @@
#include "chrome/renderer/chrome_content_renderer_client.h" #include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/extensions/chrome_extensions_renderer_client.h" #include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
#include "chrome/renderer/loadtimes_extension_bindings.h" #include "chrome/renderer/loadtimes_extension_bindings.h"
#include "chrome/renderer/media/chrome_key_systems.h"
#include "chrome/renderer/pepper/chrome_pdf_print_client.h" #include "chrome/renderer/pepper/chrome_pdf_print_client.h"
#include "chrome/renderer/pepper/pepper_helper.h" #include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" #include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
@ -412,7 +411,11 @@ bool AlloyContentRendererClient::IsOriginIsolatedPepperPlugin(
void AlloyContentRendererClient::AddSupportedKeySystems( void AlloyContentRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) { std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) {
AddChromeKeySystems(key_systems); key_systems_provider_.AddSupportedKeySystems(key_systems);
}
bool AlloyContentRendererClient::IsKeySystemsUpdateNeeded() {
return key_systems_provider_.IsKeySystemsUpdateNeeded();
} }
void AlloyContentRendererClient::RunScriptsAtDocumentStart( void AlloyContentRendererClient::RunScriptsAtDocumentStart(

View File

@ -19,6 +19,7 @@
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/task/current_thread.h" #include "base/task/current_thread.h"
#include "chrome/common/plugin.mojom.h" #include "chrome/common/plugin.mojom.h"
#include "chrome/renderer/media/chrome_key_systems_provider.h"
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_thread.h"
#include "mojo/public/cpp/bindings/generic_pending_receiver.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
@ -99,6 +100,7 @@ class AlloyContentRendererClient
void AddSupportedKeySystems( void AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems) std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
override; override;
bool IsKeySystemsUpdateNeeded() override;
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame) override;
@ -140,6 +142,10 @@ class AlloyContentRendererClient
std::unique_ptr<extensions::CefExtensionsRendererClient> std::unique_ptr<extensions::CefExtensionsRendererClient>
extensions_renderer_client_; extensions_renderer_client_;
// Used to refresh the list of supported key systems after Widevine is
// installed as a component update.
ChromeKeySystemsProvider key_systems_provider_;
// Used in single-process mode to test when cleanup is complete. // Used in single-process mode to test when cleanup is complete.
// Access must be protected by |single_process_cleanup_lock_|. // Access must be protected by |single_process_cleanup_lock_|.
bool single_process_cleanup_complete_ = false; bool single_process_cleanup_complete_ = false;

View File

@ -1,70 +0,0 @@
// Copyright (c) 2021 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=5f7db6dda8ac868e8ec94b93e3ae7d2dd7d0cf64$
//
#include "libcef_dll/cpptoc/register_cdm_callback_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK register_cdm_callback_on_cdm_registration_complete(
struct _cef_register_cdm_callback_t* self,
cef_cdm_registration_error_t result,
const cef_string_t* error_message) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: error_message
// Execute
CefRegisterCdmCallbackCppToC::Get(self)->OnCdmRegistrationComplete(
result, CefString(error_message));
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefRegisterCdmCallbackCppToC::CefRegisterCdmCallbackCppToC() {
GetStruct()->on_cdm_registration_complete =
register_cdm_callback_on_cdm_registration_complete;
}
// DESTRUCTOR - Do not edit by hand.
CefRegisterCdmCallbackCppToC::~CefRegisterCdmCallbackCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefRegisterCdmCallback> CefCppToCRefCounted<
CefRegisterCdmCallbackCppToC,
CefRegisterCdmCallback,
cef_register_cdm_callback_t>::UnwrapDerived(CefWrapperType type,
cef_register_cdm_callback_t*
s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefRegisterCdmCallbackCppToC,
CefRegisterCdmCallback,
cef_register_cdm_callback_t>::kWrapperType =
WT_REGISTER_CDM_CALLBACK;

View File

@ -1,40 +0,0 @@
// Copyright (c) 2021 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=9817a192fb9476a843c3ccd0467e781adf426b91$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_REGISTER_CDM_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_REGISTER_CDM_CALLBACK_CPPTOC_H_
#pragma once
#if !defined(WRAPPING_CEF_SHARED)
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_web_plugin_capi.h"
#include "include/cef_browser.h"
#include "include/cef_web_plugin.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefRegisterCdmCallbackCppToC
: public CefCppToCRefCounted<CefRegisterCdmCallbackCppToC,
CefRegisterCdmCallback,
cef_register_cdm_callback_t> {
public:
CefRegisterCdmCallbackCppToC();
virtual ~CefRegisterCdmCallbackCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_REGISTER_CDM_CALLBACK_CPPTOC_H_

View File

@ -1,63 +0,0 @@
// Copyright (c) 2021 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=cf53fb30f47eeda9354fa60731d554ea757a47ac$
//
#include "libcef_dll/ctocpp/register_cdm_callback_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
void CefRegisterCdmCallbackCToCpp::OnCdmRegistrationComplete(
cef_cdm_registration_error_t result,
const CefString& error_message) {
shutdown_checker::AssertNotShutdown();
cef_register_cdm_callback_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_cdm_registration_complete))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: error_message
// Execute
_struct->on_cdm_registration_complete(_struct, result,
error_message.GetStruct());
}
// CONSTRUCTOR - Do not edit by hand.
CefRegisterCdmCallbackCToCpp::CefRegisterCdmCallbackCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefRegisterCdmCallbackCToCpp::~CefRegisterCdmCallbackCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_register_cdm_callback_t* CefCToCppRefCounted<
CefRegisterCdmCallbackCToCpp,
CefRegisterCdmCallback,
cef_register_cdm_callback_t>::UnwrapDerived(CefWrapperType type,
CefRegisterCdmCallback* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefRegisterCdmCallbackCToCpp,
CefRegisterCdmCallback,
cef_register_cdm_callback_t>::kWrapperType =
WT_REGISTER_CDM_CALLBACK;

View File

@ -1,44 +0,0 @@
// Copyright (c) 2021 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=202e9ab7dd5d4dc53daa2f716e0dd74c623ecd8c$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REGISTER_CDM_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_REGISTER_CDM_CALLBACK_CTOCPP_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_browser_capi.h"
#include "include/capi/cef_web_plugin_capi.h"
#include "include/cef_browser.h"
#include "include/cef_web_plugin.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefRegisterCdmCallbackCToCpp
: public CefCToCppRefCounted<CefRegisterCdmCallbackCToCpp,
CefRegisterCdmCallback,
cef_register_cdm_callback_t> {
public:
CefRegisterCdmCallbackCToCpp();
virtual ~CefRegisterCdmCallbackCToCpp();
// CefRegisterCdmCallback methods.
void OnCdmRegistrationComplete(cef_cdm_registration_error_t result,
const CefString& error_message) override;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_REGISTER_CDM_CALLBACK_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=b2f22315d4021be203ececa54d5bb8c651f60dfc$ // $hash=232cd54c28334b9a3d98ebfb5a291643f0a7db62$
// //
#include "include/capi/cef_app_capi.h" #include "include/capi/cef_app_capi.h"
@ -47,7 +47,6 @@
#include "libcef_dll/ctocpp/app_ctocpp.h" #include "libcef_dll/ctocpp/app_ctocpp.h"
#include "libcef_dll/ctocpp/completion_callback_ctocpp.h" #include "libcef_dll/ctocpp/completion_callback_ctocpp.h"
#include "libcef_dll/ctocpp/end_tracing_callback_ctocpp.h" #include "libcef_dll/ctocpp/end_tracing_callback_ctocpp.h"
#include "libcef_dll/ctocpp/register_cdm_callback_ctocpp.h"
#include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h" #include "libcef_dll/ctocpp/scheme_handler_factory_ctocpp.h"
#include "libcef_dll/ctocpp/task_ctocpp.h" #include "libcef_dll/ctocpp/task_ctocpp.h"
#include "libcef_dll/ctocpp/v8handler_ctocpp.h" #include "libcef_dll/ctocpp/v8handler_ctocpp.h"
@ -892,22 +891,6 @@ CEF_EXPORT void cef_is_web_plugin_unstable(
CefWebPluginUnstableCallbackCToCpp::Wrap(callback)); CefWebPluginUnstableCallbackCToCpp::Wrap(callback));
} }
CEF_EXPORT void cef_register_widevine_cdm(
const cef_string_t* path,
struct _cef_register_cdm_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: path; type: string_byref_const
DCHECK(path);
if (!path)
return;
// Unverified params: callback
// Execute
CefRegisterWidevineCdm(CefString(path),
CefRegisterCdmCallbackCToCpp::Wrap(callback));
}
CEF_EXPORT void cef_execute_java_script_with_user_gesture_for_tests( CEF_EXPORT void cef_execute_java_script_with_user_gesture_for_tests(
struct _cef_frame_t* frame, struct _cef_frame_t* frame,
const cef_string_t* javascript) { const cef_string_t* javascript) {

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=85426bf2da9016443939636319265fff616f1cb4$ // $hash=01fb8dd98e44b937595c1e1f987f5e4850bff64d$
// //
#include <dlfcn.h> #include <dlfcn.h>
@ -177,9 +177,6 @@ typedef void (*cef_register_web_plugin_crash_ptr)(const cef_string_t*);
typedef void (*cef_is_web_plugin_unstable_ptr)( typedef void (*cef_is_web_plugin_unstable_ptr)(
const cef_string_t*, const cef_string_t*,
struct _cef_web_plugin_unstable_callback_t*); struct _cef_web_plugin_unstable_callback_t*);
typedef void (*cef_register_widevine_cdm_ptr)(
const cef_string_t*,
struct _cef_register_cdm_callback_t*);
typedef void (*cef_execute_java_script_with_user_gesture_for_tests_ptr)( typedef void (*cef_execute_java_script_with_user_gesture_for_tests_ptr)(
struct _cef_frame_t*, struct _cef_frame_t*,
const cef_string_t*); const cef_string_t*);
@ -570,7 +567,6 @@ struct libcef_pointers {
cef_unregister_internal_web_plugin_ptr cef_unregister_internal_web_plugin; cef_unregister_internal_web_plugin_ptr cef_unregister_internal_web_plugin;
cef_register_web_plugin_crash_ptr cef_register_web_plugin_crash; cef_register_web_plugin_crash_ptr cef_register_web_plugin_crash;
cef_is_web_plugin_unstable_ptr cef_is_web_plugin_unstable; cef_is_web_plugin_unstable_ptr cef_is_web_plugin_unstable;
cef_register_widevine_cdm_ptr cef_register_widevine_cdm;
cef_execute_java_script_with_user_gesture_for_tests_ptr cef_execute_java_script_with_user_gesture_for_tests_ptr
cef_execute_java_script_with_user_gesture_for_tests; cef_execute_java_script_with_user_gesture_for_tests;
cef_browser_host_create_browser_ptr cef_browser_host_create_browser; cef_browser_host_create_browser_ptr cef_browser_host_create_browser;
@ -787,7 +783,6 @@ int libcef_init_pointers(const char* path) {
INIT_ENTRY(cef_unregister_internal_web_plugin); INIT_ENTRY(cef_unregister_internal_web_plugin);
INIT_ENTRY(cef_register_web_plugin_crash); INIT_ENTRY(cef_register_web_plugin_crash);
INIT_ENTRY(cef_is_web_plugin_unstable); INIT_ENTRY(cef_is_web_plugin_unstable);
INIT_ENTRY(cef_register_widevine_cdm);
INIT_ENTRY(cef_execute_java_script_with_user_gesture_for_tests); INIT_ENTRY(cef_execute_java_script_with_user_gesture_for_tests);
INIT_ENTRY(cef_browser_host_create_browser); INIT_ENTRY(cef_browser_host_create_browser);
INIT_ENTRY(cef_browser_host_create_browser_sync); INIT_ENTRY(cef_browser_host_create_browser_sync);
@ -1255,12 +1250,6 @@ void cef_is_web_plugin_unstable(
g_libcef_pointers.cef_is_web_plugin_unstable(path, callback); g_libcef_pointers.cef_is_web_plugin_unstable(path, callback);
} }
NO_SANITIZE("cfi-icall")
void cef_register_widevine_cdm(const cef_string_t* path,
struct _cef_register_cdm_callback_t* callback) {
g_libcef_pointers.cef_register_widevine_cdm(path, callback);
}
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
void cef_execute_java_script_with_user_gesture_for_tests( void cef_execute_java_script_with_user_gesture_for_tests(
struct _cef_frame_t* frame, struct _cef_frame_t* frame,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=b43931d8bb81fbfd7a55c011ac6e5b471b3a30ac$ // $hash=7fef7aaa85b96ed7c7fc82542cd393210e1d89ee$
// //
#include "include/capi/cef_app_capi.h" #include "include/capi/cef_app_capi.h"
@ -44,7 +44,6 @@
#include "libcef_dll/cpptoc/app_cpptoc.h" #include "libcef_dll/cpptoc/app_cpptoc.h"
#include "libcef_dll/cpptoc/completion_callback_cpptoc.h" #include "libcef_dll/cpptoc/completion_callback_cpptoc.h"
#include "libcef_dll/cpptoc/end_tracing_callback_cpptoc.h" #include "libcef_dll/cpptoc/end_tracing_callback_cpptoc.h"
#include "libcef_dll/cpptoc/register_cdm_callback_cpptoc.h"
#include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h" #include "libcef_dll/cpptoc/scheme_handler_factory_cpptoc.h"
#include "libcef_dll/cpptoc/task_cpptoc.h" #include "libcef_dll/cpptoc/task_cpptoc.h"
#include "libcef_dll/cpptoc/v8handler_cpptoc.h" #include "libcef_dll/cpptoc/v8handler_cpptoc.h"
@ -167,7 +166,7 @@ NO_SANITIZE("cfi-icall") CEF_GLOBAL bool CefCrashReportingEnabled() {
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CEF_GLOBAL
void CefSetCrashKeyValue(const CefString& key, const CefString& value) { void CefSetCrashKeyValue(const CefString& key, const CefString& value) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: key; type: string_byref_const // Verify param: key; type: string_byref_const
@ -312,7 +311,7 @@ CEF_GLOBAL void CefLoadCRLSetsFile(const CefString& path) {
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CEF_GLOBAL
bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin, bool CefAddCrossOriginWhitelistEntry(const CefString& source_origin,
const CefString& target_protocol, const CefString& target_protocol,
const CefString& target_domain, const CefString& target_domain,
bool allow_target_subdomains) { bool allow_target_subdomains) {
@ -339,7 +338,7 @@ CEF_GLOBAL
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CEF_GLOBAL
bool CefRemoveCrossOriginWhitelistEntry(const CefString& source_origin, bool CefRemoveCrossOriginWhitelistEntry(const CefString& source_origin,
const CefString& target_protocol, const CefString& target_protocol,
const CefString& target_domain, const CefString& target_domain,
bool allow_target_subdomains) { bool allow_target_subdomains) {
@ -403,7 +402,7 @@ CEF_GLOBAL bool CefCreateURL(const CefURLParts& parts, CefString& url) {
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CefString CEF_GLOBAL CefString
CefFormatUrlForSecurityDisplay(const CefString& origin_url) { CefFormatUrlForSecurityDisplay(const CefString& origin_url) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: origin_url; type: string_byref_const // Verify param: origin_url; type: string_byref_const
@ -441,7 +440,7 @@ CEF_GLOBAL CefString CefGetMimeType(const CefString& extension) {
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CEF_GLOBAL
void CefGetExtensionsForMimeType(const CefString& mime_type, void CefGetExtensionsForMimeType(const CefString& mime_type,
std::vector<CefString>& extensions) { std::vector<CefString>& extensions) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
@ -596,8 +595,8 @@ CEF_GLOBAL CefRefPtr<CefValue> CefParseJSONAndReturnError(
} }
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CefString CEF_GLOBAL CefString CefWriteJSON(CefRefPtr<CefValue> node,
CefWriteJSON(CefRefPtr<CefValue> node, cef_json_writer_options_t options) { cef_json_writer_options_t options) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: node; type: refptr_same // Verify param: node; type: refptr_same
@ -797,7 +796,7 @@ CEF_GLOBAL bool CefRegisterExtension(const CefString& extension_name,
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL CEF_GLOBAL
void CefVisitWebPluginInfo(CefRefPtr<CefWebPluginInfoVisitor> visitor) { void CefVisitWebPluginInfo(CefRefPtr<CefWebPluginInfoVisitor> visitor) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: visitor; type: refptr_diff // Verify param: visitor; type: refptr_diff
@ -862,23 +861,6 @@ CEF_GLOBAL void CefIsWebPluginUnstable(
path.GetStruct(), CefWebPluginUnstableCallbackCppToC::Wrap(callback)); path.GetStruct(), CefWebPluginUnstableCallbackCppToC::Wrap(callback));
} }
NO_SANITIZE("cfi-icall")
CEF_GLOBAL
void CefRegisterWidevineCdm(const CefString& path,
CefRefPtr<CefRegisterCdmCallback> callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: path; type: string_byref_const
DCHECK(!path.empty());
if (path.empty())
return;
// Unverified params: callback
// Execute
cef_register_widevine_cdm(path.GetStruct(),
CefRegisterCdmCallbackCppToC::Wrap(callback));
}
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
CEF_GLOBAL void CefExecuteJavaScriptWithUserGestureForTests( CEF_GLOBAL void CefExecuteJavaScriptWithUserGestureForTests(
CefRefPtr<CefFrame> frame, CefRefPtr<CefFrame> frame,

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=8b8237eb5b789df29937eaf46a231e0ca83d86c6$ // $hash=abd4c6d471c9ff3d7113b6125a6cfb2a26d58304$
// //
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_ #ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
@ -101,7 +101,6 @@ enum CefWrapperType {
WT_PRINT_SETTINGS, WT_PRINT_SETTINGS,
WT_PROCESS_MESSAGE, WT_PROCESS_MESSAGE,
WT_READ_HANDLER, WT_READ_HANDLER,
WT_REGISTER_CDM_CALLBACK,
WT_REGISTRATION, WT_REGISTRATION,
WT_RENDER_HANDLER, WT_RENDER_HANDLER,
WT_RENDER_PROCESS_HANDLER, WT_RENDER_PROCESS_HANDLER,

View File

@ -189,13 +189,6 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2102 # https://bitbucket.org/chromiumembedded/cef/issues/2102
'name': 'views_1749_2102', 'name': 'views_1749_2102',
}, },
{
# Fix chrome Widevine build on Linux.
#
# Remove incorrect assertion on Windows/macOS by cherry-picking this commit:
# https://chromium.googlesource.com/chromium/src/+/ec992a43e7
'name': 'chrome_widevine',
},
{ {
# Support CEF changes in chrome/browser. # Support CEF changes in chrome/browser.
'name': 'chrome_browser', 'name': 'chrome_browser',
@ -405,6 +398,11 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/1936 # https://bitbucket.org/chromiumembedded/cef/issues/1936
'name': 'linux_assets_path_1936', 'name': 'linux_assets_path_1936',
}, },
{
# Linux: Avoid usage of chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT.
# https://bitbucket.org/chromiumembedded/cef/issues/3149
'name': 'linux_chrome_widevine_3149',
},
{ {
# Enhancements to NetworkService: # Enhancements to NetworkService:
# - Add support for calling CookieMonster::SetCookieableSchemes. # - Add support for calling CookieMonster::SetCookieableSchemes.

View File

@ -1,12 +0,0 @@
diff --git third_party/widevine/cdm/BUILD.gn third_party/widevine/cdm/BUILD.gn
index 91bcefa2f0698..9a5759239e590 100644
--- third_party/widevine/cdm/BUILD.gn
+++ third_party/widevine/cdm/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/chromeos/ui_mode.gni")
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/features.gni")
import("//build/toolchain/toolchain.gni")
+import("//cef/libcef/features/features.gni")
import("//media/cdm/library_cdm/cdm_paths.gni")
import("//media/media_options.gni")
import("//third_party/widevine/cdm/widevine.gni")

View File

@ -0,0 +1,58 @@
diff --git chrome/common/media/component_widevine_cdm_hint_file_linux.cc chrome/common/media/component_widevine_cdm_hint_file_linux.cc
index 44a89a2e7f6e..447c1a635ead 100644
--- chrome/common/media/component_widevine_cdm_hint_file_linux.cc
+++ chrome/common/media/component_widevine_cdm_hint_file_linux.cc
@@ -16,6 +16,7 @@
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
+#include "third_party/widevine/cdm/widevine_cdm_common.h"
namespace {
@@ -37,14 +38,33 @@ base::FilePath GetPath(const base::Value& dict) {
return path;
}
+// On Linux the Widevine CDM is loaded into the zygote at startup. When the
+// component updater runs sometime later and finds a newer version of the
+// Widevine CDM, don't register it as the newer version can't be used. Instead,
+// save the path to the new Widevine CDM in this file. Next time at startup this
+// file will be checked, and if it references a usable Widevine CDM, use this
+// version instead of the old (potentially bundled) CDM.
+// Add this method instead of using chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT
+// because only directories (not files) can be configured via
+// base::PathService::Override.
+bool GetHintFilePath(base::FilePath* hint_file_path) {
+ base::FilePath user_data_dir;
+ if (!base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
+ return false;
+ // Match the file name in chrome/common/chrome_paths.cc
+ *hint_file_path = user_data_dir
+ .AppendASCII(kWidevineCdmBaseDirectory)
+ .Append(FILE_PATH_LITERAL("latest-component-updated-widevine-cdm"));
+ return true;
+}
+
} // namespace
bool UpdateWidevineCdmHintFile(const base::FilePath& cdm_base_path) {
DCHECK(!cdm_base_path.empty());
base::FilePath hint_file_path;
- CHECK(base::PathService::Get(chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT,
- &hint_file_path));
+ CHECK(GetHintFilePath(&hint_file_path));
base::Value dict(base::Value::Type::DICTIONARY);
dict.SetStringPath(kPath, cdm_base_path.value());
@@ -62,8 +82,7 @@ bool UpdateWidevineCdmHintFile(const base::FilePath& cdm_base_path) {
base::FilePath GetLatestComponentUpdatedWidevineCdmDirectory() {
base::FilePath hint_file_path;
- CHECK(base::PathService::Get(chrome::FILE_COMPONENT_WIDEVINE_CDM_HINT,
- &hint_file_path));
+ CHECK(GetHintFilePath(&hint_file_path));
if (!base::PathExists(hint_file_path)) {
DVLOG(2) << "CDM hint file at " << hint_file_path << " does not exist.";

View File

@ -1,120 +0,0 @@
// Copyright (c) 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.
#include "tests/cefclient/browser/drm_test.h"
#include <algorithm>
#include <string>
#include "include/cef_parser.h"
#include "include/cef_web_plugin.h"
#include "tests/cefclient/browser/test_runner.h"
namespace client {
namespace drm_test {
namespace {
// Application-specific error codes.
const int kMessageFormatError = 1;
const int kCdmLoadError = 2;
const char kTestUrlPath[] = "/drm";
const char kWidevineCdmPathKey[] = "widevine_cdm_path";
// Callback executed once CDM registration is complete.
class CdmCallback : public CefRegisterCdmCallback {
public:
CdmCallback(CefRefPtr<CefMessageRouterBrowserSide::Callback> callback)
: callback_(callback) {}
void OnCdmRegistrationComplete(cef_cdm_registration_error_t result,
const CefString& error_message) override {
if (result == CEF_CDM_REGISTRATION_ERROR_NONE)
callback_->Success("");
else
callback_->Failure(kCdmLoadError, error_message);
callback_ = nullptr;
}
private:
CefRefPtr<CefMessageRouterBrowserSide::Callback> callback_;
IMPLEMENT_REFCOUNTING(CdmCallback);
DISALLOW_COPY_AND_ASSIGN(CdmCallback);
};
// Handle messages in the browser process.
class Handler : public CefMessageRouterBrowserSide::Handler {
public:
Handler() {}
// Called due to cefQuery execution in drm.html.
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) override {
// Only handle messages from the test URL.
const std::string& url = frame->GetURL();
if (!test_runner::IsTestURL(url, kTestUrlPath))
return false;
// Parse |request| as a JSON dictionary.
CefRefPtr<CefDictionaryValue> request_dict = ParseJSON(request);
if (!request_dict) {
callback->Failure(kMessageFormatError, "Incorrect message format");
return true;
}
// Verify the "widevine_cdm_path" key.
if (!VerifyKey(request_dict, kWidevineCdmPathKey, VTYPE_STRING, callback))
return true;
const std::string& widevine_cdm_path =
request_dict->GetString(kWidevineCdmPathKey);
if (widevine_cdm_path.empty()) {
callback->Failure(kMessageFormatError, "Empty widevine CDM path");
return true;
}
// Register the Widvine CDM.
CefRegisterWidevineCdm(widevine_cdm_path, new CdmCallback(callback));
return true;
}
private:
// Convert a JSON string to a dictionary value.
static CefRefPtr<CefDictionaryValue> ParseJSON(const CefString& string) {
CefRefPtr<CefValue> value = CefParseJSON(string, JSON_PARSER_RFC);
if (value.get() && value->GetType() == VTYPE_DICTIONARY)
return value->GetDictionary();
return nullptr;
}
// Verify that |key| exists in |dictionary| and has type |value_type|. Fails
// |callback| and returns false on failure.
static bool VerifyKey(CefRefPtr<CefDictionaryValue> dictionary,
const char* key,
cef_value_type_t value_type,
CefRefPtr<Callback> callback) {
if (!dictionary->HasKey(key) || dictionary->GetType(key) != value_type) {
callback->Failure(
kMessageFormatError,
"Missing or incorrectly formatted message key: " + std::string(key));
return false;
}
return true;
}
};
} // namespace
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
handlers.insert(new Handler());
}
} // namespace drm_test
} // namespace client

View File

@ -1,20 +0,0 @@
// Copyright (c) 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_TESTS_CEFCLIENT_BROWSER_DRM_TEST_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_DRM_TEST_H_
#pragma once
#include "tests/cefclient/browser/test_runner.h"
namespace client {
namespace drm_test {
// Create message handlers. Called from test_runner.cc.
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
} // namespace drm_test
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_DRM_TEST_H_

View File

@ -7,7 +7,6 @@
#include <algorithm> #include <algorithm>
#include "include/cef_parser.h" #include "include/cef_parser.h"
#include "include/cef_web_plugin.h"
#include "tests/shared/browser/client_app_browser.h" #include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/common/client_switches.h" #include "tests/shared/common/client_switches.h"
@ -144,16 +143,6 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
if (!use_transparent_painting) { if (!use_transparent_painting) {
browser_background_color_ = background_color_; browser_background_color_ = background_color_;
} }
const std::string& cdm_path =
command_line_->GetSwitchValue(switches::kWidevineCdmPath);
if (!cdm_path.empty()) {
// Register the Widevine CDM at the specified path. See comments in
// cef_web_plugin.h for details. It's safe to call this method before
// CefInitialize(), and calling it before CefInitialize() is required on
// Linux.
CefRegisterWidevineCdm(cdm_path, nullptr);
}
} }
MainContextImpl::~MainContextImpl() { MainContextImpl::~MainContextImpl() {

View File

@ -47,28 +47,27 @@
#define IDS_BINDING_HTML 1000 #define IDS_BINDING_HTML 1000
#define IDS_DIALOGS_HTML 1001 #define IDS_DIALOGS_HTML 1001
#define IDS_DRAGGABLE_HTML 1002 #define IDS_DRAGGABLE_HTML 1002
#define IDS_DRM_HTML 1003 #define IDS_LOCALSTORAGE_HTML 1003
#define IDS_LOCALSTORAGE_HTML 1004 #define IDS_LOGO_PNG 1004
#define IDS_LOGO_PNG 1005 #define IDS_MEDIA_ROUTER_HTML 1005
#define IDS_MEDIA_ROUTER_HTML 1006 #define IDS_MENU_ICON_1X_PNG 1006
#define IDS_MENU_ICON_1X_PNG 1007 #define IDS_MENU_ICON_2X_PNG 1007
#define IDS_MENU_ICON_2X_PNG 1008 #define IDS_OSRTEST_HTML 1008
#define IDS_OSRTEST_HTML 1009 #define IDS_OTHER_TESTS_HTML 1009
#define IDS_OTHER_TESTS_HTML 1010 #define IDS_PDF_HTML 1010
#define IDS_PDF_HTML 1011 #define IDS_PDF_PDF 1011
#define IDS_PDF_PDF 1012 #define IDS_PERFORMANCE_HTML 1012
#define IDS_PERFORMANCE_HTML 1013 #define IDS_PERFORMANCE2_HTML 1013
#define IDS_PERFORMANCE2_HTML 1014 #define IDS_PREFERENCES_HTML 1014
#define IDS_PREFERENCES_HTML 1015 #define IDS_RESPONSE_FILTER_HTML 1015
#define IDS_RESPONSE_FILTER_HTML 1016 #define IDS_SERVER_HTML 1016
#define IDS_SERVER_HTML 1017 #define IDS_TRANSPARENCY_HTML 1017
#define IDS_TRANSPARENCY_HTML 1018 #define IDS_URLREQUEST_HTML 1018
#define IDS_URLREQUEST_HTML 1019 #define IDS_WEBSOCKET_HTML 1019
#define IDS_WEBSOCKET_HTML 1020 #define IDS_WINDOW_HTML 1020
#define IDS_WINDOW_HTML 1021 #define IDS_WINDOW_ICON_1X_PNG 1021
#define IDS_WINDOW_ICON_1X_PNG 1022 #define IDS_WINDOW_ICON_2X_PNG 1022
#define IDS_WINDOW_ICON_2X_PNG 1023 #define IDS_XMLHTTPREQUEST_HTML 1023
#define IDS_XMLHTTPREQUEST_HTML 1024
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030 #define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031 #define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031

View File

@ -17,7 +17,6 @@ int GetResourceId(const char* resource_name) {
{"binding.html", IDS_BINDING_HTML}, {"binding.html", IDS_BINDING_HTML},
{"dialogs.html", IDS_DIALOGS_HTML}, {"dialogs.html", IDS_DIALOGS_HTML},
{"draggable.html", IDS_DRAGGABLE_HTML}, {"draggable.html", IDS_DRAGGABLE_HTML},
{"drm.html", IDS_DRM_HTML},
{"extensions/set_page_color/icon.png", {"extensions/set_page_color/icon.png",
IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG}, IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG},
{"extensions/set_page_color/manifest.json", {"extensions/set_page_color/manifest.json",

View File

@ -19,7 +19,6 @@
#include "tests/cefclient/browser/binding_test.h" #include "tests/cefclient/browser/binding_test.h"
#include "tests/cefclient/browser/client_handler.h" #include "tests/cefclient/browser/client_handler.h"
#include "tests/cefclient/browser/dialog_test.h" #include "tests/cefclient/browser/dialog_test.h"
#include "tests/cefclient/browser/drm_test.h"
#include "tests/cefclient/browser/main_context.h" #include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/media_router_test.h" #include "tests/cefclient/browser/media_router_test.h"
#include "tests/cefclient/browser/preferences_test.h" #include "tests/cefclient/browser/preferences_test.h"
@ -882,9 +881,6 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) {
// Create the dialog test handlers. // Create the dialog test handlers.
dialog_test::CreateMessageHandlers(handlers); dialog_test::CreateMessageHandlers(handlers);
// Create the drm test handlers.
drm_test::CreateMessageHandlers(handlers);
// Create the media router test handlers. // Create the media router test handlers.
media_router_test::CreateMessageHandlers(handlers); media_router_test::CreateMessageHandlers(handlers);

View File

@ -1,141 +0,0 @@
<html>
<head>
<title>DRM Test</title>
<script language="JavaScript">
function setup() {
if (location.hostname == 'tests' || location.hostname == 'localhost')
return;
alert('This page can only be run from tests or localhost.');
// Disable all elements.
var elements = document.getElementById("form").elements;
for (var i = 0, element; element = elements[i++]; ) {
element.disabled = true;
}
doTest();
}
// Based on DRM detection code from https://github.com/google/shaka-player
function probeSupport() {
var tests = [];
var testKeySystems = [
'org.w3.clearkey',
'com.widevine.alpha',
];
var basicVideoCapabilities = [
{ contentType: 'video/mp4; codecs="avc1.42E01E"' },
{ contentType: 'video/webm; codecs="vp9"' }
];
var basicConfig = {
videoCapabilities: basicVideoCapabilities
};
var offlineConfig = {
videoCapabilities: basicVideoCapabilities,
persistentState: 'required',
sessionTypes: ['persistent-license']
};
// Try the offline config first, then fall back to the basic config.
var configs = [offlineConfig, basicConfig];
var support = {};
testKeySystems.forEach(function(keySystem) {
var p = navigator.requestMediaKeySystemAccess(keySystem, configs)
.then(function(access) {
// We can't (yet) trust every browser to report the session types they
// support in access.getConfiguration(). Therefore, we create a
// MediaKeys object and try to create an offline session.
// https://goo.gl/gtYT3z, https://goo.gl/rvnB1g, https://goo.gl/z0URJ0
var mediaKeys = access.createMediaKeys();
var persistentState = false;
try {
// This will throw if persistent licenses are not supported.
mediaKeys.createSession('persistent-license');
persistentState = true;
} catch (e) {}
support[keySystem] = {persistentState: persistentState};
}, function() {
support[keySystem] = null;
});
tests.push(p);
});
return Promise.all(tests).then(function() {
return support;
});
}
function getWidevineCdmInfo() {
if (!('Widevine Content Decryption Module' in navigator.plugins)) {
return "Widevine CDM plugin not loaded.";
}
var plugin = navigator.plugins['Widevine Content Decryption Module'];
return "Widevine CDM plugin:\n" + JSON.stringify({
"name": plugin.name,
"filename": plugin.filename,
"description": plugin.description,
}, null, ' ')
}
function printSupport(support) {
var output = document.getElementById('output');
output.textContent = getWidevineCdmInfo() + "\n\nDRM Support:\n" + support;
}
function doTest() {
probeSupport().then(function(support) {
printSupport(JSON.stringify(support, null, ' '));
});
}
// Send a message to the browser process.
function sendMessage() {
// Create the request object.
var request = {};
request.widevine_cdm_path =
document.getElementById("widevine_cdm_path").value;
// Results in a call to the OnQuery method in drm_test.cc
window.cefQuery({
request: JSON.stringify(request),
onSuccess: function(response) {
alert('Widevine CDM plugin loaded successfully!');
// Registration succeeded so test again.
doTest();
},
onFailure: function(error_code, error_message) {
alert(error_message + ' (' + error_code + ')');
}
});
}
</script>
</head>
<body bgcolor="white" onload="setup()">
Important notes:
<ul>
<li>Clearkey support is built in and should always be enabled.</li>
<li>Widevine support requires CDM binaries that must be downloaded from Google. Contact Google <a href="https://www.widevine.com/contact.html">here</a> for details.</li>
<li>Widevine support is enabled by calling the CefRegisterWidevineCdm() function. See comments in cef_web_plugin.h for usage.</li>
<li>The CefRegisterWidevineCdm() function can be called during runtime on Windows and OS X to register Widevine binaries. Use the below form to test this capability.</li>
<li>Calling CefRegisterWidevineCdm() before CefInitialize() is required on Linux.</li>
<li>Cefclient will call CefRegisterWidevineCdm() before CefInitialize() if "--widevine-cdm-path=&lt;path&gt;" is specified on the command-line.</li>
<li>View extended media support information <a href="https://shaka-player-demo.appspot.com/support.html">here</a>.</li>
<li>Test DRM video playback <a href="https://shaka-player-demo.appspot.com/demo/">here</a>. Select an "asset" that includes Clearkey or Widevine in the name.</li>
</ul>
<form id="form">
Widevine CDM Path: <input type="text" id="widevine_cdm_path" value="" size="40">
<input type="button" onclick="sendMessage();" value="Load CDM">
</form>
<pre id="output"></pre>
</body>
</html>

View File

@ -13,7 +13,7 @@
<li><a href="dialogs">Dialogs</a></li> <li><a href="dialogs">Dialogs</a></li>
<li><a href="http://html5demos.com/drag">Drag & Drop</a></li> <li><a href="http://html5demos.com/drag">Drag & Drop</a></li>
<li><a href="draggable">Draggable Regions</a></li> <li><a href="draggable">Draggable Regions</a></li>
<li><a href="drm">DRM (Clearkey, Widevine)</a> - Widevine requires setup as described in cef_web_plugin.h</li> <li>DRM (Clearkey, Widevine) <a href="https://shaka-player-demo.appspot.com/support.html">Codecs support</a>, <a href="https://shaka-player-demo.appspot.com/demo/">Video player demo</a></li>
<li><a href="http://www.adobe.com/software/flash/about/">Flash Plugin</a> - requires "enable-system-flash" flag on Win/Mac and "ppapi-flash-path", "ppapi-flash-version" flags on Linux</li> <li><a href="http://www.adobe.com/software/flash/about/">Flash Plugin</a> - requires "enable-system-flash" flag on Win/Mac and "ppapi-flash-path", "ppapi-flash-version" flags on Linux</li>
<li><a href="http://www.html5test.com">HTML5 Feature Test</a></li> <li><a href="http://www.html5test.com">HTML5 Feature Test</a></li>
<li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li> <li><a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html">HTML5 Filesystem</a> - requires "cache-path" flag</li>

View File

@ -32,7 +32,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDS_BINDING_HTML BINARY "..\\binding.html" IDS_BINDING_HTML BINARY "..\\binding.html"
IDS_DIALOGS_HTML BINARY "..\\dialogs.html" IDS_DIALOGS_HTML BINARY "..\\dialogs.html"
IDS_DRAGGABLE_HTML BINARY "..\\draggable.html" IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
IDS_DRM_HTML BINARY "..\\drm.html"
IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html" IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html"
IDS_LOGO_PNG BINARY "..\\logo.png" IDS_LOGO_PNG BINARY "..\\logo.png"
IDS_MEDIA_ROUTER_HTML BINARY "..\\media_router.html" IDS_MEDIA_ROUTER_HTML BINARY "..\\media_router.html"

View File

@ -39,7 +39,6 @@ const char kHideFrame[] = "hide-frame";
const char kHideControls[] = "hide-controls"; const char kHideControls[] = "hide-controls";
const char kAlwaysOnTop[] = "always-on-top"; const char kAlwaysOnTop[] = "always-on-top";
const char kHideTopMenu[] = "hide-top-menu"; const char kHideTopMenu[] = "hide-top-menu";
const char kWidevineCdmPath[] = "widevine-cdm-path";
const char kSslClientCertificate[] = "ssl-client-certificate"; const char kSslClientCertificate[] = "ssl-client-certificate";
const char kCRLSetsPath[] = "crl-sets-path"; const char kCRLSetsPath[] = "crl-sets-path";
const char kLoadExtension[] = "load-extension"; const char kLoadExtension[] = "load-extension";

View File

@ -33,7 +33,6 @@ extern const char kHideFrame[];
extern const char kHideControls[]; extern const char kHideControls[];
extern const char kAlwaysOnTop[]; extern const char kAlwaysOnTop[];
extern const char kHideTopMenu[]; extern const char kHideTopMenu[];
extern const char kWidevineCdmPath[];
extern const char kSslClientCertificate[]; extern const char kSslClientCertificate[];
extern const char kCRLSetsPath[]; extern const char kCRLSetsPath[];
extern const char kLoadExtension[]; extern const char kLoadExtension[];