Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support widevine in linux by bundling #1475

Closed
wants to merge 11 commits into from
7 changes: 7 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import("//build/util/process_version.gni")
import("//media/cdm/library_cdm/cdm_paths.gni")
import("//brave/brave_paks.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//third_party/widevine/cdm/widevine.gni")

if (is_mac) {
import("//build/config/mac/rules.gni")
Expand Down Expand Up @@ -270,6 +271,12 @@ copy("brave_dist_resources") {
}
}

if (bundle_widevine_cdm) {
assert(is_linux, "cdm bundling is only enabled in linux")
sources += [ "$root_out_dir/libwidevinecdm.so" ]
deps += [ "//third_party/widevine/cdm:widevine_cdm_binary" ]
}

outputs = [
"$brave_dist_dir/{{source_file_part}}"
]
Expand Down
7 changes: 6 additions & 1 deletion browser/brave_browser_main_extra_parts.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/browser/brave_browser_main_extra_parts.h"

#include "brave/browser/ui/content_settings/brave_widevine_bundle_util.h"
#include "chrome/browser/first_run/first_run.h"

BraveBrowserMainExtraParts::BraveBrowserMainExtraParts() {
Expand All @@ -14,4 +16,7 @@ BraveBrowserMainExtraParts::~BraveBrowserMainExtraParts() {

void BraveBrowserMainExtraParts::PreMainMessageLoopRun() {
brave::AutoImportMuon();
#if BUILDFLAG(BUNDLE_WIDEVINE_CDM)
MaybeRegisterWidevineCdm();
#endif
}
9 changes: 8 additions & 1 deletion browser/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ source_set("ui") {
"webui/settings/brave_default_extensions_handler.h",
]

if (enable_widevine_cdm_component) {
if (enable_widevine_cdm_component || bundle_widevine_cdm) {
sources += [
"content_settings/brave_widevine_blocked_image_model.cc",
"content_settings/brave_widevine_blocked_image_model.h",
Expand All @@ -98,6 +98,13 @@ source_set("ui") {
]
}

if (bundle_widevine_cdm) {
sources += [
"content_settings/brave_widevine_bundle_util.cc",
"content_settings/brave_widevine_bundle_util.h",
]
}

if (is_mac || is_win || is_chromeos) {
sources += [
"views/frame/brave_browser_frame.cc",
Expand Down
24 changes: 15 additions & 9 deletions browser/ui/content_settings/brave_content_setting_image_models.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change announced somewhere? A think, if it was then we should fix all sources at once, otherwise its better to fix the linter. @bbondy could you please clarify?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iefremov it is enforced by the linter. There was a discussion in #brave-core

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bridiver maybe we can fix the whole codebase by a single PR then? I can do one

* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

Expand All @@ -7,30 +8,35 @@
#include "brave/browser/ui/content_settings/brave_autoplay_blocked_image_model.h"
#include "third_party/widevine/cdm/buildflags.h"

#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) || BUILDFLAG(BUNDLE_WIDEVINE_CDM)
#include "brave/browser/ui/content_settings/brave_widevine_blocked_image_model.h"
#endif

void BraveGenerateContentSettingImageModels(
std::vector<std::unique_ptr<ContentSettingImageModel>>& result) {
std::vector<std::unique_ptr<ContentSettingImageModel>>* result) {
// lint complains to use pointer or const referencc for |result|.
Copy link
Collaborator

@bridiver bridiver Jan 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* is always preferable to & because it's more clear to the caller that you're passing something which might be modified when the method returns. If you're looking at a caller using ref, it's indistinguishable from passing by const ref or value unless you look at the method sig

Copy link
Member Author

@simonhong simonhong Jan 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, totally agree about that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically, this rule is fixed in CC, so we don't even need to have comments like this in the codebase :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. using like this is natural in chromium project :) Removed.

// So, changed to pointer because it is modified in this function.
// Assigned to ref again to make it clear.
// Otherwise, we need to use (*result)[i] for deferencing its element.
std::vector<std::unique_ptr<ContentSettingImageModel>>& result_ref = *result;
// Remove the cookies content setting image model
// https://github.com/brave/brave-browser/issues/1197
// TODO(iefremov): This changes break internal image models ordering which is
// based on enum values. This breaks tests and probably should be fixed
// (by adding more diff of course).
for (size_t i = 0; i < result.size(); i++) {
if (result[i]->image_type() ==
for (size_t i = 0; i < result_ref.size(); i++) {
if (result_ref[i]->image_type() ==
ContentSettingImageModel::ImageType::COOKIES) {
result.erase(result.begin() + i);
result_ref.erase(result_ref.begin() + i);
break;
}
}

#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
result.push_back(std::make_unique<BraveWidevineBlockedImageModel>(
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) || BUILDFLAG(BUNDLE_WIDEVINE_CDM)
result_ref.push_back(std::make_unique<BraveWidevineBlockedImageModel>(
BraveWidevineBlockedImageModel::ImageType::PLUGINS,
CONTENT_SETTINGS_TYPE_PLUGINS));
#endif

result.push_back(std::make_unique<BraveAutoplayBlockedImageModel>());
result_ref.push_back(std::make_unique<BraveAutoplayBlockedImageModel>());
}
10 changes: 8 additions & 2 deletions browser/ui/content_settings/brave_content_setting_image_models.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_CONTENT_SETTING_IMAGE_MODELS_H_
#define BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_CONTENT_SETTING_IMAGE_MODELS_H_

#include <memory>
#include <vector>

class ContentSettingImageModel;

void BraveGenerateContentSettingImageModels(
std::vector<std::unique_ptr<ContentSettingImageModel>>&);
std::vector<std::unique_ptr<ContentSettingImageModel>>* result);

#endif // BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_CONTENT_SETTING_IMAGE_MODELS_H_
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

Expand Down Expand Up @@ -57,7 +58,8 @@ class BraveWidevineBlockedImageModelBrowserTest : public InProcessBrowserTest {
};

// Tests that every model creates a valid bubble.
IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest, CreateBubbleModel) {
IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
CreateBubbleModel) {
WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
auto model = CreateModel();
Expand Down Expand Up @@ -85,9 +87,11 @@ IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
// The animation has run for the current WebContents, but not for any other.
Profile* profile = browser()->profile();
WebContents::CreateParams create_params(profile);
std::unique_ptr<WebContents> other_web_contents(WebContents::Create(create_params));
std::unique_ptr<WebContents> other_web_contents(
WebContents::Create(create_params));
content::WebContents* raw_other_web_contents = other_web_contents.get();
browser()->tab_strip_model()->AppendWebContents(std::move(other_web_contents), true);
browser()->tab_strip_model()->AppendWebContents(std::move(other_web_contents),
true);
EXPECT_TRUE(model->ShouldRunAnimation(raw_other_web_contents));
}

Expand All @@ -110,8 +114,8 @@ IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
EXPECT_EQ(link_value, observer.last_navigation_url().spec());
}

// Tests that the content setting model shows and that runninng plugins changes the
// opt in setting.
// Tests that the content setting model shows and that runninng plugins changes
// the opt in setting.
IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
RunPluginsOnPageClicked) {
GURL url = embedded_test_server()->GetURL("www.netflix.com", "/blank.html");
Expand All @@ -122,14 +126,16 @@ IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
browser()->tab_strip_model()->GetActiveWebContents();
std::unique_ptr<ContentSettingBubbleModel> bubble(
model->CreateBubbleModel(
browser()->content_setting_bubble_model_delegate(), web_contents));
browser()->content_setting_bubble_model_delegate(),
web_contents));

PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();

// Before we allow, opted in should be false
ASSERT_FALSE(prefs->GetBoolean(kWidevineOptedIn));

((BraveWidevineContentSettingPluginBubbleModel*)bubble.get())->RunPluginsOnPage();
reinterpret_cast<BraveWidevineContentSettingPluginBubbleModel*>(bubble.get())
->RunPluginsOnPage();

// After we allow, opted in pref should be true
ASSERT_TRUE(prefs->GetBoolean(kWidevineOptedIn));
Expand All @@ -152,12 +158,13 @@ IN_PROC_BROWSER_TEST_F(BraveWidevineBlockedImageModelBrowserTest,
browser()->tab_strip_model()->GetActiveWebContents();
std::unique_ptr<ContentSettingBubbleModel> bubble(
model->CreateBubbleModel(
browser()->content_setting_bubble_model_delegate(), web_contents));
browser()->content_setting_bubble_model_delegate(),
web_contents));

ASSERT_FALSE(model->is_visible());
}

#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) || BUILDFLAG(BUNDLE_WIDEVINE_CDM)
class BraveWidevineIconVisibilityBrowserTest : public CertVerifierBrowserTest {
public:
BraveWidevineIconVisibilityBrowserTest()
Expand Down Expand Up @@ -248,4 +255,5 @@ IN_PROC_BROWSER_TEST_F(BraveWidevineIconVisibilityBrowserTest,
EXPECT_TRUE(content::ExecuteScript(active_contents(), widevine_js));
EXPECT_TRUE(IsWidevineIconVisible());
}
#endif // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
#endif // BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) ||
// BUILDFLAG(BUNDLE_WIDEVINE_CDM)
24 changes: 24 additions & 0 deletions browser/ui/content_settings/brave_widevine_bundle_util.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/browser/ui/content_settings/brave_widevine_bundle_util.h"

#include "brave/common/pref_names.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/prefs/pref_service.h"
#include "content/browser/media/cdm_registry_impl.h"
#include "content/public/browser/browser_thread.h"

void MaybeRegisterWidevineCdm() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
// Only registers widevine cdm when user explicitly requested.
if (!prefs->GetBoolean(kWidevineOptedIn))
return;

auto* cdm_registry = content::CdmRegistryImpl::GetInstance();
cdm_registry->RegisterCdm(cdm_registry->cached_widevine_cdm_info());
}
15 changes: 15 additions & 0 deletions browser/ui/content_settings/brave_widevine_bundle_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_WIDEVINE_BUNDLE_UTIL_H_
#define BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_WIDEVINE_BUNDLE_UTIL_H_

#include "third_party/widevine/cdm/buildflags.h"

#if BUILDFLAG(BUNDLE_WIDEVINE_CDM)
void MaybeRegisterWidevineCdm();
#endif

#endif // BRAVE_BROWSER_UI_CONTENT_SETTINGS_BRAVE_WIDEVINE_BUNDLE_UTIL_H_
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

Expand All @@ -16,16 +17,23 @@
#include "brave/grit/brave_generated_resources.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/prefs/pref_service.h"
#include "third_party/widevine/cdm/buildflags.h"
#include "ui/base/l10n/l10n_util.h"

BraveWidevineContentSettingPluginBubbleModel::BraveWidevineContentSettingPluginBubbleModel(
#if BUILDFLAG(BUNDLE_WIDEVINE_CDM)
#include "brave/browser/ui/content_settings/brave_widevine_bundle_util.h"
#endif

BraveWidevineContentSettingPluginBubbleModel::
BraveWidevineContentSettingPluginBubbleModel(
ContentSettingBubbleModel::Delegate* delegate,
content::WebContents* web_contents) :
ContentSettingSimpleBubbleModel(delegate,
web_contents,
CONTENT_SETTINGS_TYPE_PLUGINS),
brave_content_settings_delegate_(
(BraveBrowserContentSettingBubbleModelDelegate*)delegate) {
reinterpret_cast<BraveBrowserContentSettingBubbleModelDelegate*>(
delegate)) {
SetTitle();
SetLearnMore();
SetMessage();
Expand All @@ -51,7 +59,16 @@ void BraveWidevineContentSettingPluginBubbleModel::RunPluginsOnPage() {

PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
prefs->SetBoolean(kWidevineOptedIn, true);
// This bubble model is used for bundle and component install of widevine.
// So, registering widevine as component is needed for component install.
#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT)
RegisterWidevineCdmComponent(g_brave_browser_process->component_updater());
#endif

#if BUILDFLAG(BUNDLE_WIDEVINE_CDM)
MaybeRegisterWidevineCdm();
#endif

ChromeSubresourceFilterClient::FromWebContents(web_contents())
->OnReloadRequested();
}
Expand Down
62 changes: 62 additions & 0 deletions chromium_src/content/browser/media/cdm_registry_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "build/build_config.h" // For OS_LINUX

#if defined(OS_LINUX)
#include "content/browser/media/cdm_registry_impl.h"

#include <algorithm>

#define Init Init_ChromiumImpl
#include "../../../../../content/browser/media/cdm_registry_impl.cc" // NOLINT
#undef Init

namespace content {

namespace {
// This leaks but would be fine.
CdmInfo* g_widevine_info = nullptr;
}

void CdmRegistryImpl::Init() {
Init_ChromiumImpl();

// On linux, we want to register widevine cdm to CdmRegistry when users opt
// in. Otherwise, widevine is initialized by default w/o user accept.
// So, widevine cdm is erased from |cdms_| and it is registered when users opt
// in. Also, we try to register it during the startup in
// BraveBrowserMainExtraParts::PreMainMessageLoopRun() by checking opted in
// prefs.
cdms_.erase(
std::remove_if(cdms_.begin(), cdms_.end(), [](const CdmInfo& info) {
// It would be better to use |kWidevineKeySystem| constant instead of
// using "com.widevine.alpha". To use constant, it requires adding
// widevine dependency to content module.
// However, using this string directly seems fine because it would not
// be changed and can avoid addtional patching for this.
if (info.supported_key_system == "com.widevine.alpha") {
DCHECK(!g_widevine_info);
// Cache upstream created info to reuse when brave wants to register
// it later.
g_widevine_info = new CdmInfo(info);
return true;
}
return false;
}),
cdms_.end());
}

const CdmInfo& CdmRegistryImpl::cached_widevine_cdm_info() const {
DCHECK(g_widevine_info);
return *g_widevine_info;
}

} // namespace content

#else // OS_LINUX
// This overridden file is only used on linux.
#include "../../../../../content/browser/media/cdm_registry_impl.cc" // NOLINT
#endif
Loading