-
Notifications
You must be signed in to change notification settings - Fork 892
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
Conversation
When widevine cdm is bundled, widevine cdm library is loaded into zygote process and To handle this, I tried to get If we also want to show content settings bubble in linux, I need to find how to prevent cdm initialization. Or if we can disable content bubble in linux, only first & second commits in this PR are needed. |
@simonhong This way, if any of user profiles has this preference enabled, we can somehow persist the fact that the binary should be loaded (e.g. create a marker file) and, for example, check it in |
With bundling, cdm loading and initialization is in separated phase. @iefremov As you said, we can't avoid loading. But, I thought we can control cdm service launching. However, I met multi profile issue and accessing profile_manager from io thread. So, I also want to know we should have same UX. If not, it can be achieved with simple patch. Only first & second commits are needed as I said earlier. IMO, current content setting bubble is not suitable because cdm library is already installed and loaded into process. It is just not initialized. |
With the 4th commit, widevine is only initialized after users allowed to use widevine via content settings bubble. |
c54c5f2
to
67b1a9f
Compare
I think this PR is ready to review. |
@bbondy Due to the restriction of zygote in linux, I enabled widevine by bundling. |
@@ -14,4 +15,7 @@ BraveBrowserMainExtraParts::~BraveBrowserMainExtraParts() { | |||
|
|||
void BraveBrowserMainExtraParts::PreMainMessageLoopRun() { | |||
brave::AutoImportMuon(); | |||
#if BUILDFLAG(BUNDLE_WIDEVINE_CDM) | |||
RegisterWidevineCdmToCdmRegistry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename -> MaybeRegister...
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also skip ToCdmRegistry
, sounds obvious :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. it's more clear 👍
@@ -7,7 +7,9 @@ | |||
#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) | |||
// On Windows and MacOS, widevine is supported by component updater. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if the comment is relevant here, maybe move it to the widevine.gni
patch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, widevine.gni
is better place for this comment.
Done.
void CdmRegistryImpl::Init() { | ||
+ // In linux, we want to register widevine cdm to CdmRegistry when users opted | ||
+ // in. If not, widevine is initialized by default. | ||
+ // Instead, we tries to register it in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a native speaker, but probably it should be "on linux", "when users opt in", "if not" -> otherwise, "we tries" -> "we try"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 👍
+ // Instead, we tries to register it in | ||
+ // BraveBrowserMainExtraParts::PreMainMessageLoopRun() by checking opted in | ||
+ // prefs. | ||
+#if defined(BRAVE_CHROMIUM_BUILD) && !defined(OS_LINUX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ENABLE_WIDEVINE_CDM_COMPONENT instead of !OS_LINUX ?
nevermind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering whether we potentially block CDMs other than Widevine on Linux?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch.
Actually, widevine alone is used for now but don't know in the future whether chrome registers more cdms.
So, fixed to exclude widevine only after getting cdms list.
Generally LGTM with small nits |
Created f/u issue - brave/brave-browser#3172 |
e7b50fe
to
481dc08
Compare
@@ -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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
bundle_widevine_cdm = enable_library_widevine_cdm && is_chrome_branded | ||
+if (brave_chromium_build) { | ||
+ # On brave linux, widevine is supported by bundle for now. | ||
+ # TODO(simonhong): Support by component update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind placing a follow-up issue number here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has this been vetted by @bbondy? We're specifically prohibited from bundling on other platforms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I discussed in dm and he agreed to do it as a next step. (long term)
|
||
const auto& cdms = cdm_registry->GetAllRegisteredCdms(); | ||
#if defined(OS_LINUX) | ||
EXPECT_EQ(cdms.size(), 0U); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in gtest macroses expected argument is the first, i.e. EXPECT_EQ(0u, cdms.size());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
}; | ||
|
||
// This test checks CdmRegistryImpl erases widevine from cdm list after fetching | ||
// cdm list from content client. This erase only happened on linux. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This erasure happens only on Linux
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
481dc08
to
c164607
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All done. PTAL.
Also this one - brave/brave-browser#3037
}; | ||
|
||
// This test checks CdmRegistryImpl erases widevine from cdm list after fetching | ||
// cdm list from content client. This erase only happened on linux. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
|
||
const auto& cdms = cdm_registry->GetAllRegisteredCdms(); | ||
#if defined(OS_LINUX) | ||
EXPECT_EQ(cdms.size(), 0U); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
bundle_widevine_cdm = enable_library_widevine_cdm && is_chrome_branded | ||
+if (brave_chromium_build) { | ||
+ # On brave linux, widevine is supported by bundle for now. | ||
+ # TODO(simonhong): Support by component update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
// Let embedders register CDMs. | ||
GetContentClient()->AddContentDecryptionModules(&cdms_, nullptr); | ||
+#if defined(BRAVE_CHROMIUM_BUILD) && defined(OS_LINUX) | ||
+ // On linux, we want to register widevine cdm to CdmRegistry when users opt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please do not add comments to patches. We want to minimize the size of patches
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this patch file was deleted by overriding.
#include "third_party/widevine/cdm/buildflags.h" | ||
|
||
-#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) | ||
+#if BUILDFLAG(ENABLE_WIDEVINE_CDM_COMPONENT) || BUILDFLAG(BUNDLE_WIDEVINE_CDM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why we're patching this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
W/o this patch in this file, reloading doesn't enable widevine after user accepts.
+ // in. Also, we try to register it during the startup in | ||
+ // BraveBrowserMainExtraParts::PreMainMessageLoopRun() by checking opted in | ||
+ // prefs. | ||
+ cdms_.erase( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why we're doing this here, why wouldn't we do it in AddContentDecryptionModules
where we don't have to patch anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems my reply was deleted after force push.
There are some places where original cmd list is needed like PreloadLibraryCdms()
.
So, we can't override ChromeContentClient::AddContentDecryptionModules()
.
Also, this patch is removed by file overriding.
content::CdmCapability capability; | ||
const base::Version cdm_version(WIDEVINE_CDM_VERSION_STRING); | ||
|
||
// Add the supported codecs as if they came from the component manifest. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems very fragile to me. Where did this list of codecs come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think so. I copied this logic from IsWidevineAvailable()
in chrome_content_client.cc
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah,, I think this can be improved by storing excluded cdminfo in CdmRegistry
in at some place and can be reused again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this log is deleted and used cached info from CdmRegistryImpl
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All duplicated code is deleted by caching CdmInfo that created by upstream.
81ca1a1
void CdmRegistryImpl::Init() { | ||
Init_ChromiumImpl(); | ||
|
||
#if defined(OS_LINUX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're missing what I was trying to say here. It calls GetContentClient()->AddContentDecryptionModules
and we can implement AddContentDecryptionModules
in BraveContentClient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that first.
But, other places needs original list like PreloadLibraryCdms()
in content_main_runner_impl.cc
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand, the result would be identical because it passes a reference that can be modified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChromeContentClient::AddContentDecryptionModules()
fills cdms to passed pointer.
Caller of above method will have different instance.
Of course, client of CdmRegistry
will see same list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, many comments were deleted..
Caller of AddContentDecryptionMoudles
maintains it's own cmd list.
Clients of CdmRegistry
see same list because CdmRegistry::GetAllRegisteredCdms()
returns list reference.
#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|. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
0b8a725
to
15bcb7c
Compare
In linux, WidevineCdm library is bundled instead of installing it by component updating during the runtime. In linux, we can't load cdm library during the runtime because processes except browser process are forked from zygote process not created from brave.exe. So, cdm should be loaded(not initialized) into zygote process space before zygote enters the sandbox. Chrome browser also uses bundling for linux.
In linux, widevine should be enabled only when user accpeted.
With this, widevine cdm is initialized when users allowed to use widevine cdm via content settings bubble.
In linux, bundled widevine cdm is loaded by default but not initialized by default. It is only initialized when user allows it. Then, widevine cdm is added to CdmRegistry. That means renderer should also update supported KeySystems during the runtime.
We only want to exclude widevine. So, exclude it explicitly from list.
This test checks CdmRegistryImpl erases widevine from cdm list after fetching cdm list from content client. This erase only happened on linux.
Instead, use cached CdmInfo from CdmRegistryImpl.
15bcb7c
to
81ca1a1
Compare
New PR (#1606) is opened for this. |
In linux, WidevineCdm library is bundled instead of installing it
by component updating during the runtime. In linux, we can't load
cdm library during the runtime because processes except browser
process are forked from zygote process not created from brave.exe.
So, cdm should be loaded(not initialized) into zygote process space
before zygote enters the sandbox.
Chrome browser also uses bundling for linux.
This PR should be merged with brave/brave-browser#3037
Fix brave/brave-browser#413
Submitter Checklist:
npm test brave_unit_tests && npm test brave_browser_tests
) ongit rebase master
(if needed).git rebase -i
to squash commits (if needed).Test Plan:
yarn test brave_unittest --filter=CdmRegistryImplTest.WidevineCdmExcludeTest
Reviewer Checklist: