Skip to content

Commit

Permalink
widevine: Use component updater with the Alloy runtime (fixes issue c…
Browse files Browse the repository at this point in the history
…hromiumembedded#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.
  • Loading branch information
magreenblatt committed Aug 10, 2021
1 parent e747782 commit 5a0b3ea
Show file tree
Hide file tree
Showing 45 changed files with 201 additions and 1,459 deletions.
3 changes: 1 addition & 2 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,6 @@ static_library("libcef_static") {
"libcef/common/values_impl.h",
"libcef/common/waitable_event_impl.cc",
"libcef/common/waitable_event_impl.h",
"libcef/common/widevine_loader.cc",
"libcef/common/widevine_loader.h",
"libcef/features/runtime.h",
"libcef/features/runtime_checks.h",
"libcef/renderer/alloy/alloy_content_renderer_client.cc",
Expand Down Expand Up @@ -850,6 +848,7 @@ static_library("libcef_static") {
"//chrome/services/printing:lib",
"//components/cdm/renderer",
"//components/certificate_transparency",
"//components/component_updater",
"//components/content_settings/core/browser",
"//components/content_settings/core/common",
"//components/crx_file",
Expand Down
6 changes: 1 addition & 5 deletions cef_paths.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=d723a9f6637cec523b158a6750d3a64698b407c3$
# $hash=f6950d026a9c92fbb58da3fe0cbcf0050c12ecf0$
#

{
Expand Down Expand Up @@ -374,8 +374,6 @@
'libcef_dll/cpptoc/process_message_cpptoc.h',
'libcef_dll/ctocpp/read_handler_ctocpp.cc',
'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.h',
'libcef_dll/ctocpp/render_handler_ctocpp.cc',
Expand Down Expand Up @@ -686,8 +684,6 @@
'libcef_dll/ctocpp/process_message_ctocpp.h',
'libcef_dll/cpptoc/read_handler_cpptoc.cc',
'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.h',
'libcef_dll/cpptoc/render_handler_cpptoc.cc',
Expand Down
3 changes: 0 additions & 3 deletions cef_paths2.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,6 @@
'tests/cefclient/browser/client_types.h',
'tests/cefclient/browser/dialog_test.cc',
'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.h',
'tests/cefclient/browser/main_context.cc',
Expand Down Expand Up @@ -296,7 +294,6 @@
'tests/cefclient/resources/binding.html',
'tests/cefclient/resources/dialogs.html',
'tests/cefclient/resources/draggable.html',
'tests/cefclient/resources/drm.html',
'tests/cefclient/resources/localstorage.html',
'tests/cefclient/resources/logo.png',
'tests/cefclient/resources/media_router.html',
Expand Down
71 changes: 1 addition & 70 deletions include/capi/cef_web_plugin_capi.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=f74bf4d33914d56d760f1bf5aadcf2651740c711$
// $hash=f51ad9ffc67d94b9cbfad154e7f224111c2a96fa$
//

#ifndef CEF_INCLUDE_CAPI_CEF_WEB_PLUGIN_CAPI_H_
Expand Down Expand Up @@ -129,29 +129,6 @@ typedef struct _cef_web_plugin_unstable_callback_t {
int unstable);
} 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
// process.
Expand Down Expand Up @@ -187,52 +164,6 @@ CEF_EXPORT void cef_is_web_plugin_unstable(
const cef_string_t* path,
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
}
#endif
Expand Down
8 changes: 4 additions & 4 deletions include/cef_api_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// 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)
#define CEF_API_HASH_PLATFORM "5beb166d25cb4aa70e15ff565a0268c60cab3e0c"
#define CEF_API_HASH_PLATFORM "c20e4ffc24e6267b61774f49237d0f30a581f370"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "5fa684079bfafa70cc920a1ad4e694e38c46d737"
#define CEF_API_HASH_PLATFORM "65731bc654ec6e1dbd48d6ff2336c4c8573f7d35"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "1e0cc77dabf9058f0fc118b4605fbcccda14466f"
#define CEF_API_HASH_PLATFORM "4e35b9cc9735c63ac9f16fbbb49a4b8e2307f23a"
#endif

#ifdef __cplusplus
Expand Down
64 changes: 0 additions & 64 deletions include/cef_web_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,68 +145,4 @@ class CefWebPluginUnstableCallback : public virtual CefBaseRefCounted {
void CefIsWebPluginUnstable(const CefString& path,
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_
33 changes: 4 additions & 29 deletions include/internal/cef_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ typedef struct _cef_settings_t {
// be stored on disk. If this value is empty then the default
// platform-specific user data directory will be used ("~/.cef_user_data"
// directory on Linux, "~/Library/Application Support/CEF/User Data" directory
// on Mac OS X, "Local Settings\Application Data\CEF\User Data" directory
// under the user profile directory on Windows). If this value is non-empty
// then it must be an absolute path. When using the Chrome runtime this value
// will be ignored in favor of the |root_cache_path| value.
// on Mac OS X, "AppData\Local\CEF\User Data" directory under the user profile
// directory on Windows). If this value is non-empty then it must be an
// absolute path. When using the Chrome runtime this value will be ignored in
// favor of the |root_cache_path| value.
///
cef_string_t user_data_path;

Expand Down Expand Up @@ -2948,31 +2948,6 @@ typedef enum {
CEF_SCHEME_OPTION_FETCH_ENABLED = 1 << 6,
} 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.
///
Expand Down
24 changes: 24 additions & 0 deletions libcef/browser/alloy/alloy_browser_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
#include "chrome/browser/media/router/chrome_media_router_factory.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/common/chrome_switches.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/result_codes.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/constants.h"
#include "net/base/net_module.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/base/resource/resource_bundle.h"

#if defined(USE_AURA) && defined(USE_X11)
Expand Down Expand Up @@ -73,6 +75,14 @@
#include "libcef/browser/printing/print_dialog_linux.h"
#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(
const content::MainFunctionParams& parameters)
: BrowserMainParts(), devtools_delegate_(nullptr) {}
Expand Down Expand Up @@ -207,6 +217,20 @@ int AlloyBrowserMainParts::PreMainMessageLoopRun() {

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;
}

Expand Down
1 change: 1 addition & 0 deletions libcef/browser/alloy/alloy_browser_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "libcef/browser/request_context_impl.h"

#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"
Expand Down
22 changes: 7 additions & 15 deletions libcef/browser/alloy/alloy_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,11 @@
#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/web/web_window_features.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#include "url/gurl.h"

#if defined(OS_LINUX)
#include "libcef/common/widevine_loader.h"
#endif

#if defined(OS_POSIX) && !defined(OS_MAC)
#include "base/debug/leak_annotations.h"
#include "chrome/common/chrome_paths.h"
Expand Down Expand Up @@ -734,18 +729,15 @@ void AlloyContentBrowserClient::AppendExtraCommandLineSwitches(
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 (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)) {
// Force use of the sub-process executable path for the zygote process.
const base::FilePath& subprocess_path =
Expand Down
Loading

0 comments on commit 5a0b3ea

Please sign in to comment.