Add files via upload

This commit is contained in:
Alexander David Frick 2021-10-26 05:16:41 -05:00 committed by GitHub
parent 4457bbc8ee
commit d3e95634ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
91 changed files with 15173 additions and 0 deletions

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" viewBox="0 0 1522 1522"><style>.e{fill:#fff}.a{stroke:#fff}.b{stop-color:#fff}.c{stop-color:#1a237e}.d{stop-opacity:0}.f{stop-opacity:.12}</style><rect id="d" width="1520" height="1520" rx="120"/><radialGradient id="f" cx="15%" cy="14%" r="100%"><stop class="b f" offset="0"/><stop class="b d" offset="1"/></radialGradient><radialGradient id="g" cx="-.2%" cy=".1%" r="136%"><stop class="c" offset="0" stop-opacity=".2"/><stop class="c d" offset="1"/></radialGradient><radialGradient id="h" cx="85%" cy="13%" r="154%"><stop class="c f" offset="0"/><stop class="c d" offset="1"/></radialGradient><radialGradient id="i" cx="41%" cy="0" r="57%"><stop class="c" offset="0" stop-opacity=".15"/><stop class="c d" offset="1"/></radialGradient><path id="a" d="M761 1361a600 600 0 1 0 0-1200 600 600 0 0 0 0 1200z"/><mask id="j" width="120" height="120" x="0" y="0" class="e"><use xlink:href="#a"/></mask><circle id="b" cx="761" cy="761" r="280"/><mask id="k" width="56" height="56" x="0" y="0" class="e"><use xlink:href="#b"/></mask><circle id="c" cx="761" cy="761" r="200"/><mask id="l" width="40" height="40" x="0" y="0" class="e"><use xlink:href="#c"/></mask><use fill="#2879ff" xlink:href="#d"/><g stroke-opacity=".2" stroke-width="5" class="a"><path d="m-199-199 1920 1920m0-1920L-199 1721M1038.5-199v1920m-555-1920v1920M1721 1038.5H-199m1920-555H-199"/><circle cx="761" cy="761" r="390"/><path d="M-199 761h1920M761-199v1920"/></g><circle cx="761" cy="761" r="600" fill="url(#f)"/><path d="M1400 0H120C54 0 0 54 0 120v10C0 64 54 10 120 10h1280c66 0 120 54 120 120v-10c0-66-54-120-120-120z" class="e" opacity=".2"/><path fill="#000" d="M1401 1511H121c-66 0-120-54-120-120v10c0 66 54 120 120 120h1280c66 0 120-54 120-120v-10c0 66-54 120-120 120z" opacity=".1"/><path fill="url(#g)" d="M495.9 675.8 251 431l267.2 458.3a273.7 273.7 0 0 1-22.4-213.5z"/><path fill="url(#h)" d="M820.7 1031 731 1365.6 996.6 901a274.2 274.2 0 0 1-176 130z"/><path fill="url(#i)" d="m962 575.3 334.2-89.3H759.7A273.7 273.7 0 1 0 962 575.3z"/><g stroke-width="40" class="a"><use mask="url(#j)" xlink:href="#a"/><use mask="url(#k)" xlink:href="#b"/><use mask="url(#l)" xlink:href="#c"/></g><path d="M761 481h530v20H761zm242.5 420-265 459-17.3-10 265-459zm-485 0-265-459 17.3-10 265 459z" class="e"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
COMPANY_FULLNAME=The Chromium and Thorium Authors
COMPANY_SHORTNAME=The Chromium and Thorium Authors
PRODUCT_FULLNAME=Thorium
PRODUCT_SHORTNAME=Thorium
PRODUCT_INSTALLER_FULLNAME=Thorium Installer
PRODUCT_INSTALLER_SHORTNAME=Thorium Installer
COPYRIGHT=Copyright @LASTCHANGE_YEAR@ The Chromium and Thorium Authors. All rights reserved.
MAC_BUNDLE_ID=org.chromium.Chromium
MAC_CREATOR_CODE=Cr24
MAC_TEAM_ID=

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

@ -0,0 +1,297 @@
/* XPM */
static char * product_logo_32_xpm[] = {
"32 32 262 2",
" c None",
". c #4E7ADB",
"+ c #4C78DB",
"@ c #4C79DB",
"# c #4A77DA",
"$ c #4B78DA",
"% c #4D7ADB",
"& c #4776DA",
"* c #4272D9",
"= c #4172D9",
"- c #4171D9",
"; c #4071D9",
"> c #3F70D8",
", c #3E6FD8",
"' c #3D6FD8",
") c #4775DA",
"! c #4F7BDC",
"~ c #4574DA",
"{ c #4474D9",
"] c #4373D9",
"^ c #3D6ED8",
"/ c #3C6ED8",
"( c #4675DA",
"_ c #4976D8",
": c #4575D9",
"< c #3B6DD8",
"[ c #3F6FD8",
"} c #4773D5",
"| c #4573D6",
"1 c #4574D8",
"2 c #3A6CD7",
"3 c #3C6DD7",
"4 c #4670D2",
"5 c #4471D4",
"6 c #4472D5",
"7 c #4473D7",
"8 c #4573D9",
"9 c #396CD7",
"0 c #3B6DD7",
"a c #456ECF",
"b c #436ED1",
"c c #446FD2",
"d c #4470D4",
"e c #4471D6",
"f c #4472D8",
"g c #396BD7",
"h c #3B6CD7",
"i c #6C9AEE",
"j c #4169CB",
"k c #426DCF",
"l c #436FD3",
"m c #4370D5",
"n c #4372D7",
"o c #4372D8",
"p c #6BA0F7",
"q c #5580D9",
"r c #416ACD",
"s c #426CCF",
"t c #426ED1",
"u c #426FD3",
"v c #4270D5",
"w c #4271D7",
"x c #4272D8",
"y c #4172D8",
"z c #3861BC",
"A c #294992",
"B c #243C74",
"C c #314070",
"D c #44568D",
"E c #5C72B4",
"F c #6F87CE",
"G c #7089D0",
"H c #728CD2",
"I c #748ED3",
"J c #7590D5",
"K c #7892D6",
"L c #7994D9",
"M c #7B97DB",
"N c #7E9ADE",
"O c #809DDF",
"P c #6EA1F7",
"Q c #699DF3",
"R c #4369C7",
"S c #406ACD",
"T c #416CD0",
"U c #416DD2",
"V c #416FD4",
"W c #4170D5",
"X c #3D69C9",
"Y c #1F3974",
"Z c #000000",
"` c #1D3A6B",
" . c #315CA3",
".. c #305BA3",
"+. c #1C3A6B",
"@. c #414E74",
"#. c #7D92CD",
"$. c #8099D8",
"%. c #829BDB",
"&. c #86A1DE",
"*. c #8AA6E2",
"=. c #8DA9E6",
"-. c #8FACE8",
";. c #91ADE9",
">. c #91AFEA",
",. c #95B2EC",
"'. c #6A9FF7",
"). c #6B9FF7",
"!. c #5B88E0",
"~. c #3D63C5",
"{. c #3F6ACE",
"]. c #406CD1",
"^. c #406ED3",
"/. c #3C68C7",
"(. c #11234C",
"_. c #203863",
":. c #457CD9",
"<. c #4E8DF5",
"[. c #4D8CF5",
"}. c #4C8CF5",
"|. c #427BD9",
"1. c #1F3863",
"2. c #2B354F",
"3. c #89A2DA",
"4. c #91ADE8",
"5. c #92AFEA",
"6. c #93B0EB",
"7. c #94B1EC",
"8. c #95B2ED",
"9. c #96B4ED",
"0. c #97B5EE",
"a. c #98B6EF",
"b. c #486FCC",
"c. c #3E65C7",
"d. c #3F6ACF",
"e. c #1F3872",
"f. c #4D8AF1",
"g. c #4C8BF5",
"h. c #4A88F1",
"i. c #1E3763",
"j. c #596888",
"k. c #96B3ED",
"l. c #98B5EF",
"m. c #99B7F0",
"n. c #9AB9F1",
"o. c #9BBAF2",
"p. c #9CBBF3",
"q. c #9DBCF5",
"r. c #699EF7",
"s. c #6393EB",
"t. c #3C63C5",
"u. c #3D65C9",
"v. c #365CB6",
"w. c #4B8BF5",
"x. c #407AD8",
"y. c #8DA6D7",
"z. c #9DBBF3",
"A. c #9EBCF4",
"B. c #9FBEF5",
"C. c #9FBFF6",
"D. c #A0C0F7",
"E. c #A1C1F8",
"F. c #A1C2F9",
"G. c #A2C3FA",
"H. c #4F7AD5",
"I. c #3C64C8",
"J. c #27438A",
"K. c #4A8AF4",
"L. c #498AF4",
"M. c #1B396A",
"N. c #778AB0",
"O. c #A2C1F8",
"P. c #A3C2F9",
"Q. c #A3C3F9",
"R. c #A3C3FA",
"S. c #689EF7",
"T. c #6599F1",
"U. c #3F66C8",
"V. c #23386F",
"W. c #2D59A2",
"X. c #75819B",
"Y. c #A4C4FA",
"Z. c #679DF7",
"`. c #5583DE",
" + c #24386F",
".+ c #4989F4",
"++ c #76829C",
"@+ c #A2C2FA",
"#+ c #679CF6",
"$+ c #669BF5",
"%+ c #335092",
"&+ c #1A386A",
"*+ c #7C8FB2",
"=+ c #A1C1F9",
"-+ c #669CF6",
";+ c #679DF6",
">+ c #5684D3",
",+ c #3F79D8",
"'+ c #97B1DF",
")+ c #A1C1FA",
"!+ c #3A588B",
"~+ c #4988F1",
"{+ c #4786F0",
"]+ c #1D3763",
"^+ c #64728E",
"/+ c #6194E9",
"(+ c #263B5E",
"_+ c #1D2D50",
":+ c #9FBAEC",
"<+ c #A1C2FA",
"[+ c #649AF4",
"}+ c #659BF6",
"|+ c #3B598B",
"1+ c #334D80",
"2+ c #83A2E1",
"3+ c #9FC0F8",
"4+ c #649BF6",
"5+ c #5B8BDA",
"6+ c #476CAB",
"7+ c #3C5888",
"8+ c #3F5A8A",
"9+ c #4A6AA8",
"0+ c #537ECE",
"a+ c #5F8CE5",
"b+ c #A2C0F7",
"c+ c #6399F4",
"d+ c #639AF6",
"e+ c #629AF6",
"f+ c #5E92EE",
"g+ c #5A8CE8",
"h+ c #8AACEE",
"i+ c #9EBFF7",
"j+ c #649AF5",
"k+ c #6299F6",
"l+ c #5B8FEB",
"m+ c #6994E8",
"n+ c #A0C1F9",
"o+ c #6399F5",
"p+ c #6096F3",
"q+ c #5B8DEA",
"r+ c #92B3F1",
"s+ c #6299F5",
"t+ c #6199F6",
"u+ c #5E94F1",
"v+ c #749CEB",
"w+ c #6198F5",
"x+ c #5B8FEC",
"y+ c #9BBCF6",
"z+ c #5F95F2",
"A+ c #5F96F2",
"B+ c #80A6EF",
"C+ c #9CBDF6",
"D+ c #6098F5",
"E+ c #6097F5",
"F+ c #6193EE",
"G+ c #9FC0F9",
"H+ c #9DBDF6",
"I+ c #5D93F1",
"J+ c #5B91EE",
"K+ c #82A6ED",
"L+ c #9DBDF5",
"M+ c #9CBCF5",
" ",
" . + @ + # $ ",
" % & * = = - ; > , ' - ) ",
" ! ~ { ] * * = - ; > , , ' ^ / ( ",
" _ : ~ { ] ] * = - ; > , , ' ^ / < [ ",
" } | 1 ~ { ] ] * = - ; > , , ' ^ / < 2 3 ",
" 4 5 6 7 8 { ] * * = - ; > , , ' ^ / < 2 9 0 ",
" a b c d e f { ] * = = - ; > , ' ' ^ / < 2 9 g h ",
" i j k b l m n o ] * = - - ; > , ' ^ ^ / < 2 9 g g [ ",
" p q r s t u v w x y z A B C D E F G H I J K L M N O ",
" P p Q R S T U V W X Y Z ` ...+.Z @.#.$.%.&.*.=.-.;.>.,. ",
" '.).).!.~.{.].^./.(._.:.<.[.[.}.|.1.2.3.4.5.6.7.8.9.0.a. ",
" '.'.'.).b.c.d.].e._.f.<.<.[.}.}.g.h.i.j.k.l.a.m.n.o.p.q. ",
" r.r.r.r.r.s.t.u.v.Z :.<.<.[.}.}.g.w.w.x.Z y.z.A.B.C.D.E.F.G. ",
" '.r.r.r.r.r.H.I.J.` <.<.[.}.}.g.g.w.K.L.M.N.O.P.Q.R.R.G.G.R. ",
" S.S.r.r.r.r.T.U.V. .[.[.}.}.g.g.w.K.K.L.W.X.Y.Y.R.R.R.G.G.G. ",
" Z.Z.S.S.S.S.S.`. +..[.}.}.g.g.w.K.K.L..+W.++Y.Y.R.R.G.G.G.@+ ",
" #+Z.Z.Z.Z.Z.Z.$+%++.}.g.g.g.w.K.K.L.L..+&+*+Y.R.R.R.G.G.@+=+ ",
" -+;+;+;+;+;+;+;+>+Z |.g.w.w.K.K.L.L..+,+Z '+R.R.R.G.G.G.@+)+ ",
" -+-+-+-+-+-+-+-+!+1.~+w.K.K.L.L..+{+]+^+Y.R.R.R.G.G.@+@+ ",
" -+-+-+-+-+-+-+-+/+(+1.x.L.L..+.+,+]+_+:+R.R.R.G.G.G.@+<+ ",
" [+}+-+-+-+}+}+}+}+/+|+Z M.W.W.&+Z 1+2+R.R.R.G.G.G.@+<+3+ ",
" }+}+}+}+}+4+4+4+4+}+5+6+7+8+9+0+a+b+R.R.G.G.G.@+@+<+ ",
" c+4+4+4+4+4+4+4+4+4+d+d+d+e+f+g+h+R.R.G.G.G.@+@+<+i+ ",
" j+4+4+4+4+4+d+d+d+d+e+e+k+l+m+P.R.G.G.G.@+@+<+n+ ",
" o+d+d+d+d+d+e+e+e+e+k+p+q+r+G.G.G.G.@+@+<+n+ ",
" s+e+e+e+e+e+k+k+k+t+u+v+R.G.G.G.@+@+<+n+ ",
" w+k+k+k+k+k+t+t+w+x+y+G.G.G.@+@+<+3+ ",
" z+t+t+t+t+t+t+A+B+G.G.@+@+<+<+C+ ",
" z+D+t+t+E+F+E.@+@+@+G+H+ ",
" I+J+K+L+H+M+ ",
" "};

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,417 @@
// Copyright 2020 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 "chrome/browser/net/stub_resolver_config_reader.h"
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/browser/net/secure_dns_util.h"
#include "chrome/browser/policy/chrome_browser_policy_connector.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "components/flags_ui/pref_service_flags_storage.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/network_service_instance.h"
#include "net/dns/public/secure_dns_mode.h"
#include "net/dns/public/util.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#include "chrome/browser/enterprise/util/android_enterprise_info.h"
#endif
#if defined(OS_WIN)
#include "base/enterprise_util.h"
#include "base/win/windows_version.h"
#include "chrome/browser/win/parental_controls.h"
#endif
namespace {
// Detailed descriptions of the secure DNS mode. These values are logged to UMA.
// Entries should not be renumbered and numeric values should never be reused.
// Please keep in sync with "SecureDnsModeDetails" in
// src/tools/metrics/histograms/enums.xml.
enum class SecureDnsModeDetailsForHistogram {
// The mode is controlled by the user and is set to 'off'.
kOffByUser = 0,
// The mode is controlled via enterprise policy and is set to 'off'.
kOffByEnterprisePolicy = 1,
// Chrome detected a managed environment and forced the mode to 'off'.
kOffByDetectedManagedEnvironment = 2,
// Chrome detected parental controls and forced the mode to 'off'.
kOffByDetectedParentalControls = 3,
// The mode is controlled by the user and is set to 'automatic' (the default
// mode).
kAutomaticByUser = 4,
// The mode is controlled via enterprise policy and is set to 'automatic'.
kAutomaticByEnterprisePolicy = 5,
// The mode is controlled by the user and is set to 'secure'.
kSecureByUser = 6,
// The mode is controlled via enterprise policy and is set to 'secure'.
kSecureByEnterprisePolicy = 7,
kMaxValue = kSecureByEnterprisePolicy,
};
#if defined(OS_WIN)
bool ShouldDisableDohForWindowsParentalControls() {
const WinParentalControls& parental_controls = GetWinParentalControls();
if (parental_controls.web_filter)
return true;
// Some versions before Windows 8 may not fully support |web_filter|, so
// conservatively disable doh for any recognized parental controls.
if (parental_controls.any_restrictions &&
base::win::GetVersion() < base::win::Version::WIN8) {
return true;
}
return false;
}
#endif // defined(OS_WIN)
// Check the AsyncDns field trial and return true if it should be enabled. On
// Android this includes checking the Android version in the field trial.
bool ShouldEnableAsyncDns() {
bool feature_can_be_enabled = true;
#if defined(OS_ANDROID)
int min_sdk =
base::GetFieldTrialParamByFeatureAsInt(features::kAsyncDns, "min_sdk", 0);
if (base::android::BuildInfo::GetInstance()->sdk_int() < min_sdk)
feature_can_be_enabled = false;
#endif
return feature_can_be_enabled &&
base::FeatureList::IsEnabled(features::kAsyncDns);
}
} // namespace
// static
constexpr base::TimeDelta StubResolverConfigReader::kParentalControlsCheckDelay;
StubResolverConfigReader::StubResolverConfigReader(PrefService* local_state,
bool set_up_pref_defaults)
: local_state_(local_state) {
base::RepeatingClosure pref_callback =
base::BindRepeating(&StubResolverConfigReader::UpdateNetworkService,
base::Unretained(this), false /* record_metrics */);
pref_change_registrar_.Init(local_state_);
// Update the DnsClient and DoH default preferences based on the corresponding
// features before registering change callbacks for these preferences.
// Changing prefs or defaults after registering change callbacks could result
// in reentrancy and mess up registration between this code and NetworkService
// creation.
if (set_up_pref_defaults) {
local_state_->SetDefaultPrefValue(prefs::kBuiltInDnsClientEnabled,
base::Value(ShouldEnableAsyncDns()));
net::SecureDnsMode default_secure_dns_mode = net::SecureDnsMode::kOff;
std::string default_doh_templates;
if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
if (features::kDnsOverHttpsFallbackParam.Get()) {
default_secure_dns_mode = net::SecureDnsMode::kAutomatic;
} else {
default_secure_dns_mode = net::SecureDnsMode::kSecure;
}
default_doh_templates = features::kDnsOverHttpsTemplatesParam.Get();
}
local_state_->SetDefaultPrefValue(
prefs::kDnsOverHttpsMode,
base::Value(SecureDnsConfig::ModeToString(default_secure_dns_mode)));
local_state_->SetDefaultPrefValue(prefs::kDnsOverHttpsTemplates,
base::Value(default_doh_templates));
// If the user has explicitly enabled or disabled the DoH experiment in
// chrome://flags and the DoH UI setting is not visible, store that choice
// in the user prefs so that it can be persisted after the experiment ends.
// Also make sure to remove the stored prefs value if the user has changed
// their chrome://flags selection to the default.
if (!features::kDnsOverHttpsShowUiParam.Get()) {
flags_ui::PrefServiceFlagsStorage flags_storage(local_state_);
std::set<std::string> entries = flags_storage.GetFlags();
if (entries.count("dns-over-https@1")) {
// The user has "Enabled" selected.
local_state_->SetString(prefs::kDnsOverHttpsMode,
SecureDnsConfig::kModeSecure);
} else if (entries.count("dns-over-https@2")) {
// The user has "Disabled" selected.
local_state_->SetString(prefs::kDnsOverHttpsMode,
SecureDnsConfig::kModeOff);
} else {
// The user has "Default" selected.
local_state_->ClearPref(prefs::kDnsOverHttpsMode);
}
}
}
pref_change_registrar_.Add(prefs::kBuiltInDnsClientEnabled, pref_callback);
pref_change_registrar_.Add(prefs::kDnsOverHttpsMode, pref_callback);
pref_change_registrar_.Add(prefs::kDnsOverHttpsTemplates, pref_callback);
pref_change_registrar_.Add(prefs::kAdditionalDnsQueryTypesEnabled,
pref_callback);
parental_controls_delay_timer_.Start(
FROM_HERE, kParentalControlsCheckDelay,
base::BindOnce(&StubResolverConfigReader::OnParentalControlsDelayTimer,
base::Unretained(this)));
#if defined(OS_ANDROID)
chrome::enterprise_util::AndroidEnterpriseInfo::GetInstance()
->GetAndroidEnterpriseInfoState(base::BindOnce(
&StubResolverConfigReader::OnAndroidOwnedStateCheckComplete,
weak_factory_.GetWeakPtr()));
#endif
}
StubResolverConfigReader::~StubResolverConfigReader() = default;
// static
void StubResolverConfigReader::RegisterPrefs(PrefRegistrySimple* registry) {
// Register the DnsClient and DoH preferences. The feature list has not been
// initialized yet, so setting the preference defaults here to reflect the
// corresponding features will only cause the preference defaults to reflect
// the feature defaults (feature values set via the command line will not be
// captured). Thus, the preference defaults are updated in the constructor
// for SystemNetworkContextManager, at which point the feature list is ready.
registry->RegisterBooleanPref(prefs::kBuiltInDnsClientEnabled, false);
registry->RegisterStringPref(prefs::kDnsOverHttpsMode, std::string());
registry->RegisterStringPref(prefs::kDnsOverHttpsTemplates, std::string());
registry->RegisterBooleanPref(prefs::kAdditionalDnsQueryTypesEnabled, true);
}
SecureDnsConfig StubResolverConfigReader::GetSecureDnsConfiguration(
bool force_check_parental_controls_for_automatic_mode) {
return GetAndUpdateConfiguration(
force_check_parental_controls_for_automatic_mode,
false /* record_metrics */, false /* update_network_service */);
}
void StubResolverConfigReader::UpdateNetworkService(bool record_metrics) {
GetAndUpdateConfiguration(
false /* force_check_parental_controls_for_automatic_mode */,
record_metrics, true /* update_network_service */);
}
bool StubResolverConfigReader::ShouldDisableDohForManaged() {
// This function ignores cloud policies which are loaded on a per-profile basis.
#if defined(OS_ANDROID)
// Check for MDM/management/owner apps. android_has_owner_ is true if either a
// device or policy owner app is discovered by
// GetAndroidEnterpriseInfoState(). If android_has_owner_ is nullopt, take a
// value of false so that we don't disable DoH during the async check.
// Because Android policies can only be loaded with owner apps this is
// sufficient to check for the prescences of policies as well.
if (android_has_owner_.value_or(false))
return true;
#elif defined(OS_WIN)
if (base::IsMachineExternallyManaged())
return true;
#endif
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
if (g_browser_process->browser_policy_connector()->HasMachineLevelPolicies())
return true;
#endif
return false;
}
bool StubResolverConfigReader::ShouldDisableDohForParentalControls() {
if (parental_controls_testing_override_.has_value())
return parental_controls_testing_override_.value();
#if defined(OS_WIN)
return ShouldDisableDohForWindowsParentalControls();
#else
return false;
#endif
}
void StubResolverConfigReader::OnParentalControlsDelayTimer() {
DCHECK(!parental_controls_delay_timer_.IsRunning());
// No need to act if parental controls were checked early.
if (parental_controls_checked_)
return;
parental_controls_checked_ = true;
// If parental controls are enabled, force a config change so secure DNS can
// be disabled.
if (ShouldDisableDohForParentalControls())
UpdateNetworkService(false /* record_metrics */);
}
bool StubResolverConfigReader::GetInsecureStubResolverEnabled() {
return local_state_->GetBoolean(prefs::kBuiltInDnsClientEnabled);
}
SecureDnsConfig StubResolverConfigReader::GetAndUpdateConfiguration(
bool force_check_parental_controls_for_automatic_mode,
bool record_metrics,
bool update_network_service) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
net::SecureDnsMode secure_dns_mode;
SecureDnsModeDetailsForHistogram mode_details;
SecureDnsConfig::ManagementMode forced_management_mode =
SecureDnsConfig::ManagementMode::kNoOverride;
bool is_managed =
local_state_->FindPreference(prefs::kDnsOverHttpsMode)->IsManaged();
if (!is_managed && ShouldDisableDohForManaged()) {
secure_dns_mode = net::SecureDnsMode::kOff;
forced_management_mode = SecureDnsConfig::ManagementMode::kDisabledManaged;
} else {
secure_dns_mode = SecureDnsConfig::ParseMode(
local_state_->GetString(prefs::kDnsOverHttpsMode))
.value_or(net::SecureDnsMode::kOff);
}
bool check_parental_controls = false;
if (secure_dns_mode == net::SecureDnsMode::kSecure) {
mode_details =
is_managed ? SecureDnsModeDetailsForHistogram::kSecureByEnterprisePolicy
: SecureDnsModeDetailsForHistogram::kSecureByUser;
// SECURE mode must always check for parental controls immediately (unless
// enabled through policy, which takes precedence over parental controls)
// because the mode allows sending DoH requests immediately.
check_parental_controls = !is_managed;
} else if (secure_dns_mode == net::SecureDnsMode::kAutomatic) {
mode_details =
is_managed
? SecureDnsModeDetailsForHistogram::kAutomaticByEnterprisePolicy
: SecureDnsModeDetailsForHistogram::kAutomaticByUser;
// To avoid impacting startup performance, AUTOMATIC mode should defer
// checking parental for a short period. This delay should have no practical
// effect on DoH queries because DoH enabling probes do not start until a
// longer period after startup.
bool allow_check_parental_controls =
force_check_parental_controls_for_automatic_mode ||
parental_controls_checked_;
check_parental_controls = !is_managed && allow_check_parental_controls;
} else {
switch (forced_management_mode) {
case SecureDnsConfig::ManagementMode::kNoOverride:
mode_details =
is_managed
? SecureDnsModeDetailsForHistogram::kOffByEnterprisePolicy
: SecureDnsModeDetailsForHistogram::kOffByUser;
break;
case SecureDnsConfig::ManagementMode::kDisabledManaged:
mode_details =
SecureDnsModeDetailsForHistogram::kOffByDetectedManagedEnvironment;
break;
case SecureDnsConfig::ManagementMode::kDisabledParentalControls:
NOTREACHED();
break;
default:
NOTREACHED();
}
// No need to check for parental controls if DoH is already disabled.
check_parental_controls = false;
}
// Check parental controls last because it can be expensive and should only be
// checked if necessary for the otherwise-determined mode.
if (check_parental_controls) {
if (ShouldDisableDohForParentalControls()) {
forced_management_mode =
SecureDnsConfig::ManagementMode::kDisabledParentalControls;
secure_dns_mode = net::SecureDnsMode::kOff;
mode_details =
SecureDnsModeDetailsForHistogram::kOffByDetectedParentalControls;
// If parental controls had not previously been checked, need to update
// network service.
if (!parental_controls_checked_)
update_network_service = true;
}
parental_controls_checked_ = true;
}
bool additional_dns_query_types_enabled =
local_state_->GetBoolean(prefs::kAdditionalDnsQueryTypesEnabled);
if (record_metrics) {
UMA_HISTOGRAM_ENUMERATION("Net.DNS.DnsConfig.SecureDnsMode", mode_details);
if (!additional_dns_query_types_enabled || ShouldDisableDohForManaged()) {
UMA_HISTOGRAM_BOOLEAN("Net.DNS.DnsConfig.AdditionalDnsQueryTypesEnabled",
additional_dns_query_types_enabled);
}
}
std::string doh_templates =
local_state_->GetString(prefs::kDnsOverHttpsTemplates);
std::string server_method;
std::vector<net::DnsOverHttpsServerConfig> dns_over_https_servers;
absl::optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>
servers_mojo;
if (!doh_templates.empty() && secure_dns_mode != net::SecureDnsMode::kOff) {
for (base::StringPiece server_template :
chrome_browser_net::secure_dns::SplitGroup(doh_templates)) {
if (!net::dns_util::IsValidDohTemplate(server_template, &server_method)) {
continue;
}
bool use_post = server_method == "POST";
dns_over_https_servers.emplace_back(std::string(server_template),
use_post);
if (!servers_mojo.has_value()) {
servers_mojo = absl::make_optional<
std::vector<network::mojom::DnsOverHttpsServerPtr>>();
}
network::mojom::DnsOverHttpsServerPtr server_mojo =
network::mojom::DnsOverHttpsServer::New();
server_mojo->server_template = std::string(server_template);
server_mojo->use_post = use_post;
servers_mojo->emplace_back(std::move(server_mojo));
}
}
if (update_network_service) {
content::GetNetworkService()->ConfigureStubHostResolver(
GetInsecureStubResolverEnabled(), secure_dns_mode,
std::move(servers_mojo), additional_dns_query_types_enabled);
}
return SecureDnsConfig(secure_dns_mode, std::move(dns_over_https_servers),
forced_management_mode);
}
#if defined(OS_ANDROID)
void StubResolverConfigReader::OnAndroidOwnedStateCheckComplete(
bool has_profile_owner,
bool has_device_owner) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
android_has_owner_ = has_profile_owner || has_device_owner;
// update the network service if the actual result is "true" to save time.
if (android_has_owner_.value())
UpdateNetworkService(false /* record_metrics */);
}
#endif

View file

@ -0,0 +1,36 @@
<!-- Copyright 2017 The Chromium Authors -->
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>thorium-browser.desktop</id>
<update_contact>chromium-dev@chromium.org</update_contact>
<metadata_license>CC0-1.0</metadata_license>
<project_license>BSD-3-Clause and LGPL-2.1+ and Apache-2.0 and IJG and MIT and GPL-2.0+ and ISC and OpenSSL and (MPL-1.1 or GPL-2.0 or LGPL-2.0)</project_license>
<name>Thorium Web Browser</name>
<summary>The web browser from the Chromium project</summary>
<description>
<p>
Chromium is an open-source browser project that aims to build a safer, faster,
and more stable way to experience the web.
</p>
<p>
We invite you to join our effort to build a powerful platform for developing a
new generation of web applications.
</p>
<p>
Chromium supports Vorbis, Theora, WebM and HTML5 audio and video standards, but
does not include the non-free AAC, H.264, MP3 or Adobe Flash code that is found
in Chrome.
</p>
</description>
<url type="homepage">https://www.chromium.org/Home</url>
<screenshots>
<screenshot type="default">
<image>https://www.gstatic.com/chrome/appstream/chrome-2.png</image>
<caption/>
</screenshot>
</screenshots>
<translation/>
<developer_name>The Chromium and Thorium Authors</developer_name>
<url type="bugtracker">https://www.chromium.org/for-testers/bug-reporting-guidelines</url>
<url type="help">https://chromium.googlesource.com/chromium/src/+/main/docs/linux/debugging.md</url>
</component>

View file

@ -0,0 +1,33 @@
# Copyright (c) 2009 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.
#
# This file provides common configuration information for building
# chromium-browser packages for various platforms.
# Base name of the package.
PACKAGE="thorium-browser"
# Base name of the snap package
SNAPNAME="thorium"
# Filename of the main executable (for generating launcher scripts, etc.)
PROGNAME=chrome
# Base directory for package installation.
INSTALLDIR=/opt/chromium.org/chromium
# Display string for desktop menu/icon.
MENUNAME="Thorium Web Browser"
# Brief package description.
SHORTDESC="The web browser from Chromium.org and The Thorium Authors"
# Detailed package description.
FULLDESC="Thorium is a browser that combines a minimal design with sophisticated technology to make the web faster, safer, and easier."
# Package maintainer information.
# TODO(mmoss) Setup a mailbox for this address
MAINTNAME="Thorium Linux Maintainers"
MAINTMAIL="alex313031@gmail.com"
PRODUCTURL="http://www.chromium.org/"

View file

@ -0,0 +1,275 @@
[Desktop Entry]
Version=1.0
Name=Thorium Web Browser
# Only KDE 4 seems to use GenericName, so we reuse the KDE strings.
# From Ubuntu's language-pack-kde-XX-base packages, version 9.04-20090413.
GenericName=Web Browser
GenericName[ar]=متصفح الشبكة
GenericName[bg]=Уеб браузър
GenericName[ca]=Navegador web
GenericName[cs]=WWW prohlížeč
GenericName[da]=Browser
GenericName[de]=Web-Browser
GenericName[el]=Περιηγητής ιστού
GenericName[en_GB]=Web Browser
GenericName[es]=Navegador web
GenericName[et]=Veebibrauser
GenericName[fi]=WWW-selain
GenericName[fr]=Navigateur Web
GenericName[gu]=વેબ બ્રાઉઝર
GenericName[he]=דפדפן אינטרנט
GenericName[hi]=वेब ब्राउज़र
GenericName[hu]=Webböngésző
GenericName[it]=Browser Web
GenericName[ja]=ウェブブラウザ
GenericName[kn]=ಜಾಲ ವೀಕ್ಷಕ
GenericName[ko]=웹 브라우저
GenericName[lt]=Žiniatinklio naršyklė
GenericName[lv]=Tīmekļa pārlūks
GenericName[ml]=വെബ് ബ്രൌസര്‍
GenericName[mr]=वेब ब्राऊजर
GenericName[nb]=Nettleser
GenericName[nl]=Webbrowser
GenericName[pl]=Przeglądarka WWW
GenericName[pt]=Navegador Web
GenericName[pt_BR]=Navegador da Internet
GenericName[ro]=Navigator de Internet
GenericName[ru]=Веб-браузер
GenericName[sl]=Spletni brskalnik
GenericName[sv]=Webbläsare
GenericName[ta]=இணைய உலாவி
GenericName[th]=เว็บเบราว์เซอร์
GenericName[tr]=Web Tarayıcı
GenericName[uk]=Навігатор Тенет
GenericName[zh_CN]=网页浏览器
GenericName[zh_HK]=網頁瀏覽器
GenericName[zh_TW]=網頁瀏覽器
# Not translated in KDE, from Epiphany 2.26.1-0ubuntu1.
GenericName[bn]=ওয়েব ব্রাউজার
GenericName[fil]=Web Browser
GenericName[hr]=Web preglednik
GenericName[id]=Browser Web
GenericName[or]=ଓ୍ବେବ ବ୍ରାଉଜର
GenericName[sk]=WWW prehliadač
GenericName[sr]=Интернет прегледник
GenericName[te]=మహాతల అన్వేషి
GenericName[vi]=Bộ duyệt Web
# Gnome and KDE 3 uses Comment.
Comment=Access the Internet
Comment[ar]=الدخول إلى الإنترنت
Comment[bg]=Достъп до интернет
Comment[bn]=ইন্টারনেটটি অ্যাক্সেস করুন
Comment[ca]=Accedeix a Internet
Comment[cs]=Přístup k internetu
Comment[da]=Få adgang til internettet
Comment[de]=Internetzugriff
Comment[el]=Πρόσβαση στο Διαδίκτυο
Comment[en_GB]=Access the Internet
Comment[es]=Accede a Internet.
Comment[et]=Pääs Internetti
Comment[fi]=Käytä internetiä
Comment[fil]=I-access ang Internet
Comment[fr]=Accéder à Internet
Comment[gu]=ઇંટરનેટ ઍક્સેસ કરો
Comment[he]=גישה אל האינטרנט
Comment[hi]=इंटरनेट तक पहुंच स्थापित करें
Comment[hr]=Pristup Internetu
Comment[hu]=Internetelérés
Comment[id]=Akses Internet
Comment[it]=Accesso a Internet
Comment[ja]=インターネットにアクセス
Comment[kn]=ಇಂಟರ್ನೆಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿ
Comment[ko]=인터넷 연결
Comment[lt]=Interneto prieiga
Comment[lv]=Piekļūt internetam
Comment[ml]=ഇന്റര്‍‌നെറ്റ് ആക്‌സസ് ചെയ്യുക
Comment[mr]=इंटरनेटमध्ये प्रवेश करा
Comment[nb]=Gå til Internett
Comment[nl]=Verbinding maken met internet
Comment[or]=ଇଣ୍ଟର୍ନେଟ୍ ପ୍ରବେଶ କରନ୍ତୁ
Comment[pl]=Skorzystaj z internetu
Comment[pt]=Aceder à Internet
Comment[pt_BR]=Acessar a internet
Comment[ro]=Accesaţi Internetul
Comment[ru]=Доступ в Интернет
Comment[sk]=Prístup do siete Internet
Comment[sl]=Dostop do interneta
Comment[sr]=Приступите Интернету
Comment[sv]=Gå ut på Internet
Comment[ta]=இணையத்தை அணுகுதல்
Comment[te]=ఇంటర్నెట్‌ను ఆక్సెస్ చెయ్యండి
Comment[th]=เข้าถึงอินเทอร์เน็ต
Comment[tr]=İnternet'e erişin
Comment[uk]=Доступ до Інтернету
Comment[vi]=Truy cập Internet
Comment[zh_CN]=访问互联网
Comment[zh_HK]=連線到網際網路
Comment[zh_TW]=連線到網際網路
Exec=/opt/chromium.org/chromium-unstable/chrome --show-component-extension-options --autoplay-policy=user-gesture-required --enable-features=VaapiVideoDecoder %U
StartupNotify=true
Terminal=false
Icon=@@PACKAGE@@
Type=Application
Categories=Network;WebBrowser;
MimeType=application/pdf;application/rdf+xml;application/rss+xml;application/xhtml+xml;application/xhtml_xml;application/xml;image/gif;image/jpeg;image/png;image/webp;text/html;text/xml;x-scheme-handler/http;x-scheme-handler/https;
Actions=new-window;new-private-window;
[Desktop Action new-window]
Name=New Window
Name[am]=አዲስ መስኮት
Name[ar]=نافذة جديدة
Name[bg]=Нов прозорец
Name[bn]=নতুন উইন্ডো
Name[ca]=Finestra nova
Name[cs]=Nové okno
Name[da]=Nyt vindue
Name[de]=Neues Fenster
Name[el]=Νέο Παράθυρο
Name[en_GB]=New Window
Name[es]=Nueva ventana
Name[et]=Uus aken
Name[fa]=پنجره جدید
Name[fi]=Uusi ikkuna
Name[fil]=New Window
Name[fr]=Nouvelle fenêtre
Name[gu]=નવી વિંડો
Name[hi]=नई विंडो
Name[hr]=Novi prozor
Name[hu]=Új ablak
Name[id]=Jendela Baru
Name[it]=Nuova finestra
Name[iw]=חלון חדש
Name[ja]=新規ウインドウ
Name[kn]=ಹೊಸ ವಿಂಡೊ
Name[ko]=새 창
Name[lt]=Naujas langas
Name[lv]=Jauns logs
Name[ml]=പുതിയ വിന്‍ഡോ
Name[mr]=नवीन विंडो
Name[nl]=Nieuw venster
Name[no]=Nytt vindu
Name[pl]=Nowe okno
Name[pt]=Nova janela
Name[pt_BR]=Nova janela
Name[ro]=Fereastră nouă
Name[ru]=Новое окно
Name[sk]=Nové okno
Name[sl]=Novo okno
Name[sr]=Нови прозор
Name[sv]=Nytt fönster
Name[sw]=Dirisha Jipya
Name[ta]=புதிய சாளரம்
Name[te]=క్రొత్త విండో
Name[th]=หน้าต่างใหม่
Name[tr]=Yeni Pencere
Name[uk]=Нове вікно
Name[vi]=Cửa sổ Mới
Name[zh_CN]=新建窗口
Name[zh_TW]=開新視窗
Exec=/opt/chromium.org/chromium-unstable/chrome --show-component-extension-options --autoplay-policy=user-gesture-required --enable-features=VaapiVideoDecoder
[Desktop Action content-shell]
Name=Open Content Shell
Name[am]=አዲስ መስኮት
Name[ar]=نافذة جديدة
Name[bg]=Нов прозорец
Name[bn]=নতুন উইন্ডো
Name[ca]=Finestra nova
Name[cs]=Nové okno
Name[da]=Nyt vindue
Name[de]=Neues Fenster
Name[el]=Νέο Παράθυρο
Name[en_GB]=New Window
Name[es]=Nueva ventana
Name[et]=Uus aken
Name[fa]=پنجره جدید
Name[fi]=Uusi ikkuna
Name[fil]=New Window
Name[fr]=Nouvelle fenêtre
Name[gu]=નવી વિંડો
Name[hi]=नई विंडो
Name[hr]=Novi prozor
Name[hu]=Új ablak
Name[id]=Jendela Baru
Name[it]=Nuova finestra
Name[iw]=חלון חדש
Name[ja]=新規ウインドウ
Name[kn]=ಹೊಸ ವಿಂಡೊ
Name[ko]=새 창
Name[lt]=Naujas langas
Name[lv]=Jauns logs
Name[ml]=പുതിയ വിന്‍ഡോ
Name[mr]=नवीन विंडो
Name[nl]=Nieuw venster
Name[no]=Nytt vindu
Name[pl]=Nowe okno
Name[pt]=Nova janela
Name[pt_BR]=Nova janela
Name[ro]=Fereastră nouă
Name[ru]=Новое окно
Name[sk]=Nové okno
Name[sl]=Novo okno
Name[sr]=Нови прозор
Name[sv]=Nytt fönster
Name[sw]=Dirisha Jipya
Name[ta]=புதிய சாளரம்
Name[te]=క్రొత్త విండో
Name[th]=หน้าต่างใหม่
Name[tr]=Yeni Pencere
Name[uk]=Нове вікно
Name[vi]=Cửa sổ Mới
Name[zh_CN]=新建窗口
Name[zh_TW]=開新視窗
Exec=/opt/chromium.org/chromium-unstable/content_shell
[Desktop Action new-private-window]
Name=New Incognito Window
Name[ar]=نافذة جديدة للتصفح المتخفي
Name[bg]=Нов прозорец „инкогнито“
Name[bn]=নতুন ছদ্মবেশী উইন্ডো
Name[ca]=Finestra d'incògnit nova
Name[cs]=Nové anonymní okno
Name[da]=Nyt inkognitovindue
Name[de]=Neues Inkognito-Fenster
Name[el]=Νέο παράθυρο για ανώνυμη περιήγηση
Name[en_GB]=New Incognito window
Name[es]=Nueva ventana de incógnito
Name[et]=Uus inkognito aken
Name[fa]=پنجره جدید حالت ناشناس
Name[fi]=Uusi incognito-ikkuna
Name[fil]=Bagong Incognito window
Name[fr]=Nouvelle fenêtre de navigation privée
Name[gu]=નવી છુપી વિંડો
Name[hi]=नई गुप्त विंडो
Name[hr]=Novi anoniman prozor
Name[hu]=Új Inkognitóablak
Name[id]=Jendela Penyamaran baru
Name[it]=Nuova finestra di navigazione in incognito
Name[iw]=חלון חדש לגלישה בסתר
Name[ja]=新しいシークレット ウィンドウ
Name[kn]=ಹೊಸ ಅಜ್ಞಾತ ವಿಂಡೋ
Name[ko]=새 시크릿 창
Name[lt]=Naujas inkognito langas
Name[lv]=Jauns inkognito režīma logs
Name[ml]=പുതിയ വേഷ പ്രച്ഛന്ന വിന്‍ഡോ
Name[mr]=नवीन गुप्त विंडो
Name[nl]=Nieuw incognitovenster
Name[no]=Nytt inkognitovindu
Name[pl]=Nowe okno incognito
Name[pt]=Nova janela de navegação anónima
Name[pt_BR]=Nova janela anônima
Name[ro]=Fereastră nouă incognito
Name[ru]=Новое окно в режиме инкогнито
Name[sk]=Nové okno inkognito
Name[sl]=Novo okno brez beleženja zgodovine
Name[sr]=Нови прозор за прегледање без архивирања
Name[sv]=Nytt inkognitofönster
Name[ta]=புதிய மறைநிலைச் சாளரம்
Name[te]=క్రొత్త అజ్ఞాత విండో
Name[th]=หน้าต่างใหม่ที่ไม่ระบุตัวตน
Name[tr]=Yeni Gizli pencere
Name[uk]=Нове вікно в режимі анонімного перегляду
Name[vi]=Cửa sổ ẩn danh mới
Name[zh_CN]=新建隐身窗口
Name[zh_TW]=新增無痕式視窗
Exec=/opt/chromium.org/chromium-unstable/chrome --incognito --show-component-extension-options --autoplay-policy=user-gesture-required --enable-features=VaapiVideoDecoder

View file

@ -0,0 +1,449 @@
# Shows the output of a given command only on failure, or when VERBOSE is set.
log_cmd() {
if [ "${VERBOSE:-}" ]; then
"$@"
else
# Record $- into a separate variable because it gets reset in the subshell.
FORWARD_SHELL_OPTS=$-
ERREXIT=$(echo ${FORWARD_SHELL_OPTS} | grep -o e || true)
set +${ERREXIT}
CMD_OUTPUT=$("$@" 2>&1)
ERRCODE=$?
set -${ERREXIT}
if [ ${ERRCODE} -ne 0 ]; then
echo "$@"
echo "${CMD_OUTPUT}"
if [ ${ERREXIT} ]; then
exit ${ERRCODE}
fi
fi
fi
}
# Recursively replace @@include@@ template variables with the referenced file,
# and write the resulting text to stdout.
process_template_includes() {
INCSTACK+="$1->"
# Includes are relative to the file that does the include.
INCDIR=$(dirname $1)
# Clear IFS so 'read' doesn't trim whitespace
local OLDIFS="$IFS"
IFS=''
while read -r LINE
do
INCLINE=$(sed -e '/^[[:space:]]*@@include@@/!d' <<<$LINE)
if [ -n "$INCLINE" ]; then
INCFILE=$(echo $INCLINE | sed -e "s#@@include@@\(.*\)#\1#")
# Simple filename match to detect cyclic includes.
CYCLE=$(sed -e "\#$INCFILE#"'!d' <<<$INCSTACK)
if [ "$CYCLE" ]; then
echo "ERROR: Possible cyclic include detected." 1>&2
echo "$INCSTACK$INCFILE" 1>&2
exit 1
fi
if [ ! -r "$INCDIR/$INCFILE" ]; then
echo "ERROR: Couldn't read include file: $INCDIR/$INCFILE" 1>&2
exit 1
fi
process_template_includes "$INCDIR/$INCFILE"
else
echo "$LINE"
fi
done < "$1"
IFS="$OLDIFS"
INCSTACK=${INCSTACK%"$1->"}
}
# Replace template variables (@@VARNAME@@) in the given template file. If a
# second argument is given, save the processed text to that filename, otherwise
# modify the template file in place.
process_template() (
# Don't worry if some of these substitution variables aren't set.
# Note that this function is run in a sub-shell so we don't leak this
# setting, since we still want unbound variables to be an error elsewhere.
set +u
local TMPLIN="$1"
if [ -z "$2" ]; then
local TMPLOUT="$TMPLIN"
else
local TMPLOUT="$2"
fi
# Process includes first so included text also gets substitutions.
TMPLINCL="$(process_template_includes "$TMPLIN")"
sed \
-e "s#@@PACKAGE@@#${PACKAGE}#g" \
-e "s#@@PACKAGE_ORIG@@#${PACKAGE_ORIG}#g" \
-e "s#@@PACKAGE_FILENAME@@#${PACKAGE_FILENAME}#g" \
-e "s#@@SNAPNAME@@#${SNAPNAME}#g" \
-e "s#@@PROGNAME@@#${PROGNAME}#g" \
-e "s#@@CHANNEL@@#${CHANNEL}#g" \
-e "s#@@COMPANY_FULLNAME@@#${COMPANY_FULLNAME}#g" \
-e "s#@@VERSION@@#${VERSION}#g" \
-e "s#@@PACKAGE_RELEASE@@#${PACKAGE_RELEASE}#g" \
-e "s#@@VERSIONFULL@@#${VERSIONFULL}#g" \
-e "s#@@INSTALLDIR@@#${INSTALLDIR}#g" \
-e "s#@@BUILDDIR@@#${OUTPUTDIR}#g" \
-e "s#@@STAGEDIR@@#${STAGEDIR}#g" \
-e "s#@@SCRIPTDIR@@#${SCRIPTDIR}#g" \
-e "s#@@MENUNAME@@#${MENUNAME}#g" \
-e "s#@@PRODUCTURL@@#${PRODUCTURL}#g" \
-e "s#@@PREDEPENDS@@#${PREDEPENDS}#g" \
-e "s#@@DEPENDS@@#${DEPENDS}#g" \
-e "s#@@RECOMMENDS@@#${RECOMMENDS}#g" \
-e "s#@@PROVIDES@@#${PROVIDES}#g" \
-e "s#@@ARCHITECTURE@@#${ARCHITECTURE}#g" \
-e "s#@@MAINTNAME@@#${MAINTNAME}#g" \
-e "s#@@MAINTMAIL@@#${MAINTMAIL}#g" \
-e "s#@@REPOCONFIG@@#${REPOCONFIG}#g" \
-e "s#@@REPOCONFIGREGEX@@#${REPOCONFIGREGEX}#g" \
-e "s#@@SHORTDESC@@#${SHORTDESC}#g" \
-e "s#@@FULLDESC@@#${FULLDESC}#g" \
-e "s#@@USR_BIN_SYMLINK_NAME@@#${USR_BIN_SYMLINK_NAME:-}#g" \
-e "s#@@LOGO_RESOURCES_PNG@@#${LOGO_RESOURCES_PNG}#g" \
-e "s#@@LOGO_RESOURCE_XPM@@#${LOGO_RESOURCE_XPM}#g" \
-e "s#@@DATE_RFC5322@@#$(date --rfc-email)#g" \
> "$TMPLOUT" <<< "$TMPLINCL"
)
# Setup the installation directory hierarchy in the package staging area.
prep_staging_common() {
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}" \
"${STAGEDIR}/usr/bin" \
"${STAGEDIR}/usr/share/applications" \
"${STAGEDIR}/usr/share/appdata" \
"${STAGEDIR}/usr/share/gnome-control-center/default-apps" \
"${STAGEDIR}/usr/share/man/man1"
}
get_version_info() {
source "${OUTPUTDIR}/installer/version.txt"
VERSION="${MAJOR}.${MINOR}.${BUILD}.${PATCH}"
# TODO(phajdan.jr): Provide a mechanism to pass a different package
# release number if needed. The meaning of it is to bump it for
# packaging-only changes while the underlying software has the same version.
# This corresponds to the Release field in RPM spec files and debian_revision
# component of the Version field for DEB control file.
# Generally with Chrome's fast release cycle it'd be more hassle to try
# to bump this number between releases.
PACKAGE_RELEASE="1"
}
stage_install_common() {
log_cmd echo "Staging common install files in '${STAGEDIR}'..."
# Note: Changes here may also need to be applied to ChromeOS's
# chromite/lib/chrome_util.py.
# Note: This only supports static binaries and does not work when the GN
# is_component_build flag is true.
# app
STRIPPEDFILE="${OUTPUTDIR}/${PROGNAME}.stripped"
install -m 755 "${STRIPPEDFILE}" "${STAGEDIR}/${INSTALLDIR}/${PROGNAME}"
# crashpad
buildfile="${OUTPUTDIR}/chrome_crashpad_handler"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/chrome_crashpad_handler"
# resources
install -m 644 "${OUTPUTDIR}/resources.pak" "${STAGEDIR}/${INSTALLDIR}/"
# TODO(mmoss): This has broken a couple times on adding new .pak files. Maybe
# we should flag all installer files in FILES.cfg and get them from there, so
# there's only one place people need to keep track of such things (and in
# only the public repository).
if [ -r "${OUTPUTDIR}/chrome_100_percent.pak" ]; then
install -m 644 "${OUTPUTDIR}/chrome_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/"
install -m 644 "${OUTPUTDIR}/chrome_200_percent.pak" "${STAGEDIR}/${INSTALLDIR}/"
else
install -m 644 "${OUTPUTDIR}/theme_resources_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/"
install -m 644 "${OUTPUTDIR}/ui_resources_100_percent.pak" "${STAGEDIR}/${INSTALLDIR}/"
fi
# ICU data file; Necessary when the GN icu_use_data_file flag is true.
install -m 644 "${OUTPUTDIR}/icudtl.dat" "${STAGEDIR}/${INSTALLDIR}/"
# V8 snapshot files; Necessary when the GN v8_use_external_startup_data flag
# is true.
# Use v8_context_snapshot.bin instead of snapshot_blob.bin if it is available.
# TODO(crbug.com/764576): Unship snapshot_blob.bin on ChromeOS and drop this branch
if [ -f "${OUTPUTDIR}/v8_context_snapshot.bin" ]; then
install -m 644 "${OUTPUTDIR}/v8_context_snapshot.bin" "${STAGEDIR}/${INSTALLDIR}/"
else
install -m 644 "${OUTPUTDIR}/snapshot_blob.bin" "${STAGEDIR}/${INSTALLDIR}/"
fi
# sandbox
# Rename sandbox binary with hyphen instead of underscore because that's what
# the code looks for. Originally, the SCons build system may have had a bug
# where it did not support hyphens, so this is stuck as is to avoid breaking
# anyone who expects the build artifact to have the underscore.
# the code looks for, but the build targets can't use hyphens (scons bug?)
buildfile="${OUTPUTDIR}/${PROGNAME}_sandbox"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m 4755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/chrome-sandbox"
# l10n paks
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/locales/"
find "${OUTPUTDIR}/locales" -type f -name '*.pak' -exec \
cp -a '{}' "${STAGEDIR}/${INSTALLDIR}/locales/" \;
find "${STAGEDIR}/${INSTALLDIR}/locales" -type f -exec chmod 644 '{}' \;
# TODO(https://crbug.com/1077934): The below conditions check for the
# existence of files to determine if they should be copied to the staging
# directory. However, these may be stale if the build config no longer
# builds these files. The build config should be obtained from gn rather than
# guessed based on the presence of files.
# MEI Preload
if [ -f "${OUTPUTDIR}/MEIPreload/manifest.json" ]; then
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
install -m 644 "${OUTPUTDIR}/MEIPreload/manifest.json" "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
install -m 644 "${OUTPUTDIR}/MEIPreload/preloaded_data.pb" "${STAGEDIR}/${INSTALLDIR}/MEIPreload/"
fi
# Widevine CDM.
if [ -d "${OUTPUTDIR}/WidevineCdm" ]; then
# No need to strip; libwidevinecdm.so starts out stripped.
cp -a "${OUTPUTDIR}/WidevineCdm" "${STAGEDIR}/${INSTALLDIR}/"
find "${STAGEDIR}/${INSTALLDIR}/WidevineCdm" -type d -exec chmod 755 '{}' \;
find "${STAGEDIR}/${INSTALLDIR}/WidevineCdm" -type f -exec chmod 644 '{}' \;
find "${STAGEDIR}/${INSTALLDIR}/WidevineCdm" -name libwidevinecdm.so \
-exec chmod ${SHLIB_PERMS} '{}' \;
fi
# ANGLE
if [ -f "${OUTPUTDIR}/libEGL.so" ]; then
for file in libEGL.so libGLESv2.so; do
buildfile="${OUTPUTDIR}/${file}"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m ${SHLIB_PERMS} "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
done
fi
# ANGLE's libvulkan library
if [ -f "${OUTPUTDIR}/libvulkan.so.1" ]; then
file="libvulkan.so.1"
buildfile="${OUTPUTDIR}/${file}"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
fi
# SwiftShader ES
if [ -f "${OUTPUTDIR}/swiftshader/libEGL.so" ]; then
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/swiftshader/"
for file in libEGL.so libGLESv2.so; do
buildfile="${OUTPUTDIR}/swiftshader/${file}"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m ${SHLIB_PERMS} "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/swiftshader/${file}"
done
fi
# SwiftShader VK
if [ -f "${OUTPUTDIR}/libvk_swiftshader.so" ]; then
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/"
file="libvk_swiftshader.so"
buildfile="${OUTPUTDIR}/${file}"
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m ${SHLIB_PERMS} "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
# Install the ICD json file to point ANGLE to libvk_swiftshader.so
install -m 644 "${OUTPUTDIR}/vk_swiftshader_icd.json" "${STAGEDIR}/${INSTALLDIR}/"
fi
# libc++
if [ -f "${OUTPUTDIR}/lib/libc++.so" ]; then
install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/"
install -m ${SHLIB_PERMS} -s "${OUTPUTDIR}/lib/libc++.so" "${STAGEDIR}/${INSTALLDIR}/lib/"
fi
# nacl_helper and nacl_helper_bootstrap
# Don't use "-s" (strip) because this runs binutils "strip", which
# mangles the special ELF program headers of nacl_helper_bootstrap.
# Explicitly use eu-strip instead, because it doesn't have that problem.
for file in nacl_helper nacl_helper_bootstrap; do
buildfile="${OUTPUTDIR}/${file}"
if [ -f "${buildfile}" ]; then
strippedfile="${buildfile}.stripped"
debugfile="${buildfile}.debug"
"${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
fi
done
# Don't use "-s" (strip) because this would use the Linux toolchain to
# strip the NaCl binary, which has the potential to break it. It
# certainly resets the OSABI and ABIVERSION fields to non-NaCl values,
# although the NaCl IRT loader doesn't care about these fields. In any
# case, the IRT binaries are already stripped by NaCl's build process.
for filename in ${OUTPUTDIR}/nacl_irt_*.nexe; do
# Re-check the filename in case globbing matched nothing.
if [ -f "$filename" ]; then
install -m 644 "$filename" "${STAGEDIR}/${INSTALLDIR}/`basename "$filename"`"
fi
done
# default apps
if [ -d "${OUTPUTDIR}/default_apps" ]; then
cp -a "${OUTPUTDIR}/default_apps" "${STAGEDIR}/${INSTALLDIR}/"
find "${STAGEDIR}/${INSTALLDIR}/default_apps" -type d -exec chmod 755 '{}' \;
find "${STAGEDIR}/${INSTALLDIR}/default_apps" -type f -exec chmod 644 '{}' \;
fi
# launcher script and symlink
process_template "${OUTPUTDIR}/installer/common/wrapper" \
"${STAGEDIR}/${INSTALLDIR}/${PACKAGE}"
chmod 755 "${STAGEDIR}/${INSTALLDIR}/${PACKAGE}"
if [ ! -z "${PACKAGE_ORIG}" ]; then
if [ ! -f "${STAGEDIR}/${INSTALLDIR}/${PACKAGE_ORIG}" ]; then
ln -sn "${INSTALLDIR}/${PACKAGE}" \
"${STAGEDIR}/${INSTALLDIR}/${PACKAGE_ORIG}"
fi
fi
if [ ! -z "${USR_BIN_SYMLINK_NAME}" ]; then
ln -snf "${INSTALLDIR}/${PACKAGE}" \
"${STAGEDIR}/usr/bin/${USR_BIN_SYMLINK_NAME}"
fi
# app icons
local icon_regex=".*product_logo_[0-9]\+\."
if [ "$BRANDING" = "google_chrome" ]; then
if [ "$CHANNEL" = "beta" ]; then
icon_regex=".*product_logo_[0-9]\+_beta\."
elif [ "$CHANNEL" = "unstable" ]; then
icon_regex=".*product_logo_[0-9]\+_dev\."
fi
fi
LOGO_RESOURCES_PNG=$(find "${OUTPUTDIR}/installer/theme/" \
-regextype sed -regex "${icon_regex}png" -printf "%f ")
LOGO_RESOURCE_XPM=$(find "${OUTPUTDIR}/installer/theme/" \
-regextype sed -regex "${icon_regex}xpm" -printf "%f")
for logo in ${LOGO_RESOURCES_PNG} ${LOGO_RESOURCE_XPM}; do
install -m 644 \
"${OUTPUTDIR}/installer/theme/${logo}" \
"${STAGEDIR}/${INSTALLDIR}/"
done
# desktop integration
install -m 755 "${OUTPUTDIR}/xdg-mime" "${STAGEDIR}${INSTALLDIR}/"
install -m 755 "${OUTPUTDIR}/xdg-settings" "${STAGEDIR}${INSTALLDIR}/"
if [ ${PACKAGE:0:6} = google ]; then
process_template "${OUTPUTDIR}/installer/common/google-chrome.appdata.xml.template" \
"${STAGEDIR}/usr/share/appdata/${PACKAGE}.appdata.xml"
chmod 644 "${STAGEDIR}/usr/share/appdata/${PACKAGE}.appdata.xml"
else
install -m 644 "${OUTPUTDIR}/installer/common/chromium-browser.appdata.xml" \
"${STAGEDIR}/usr/share/appdata/${PACKAGE}.appdata.xml"
fi
process_template "${OUTPUTDIR}/installer/common/desktop.template" \
"${STAGEDIR}/usr/share/applications/${PACKAGE}.desktop"
chmod 644 "${STAGEDIR}/usr/share/applications/${PACKAGE}.desktop"
process_template "${OUTPUTDIR}/installer/common/default-app.template" \
"${STAGEDIR}/usr/share/gnome-control-center/default-apps/${PACKAGE}.xml"
chmod 644 "${STAGEDIR}/usr/share/gnome-control-center/default-apps/${PACKAGE}.xml"
process_template "${OUTPUTDIR}/installer/common/default-app-block.template" \
"${STAGEDIR}${INSTALLDIR}/default-app-block"
chmod 644 "${STAGEDIR}${INSTALLDIR}/default-app-block"
# documentation
process_template "${OUTPUTDIR}/installer/common/manpage.1.in" \
"${STAGEDIR}/usr/share/man/man1/${USR_BIN_SYMLINK_NAME}.1"
gzip -9n "${STAGEDIR}/usr/share/man/man1/${USR_BIN_SYMLINK_NAME}.1"
chmod 644 "${STAGEDIR}/usr/share/man/man1/${USR_BIN_SYMLINK_NAME}.1.gz"
# The stable channel allows launching the app without the "-stable"
# suffix like the other channels. Create a linked man page for the
# app-without-the-channel case.
if [ ! -f "${STAGEDIR}/usr/share/man/man1/${PACKAGE}.1.gz" ]; then
ln -s "${USR_BIN_SYMLINK_NAME}.1.gz" \
"${STAGEDIR}/usr/share/man/man1/${PACKAGE}.1.gz"
fi
# Check to make sure all the ELF binaries are stripped.
UNSTRIPPED=$(find "${STAGEDIR}/${INSTALLDIR}/" -type f | xargs file |
grep ELF | grep -c "not stripped" || true)
if [ "${UNSTRIPPED}" != "0" ]; then
echo "ERROR: Found ${UNSTRIPPED} unstripped ELF files." 1>&2
exit 1
fi
# Check to make sure no ELF binaries set RPATH.
if [ "${TARGET_OS}" != "chromeos" ]; then
RPATH_BINS=
for elf in $(find "${STAGEDIR}/${INSTALLDIR}/" -type f | xargs file |
grep ELF | awk '{print $1;}' | sed 's/:$//'); do
if readelf -d ${elf} | grep "(RPATH)" >/dev/null; then
RPATH_BINS="${RPATH_BINS} $(basename ${elf})"
fi
done
if [ -n "${RPATH_BINS}" ]; then
echo "ERROR: Found binaries with RPATH set:${RPATH_BINS}" 1>&2
exit 1
fi
fi
# Make sure ELF binaries live in INSTALLDIR exclusively.
ELF_OUTSIDE_INSTALLDIR=$(find "${STAGEDIR}/" -not -path \
"${STAGEDIR}${INSTALLDIR}/*" -type f | xargs file -b |
grep -ce "^ELF" || true)
if [ "${ELF_OUTSIDE_INSTALLDIR}" -ne 0 ]; then
echo "ERROR: Found ${ELF_OUTSIDE_INSTALLDIR} ELF binaries" \
"outside of ${INSTALLDIR}" 1>&2
exit 1
fi
# Verify file permissions.
for file in $(find "${STAGEDIR}" -mindepth 1); do
local actual_perms=$(stat -c "%a" "${file}")
local file_type="$(file -b "${file}")"
local base_name=$(basename "${file}")
if [[ "${file_type}" = "directory"* ]]; then
local expected_perms=755
elif [[ "${file_type}" = *"symbolic link"* ]]; then
if [[ "$(readlink ${file})" = "/"* ]]; then
# Absolute symlink.
local expect_exists="${STAGEDIR}/$(readlink "${file}")"
else
# Relative symlink.
local expect_exists="$(dirname "${file}")/$(readlink "${file}")"
fi
if [ ! -f "${expect_exists}" ]; then
echo "Broken symlink: ${file}" 1>&2
exit 1
fi
local expected_perms=777
elif [ "${base_name}" = "chrome-sandbox" ]; then
local expected_perms=4755
elif [[ "${base_name}" = "nacl_irt_"*".nexe" ]]; then
local expected_perms=644
elif [[ "${file_type}" = *"shell script"* ]]; then
local expected_perms=755
elif [[ "${file_type}" = ELF* ]]; then
if [[ "${base_name}" = *".so" ]]; then
local expected_perms=${SHLIB_PERMS}
else
local expected_perms=755
fi
else
# Regular data file.
local expected_perms=644
fi
if [ ${expected_perms} -ne ${actual_perms} ]; then
echo Expected permissions on ${base_name} to be \
${expected_perms}, but they were ${actual_perms} 1>&2
exit 1
fi
done
}

View file

@ -0,0 +1,6 @@
?package(@@USR_BIN_SYMLINK_NAME@@):needs="x11" \
section="Applications/Network/Web Browsing" \
hints="Web browsers" \
title="Thorium Browser" \
icon="@@INSTALLDIR@@/@@LOGO_RESOURCE_XPM@@" \
command="@@INSTALLDIR@@/@@PACKAGE@@"

View file

@ -0,0 +1,21 @@
# Copyright 2019 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.
#
# Recommended dependencies not in the dpkg-shlibdeps output.
# u2f udev rules have moved from being installed by default by systemd on Debian
# systems to a separate package called libu2f-udev. Pull it in manually so that
# u2f keys will work. TODO(https://crbug.com/784010): Move this to "Depends"
# once support for Jessie, Stretch, Trusty, and Xenial are dropped.
libu2f-udev
# Try to use Vulkan when possible. libvulkan1 is not available on Ubuntu Trusty
# or Debian Jessie, so it is added to "Recommends" instead of "Depends".
# TODO(https://crbug.com/784010): Move this to "Depends" once support for
# Trusty and Jessie are dropped. Note that the dependency must still be manually
# added since the library is dlopen()'ed.
libvulkan1
#Add unrar for unrar support
unrar

147
content/gpu/BUILD.gn Normal file
View file

@ -0,0 +1,147 @@
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
import("//media/media_options.gni")
import("//media/gpu/args.gni")
# See //content/BUILD.gn for how this works.
group("gpu") {
visibility = [ "//content/*" ] # This is an internal content API.
if (is_component_build) {
public_deps = [ "//content" ]
} else {
public_deps = [ ":gpu_sources" ]
}
}
if (is_component_build) {
link_target_type = "source_set"
} else {
link_target_type = "static_library"
}
target(link_target_type, "gpu_sources") {
# This is an internal content API. Code outside of the content "component"
# (like content/test and content/shell) should depend on ":gpu" above.
visibility = [ "//content/*" ]
sources = [
"browser_exposed_gpu_interfaces.cc",
"browser_exposed_gpu_interfaces.h",
"gpu_child_thread.cc",
"gpu_child_thread.h",
"gpu_child_thread_receiver_bindings.cc",
"gpu_main.cc",
"gpu_process.cc",
"gpu_process.h",
"gpu_service_factory.cc",
"gpu_service_factory.h",
"in_process_gpu_thread.cc",
"in_process_gpu_thread.h",
]
configs += [ "//content:content_implementation" ]
deps = [
"//base",
"//base/third_party/dynamic_annotations",
"//build:branding_buildflags",
"//build:chromeos_buildflags",
"//components/viz/service",
"//content:export",
"//content/child",
"//content/common",
"//content/common:mojo_bindings",
"//content/public/child:child_sources",
"//content/public/common:common_sources",
"//gpu:gpu",
"//gpu/ipc/common:command_buffer_traits",
"//gpu/ipc/service",
"//ipc",
"//media:media_buildflags",
"//media/gpu",
"//media/mojo:buildflags",
# TODO(jrummell): As //media/gpu/ipc/service is a source_set in a
# component build, determine if it should not be included here.
# http://crbug.com/702833.
"//components/viz/service/main",
"//media/gpu/ipc/service",
"//media/mojo/clients:clients",
"//sandbox/policy:chromecast_sandbox_allowlist_buildflags",
"//services/service_manager/public/cpp",
"//services/service_manager/public/mojom",
"//services/tracing/public/cpp",
"//services/viz/privileged/mojom",
"//skia",
"//third_party/angle:angle_gpu_info_util",
"//ui/gfx/ipc",
"//ui/gl",
"//ui/gl/init",
"//ui/latency/ipc",
]
if (!is_chromeos_ash || !is_chrome_branded) {
deps += [
"//services/shape_detection:lib",
"//services/shape_detection/public/mojom",
]
}
if (is_linux || is_chromeos) {
sources += [
"gpu_sandbox_hook_linux.cc",
"gpu_sandbox_hook_linux.h",
]
}
if (is_android) {
deps += [
"//components/tracing:graphics_provider",
"//media",
]
}
if (mojo_media_host == "gpu") {
deps += [ "//media/mojo/services" ]
}
if (is_linux || is_chromeos || is_mac || is_win) {
deps += [ "//sandbox" ]
}
if (is_mac) {
deps += [ "//components/metal_util" ]
}
if (use_x11) {
deps += [
"//ui/events/platform/x11",
"//ui/gfx/linux:gpu_memory_buffer_support_x11",
"//ui/gfx/x",
]
}
if (use_ozone) {
deps += [ "//ui/ozone" ]
}
if (enable_vulkan) {
deps += [ "//gpu/vulkan" ]
}
# Use DRI on desktop Linux builds.
if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux &&
(!is_chromecast || is_cast_desktop_build)) {
configs += [ "//build/config/linux/dri" ]
}
if (is_linux && use_vaapi) {
public_configs = [ "//build/config/linux/libva" ]
}
}

BIN
logos/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
logos/SmallLogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
logos/chromium.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
logos/product_logo_128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
logos/product_logo_16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
logos/product_logo_24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
logos/product_logo_256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
logos/product_logo_32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

297
logos/product_logo_32.xpm Normal file
View file

@ -0,0 +1,297 @@
/* XPM */
static char * product_logo_32_xpm[] = {
"32 32 262 2",
" c None",
". c #4E7ADB",
"+ c #4C78DB",
"@ c #4C79DB",
"# c #4A77DA",
"$ c #4B78DA",
"% c #4D7ADB",
"& c #4776DA",
"* c #4272D9",
"= c #4172D9",
"- c #4171D9",
"; c #4071D9",
"> c #3F70D8",
", c #3E6FD8",
"' c #3D6FD8",
") c #4775DA",
"! c #4F7BDC",
"~ c #4574DA",
"{ c #4474D9",
"] c #4373D9",
"^ c #3D6ED8",
"/ c #3C6ED8",
"( c #4675DA",
"_ c #4976D8",
": c #4575D9",
"< c #3B6DD8",
"[ c #3F6FD8",
"} c #4773D5",
"| c #4573D6",
"1 c #4574D8",
"2 c #3A6CD7",
"3 c #3C6DD7",
"4 c #4670D2",
"5 c #4471D4",
"6 c #4472D5",
"7 c #4473D7",
"8 c #4573D9",
"9 c #396CD7",
"0 c #3B6DD7",
"a c #456ECF",
"b c #436ED1",
"c c #446FD2",
"d c #4470D4",
"e c #4471D6",
"f c #4472D8",
"g c #396BD7",
"h c #3B6CD7",
"i c #6C9AEE",
"j c #4169CB",
"k c #426DCF",
"l c #436FD3",
"m c #4370D5",
"n c #4372D7",
"o c #4372D8",
"p c #6BA0F7",
"q c #5580D9",
"r c #416ACD",
"s c #426CCF",
"t c #426ED1",
"u c #426FD3",
"v c #4270D5",
"w c #4271D7",
"x c #4272D8",
"y c #4172D8",
"z c #3861BC",
"A c #294992",
"B c #243C74",
"C c #314070",
"D c #44568D",
"E c #5C72B4",
"F c #6F87CE",
"G c #7089D0",
"H c #728CD2",
"I c #748ED3",
"J c #7590D5",
"K c #7892D6",
"L c #7994D9",
"M c #7B97DB",
"N c #7E9ADE",
"O c #809DDF",
"P c #6EA1F7",
"Q c #699DF3",
"R c #4369C7",
"S c #406ACD",
"T c #416CD0",
"U c #416DD2",
"V c #416FD4",
"W c #4170D5",
"X c #3D69C9",
"Y c #1F3974",
"Z c #000000",
"` c #1D3A6B",
" . c #315CA3",
".. c #305BA3",
"+. c #1C3A6B",
"@. c #414E74",
"#. c #7D92CD",
"$. c #8099D8",
"%. c #829BDB",
"&. c #86A1DE",
"*. c #8AA6E2",
"=. c #8DA9E6",
"-. c #8FACE8",
";. c #91ADE9",
">. c #91AFEA",
",. c #95B2EC",
"'. c #6A9FF7",
"). c #6B9FF7",
"!. c #5B88E0",
"~. c #3D63C5",
"{. c #3F6ACE",
"]. c #406CD1",
"^. c #406ED3",
"/. c #3C68C7",
"(. c #11234C",
"_. c #203863",
":. c #457CD9",
"<. c #4E8DF5",
"[. c #4D8CF5",
"}. c #4C8CF5",
"|. c #427BD9",
"1. c #1F3863",
"2. c #2B354F",
"3. c #89A2DA",
"4. c #91ADE8",
"5. c #92AFEA",
"6. c #93B0EB",
"7. c #94B1EC",
"8. c #95B2ED",
"9. c #96B4ED",
"0. c #97B5EE",
"a. c #98B6EF",
"b. c #486FCC",
"c. c #3E65C7",
"d. c #3F6ACF",
"e. c #1F3872",
"f. c #4D8AF1",
"g. c #4C8BF5",
"h. c #4A88F1",
"i. c #1E3763",
"j. c #596888",
"k. c #96B3ED",
"l. c #98B5EF",
"m. c #99B7F0",
"n. c #9AB9F1",
"o. c #9BBAF2",
"p. c #9CBBF3",
"q. c #9DBCF5",
"r. c #699EF7",
"s. c #6393EB",
"t. c #3C63C5",
"u. c #3D65C9",
"v. c #365CB6",
"w. c #4B8BF5",
"x. c #407AD8",
"y. c #8DA6D7",
"z. c #9DBBF3",
"A. c #9EBCF4",
"B. c #9FBEF5",
"C. c #9FBFF6",
"D. c #A0C0F7",
"E. c #A1C1F8",
"F. c #A1C2F9",
"G. c #A2C3FA",
"H. c #4F7AD5",
"I. c #3C64C8",
"J. c #27438A",
"K. c #4A8AF4",
"L. c #498AF4",
"M. c #1B396A",
"N. c #778AB0",
"O. c #A2C1F8",
"P. c #A3C2F9",
"Q. c #A3C3F9",
"R. c #A3C3FA",
"S. c #689EF7",
"T. c #6599F1",
"U. c #3F66C8",
"V. c #23386F",
"W. c #2D59A2",
"X. c #75819B",
"Y. c #A4C4FA",
"Z. c #679DF7",
"`. c #5583DE",
" + c #24386F",
".+ c #4989F4",
"++ c #76829C",
"@+ c #A2C2FA",
"#+ c #679CF6",
"$+ c #669BF5",
"%+ c #335092",
"&+ c #1A386A",
"*+ c #7C8FB2",
"=+ c #A1C1F9",
"-+ c #669CF6",
";+ c #679DF6",
">+ c #5684D3",
",+ c #3F79D8",
"'+ c #97B1DF",
")+ c #A1C1FA",
"!+ c #3A588B",
"~+ c #4988F1",
"{+ c #4786F0",
"]+ c #1D3763",
"^+ c #64728E",
"/+ c #6194E9",
"(+ c #263B5E",
"_+ c #1D2D50",
":+ c #9FBAEC",
"<+ c #A1C2FA",
"[+ c #649AF4",
"}+ c #659BF6",
"|+ c #3B598B",
"1+ c #334D80",
"2+ c #83A2E1",
"3+ c #9FC0F8",
"4+ c #649BF6",
"5+ c #5B8BDA",
"6+ c #476CAB",
"7+ c #3C5888",
"8+ c #3F5A8A",
"9+ c #4A6AA8",
"0+ c #537ECE",
"a+ c #5F8CE5",
"b+ c #A2C0F7",
"c+ c #6399F4",
"d+ c #639AF6",
"e+ c #629AF6",
"f+ c #5E92EE",
"g+ c #5A8CE8",
"h+ c #8AACEE",
"i+ c #9EBFF7",
"j+ c #649AF5",
"k+ c #6299F6",
"l+ c #5B8FEB",
"m+ c #6994E8",
"n+ c #A0C1F9",
"o+ c #6399F5",
"p+ c #6096F3",
"q+ c #5B8DEA",
"r+ c #92B3F1",
"s+ c #6299F5",
"t+ c #6199F6",
"u+ c #5E94F1",
"v+ c #749CEB",
"w+ c #6198F5",
"x+ c #5B8FEC",
"y+ c #9BBCF6",
"z+ c #5F95F2",
"A+ c #5F96F2",
"B+ c #80A6EF",
"C+ c #9CBDF6",
"D+ c #6098F5",
"E+ c #6097F5",
"F+ c #6193EE",
"G+ c #9FC0F9",
"H+ c #9DBDF6",
"I+ c #5D93F1",
"J+ c #5B91EE",
"K+ c #82A6ED",
"L+ c #9DBDF5",
"M+ c #9CBCF5",
" ",
" . + @ + # $ ",
" % & * = = - ; > , ' - ) ",
" ! ~ { ] * * = - ; > , , ' ^ / ( ",
" _ : ~ { ] ] * = - ; > , , ' ^ / < [ ",
" } | 1 ~ { ] ] * = - ; > , , ' ^ / < 2 3 ",
" 4 5 6 7 8 { ] * * = - ; > , , ' ^ / < 2 9 0 ",
" a b c d e f { ] * = = - ; > , ' ' ^ / < 2 9 g h ",
" i j k b l m n o ] * = - - ; > , ' ^ ^ / < 2 9 g g [ ",
" p q r s t u v w x y z A B C D E F G H I J K L M N O ",
" P p Q R S T U V W X Y Z ` ...+.Z @.#.$.%.&.*.=.-.;.>.,. ",
" '.).).!.~.{.].^./.(._.:.<.[.[.}.|.1.2.3.4.5.6.7.8.9.0.a. ",
" '.'.'.).b.c.d.].e._.f.<.<.[.}.}.g.h.i.j.k.l.a.m.n.o.p.q. ",
" r.r.r.r.r.s.t.u.v.Z :.<.<.[.}.}.g.w.w.x.Z y.z.A.B.C.D.E.F.G. ",
" '.r.r.r.r.r.H.I.J.` <.<.[.}.}.g.g.w.K.L.M.N.O.P.Q.R.R.G.G.R. ",
" S.S.r.r.r.r.T.U.V. .[.[.}.}.g.g.w.K.K.L.W.X.Y.Y.R.R.R.G.G.G. ",
" Z.Z.S.S.S.S.S.`. +..[.}.}.g.g.w.K.K.L..+W.++Y.Y.R.R.G.G.G.@+ ",
" #+Z.Z.Z.Z.Z.Z.$+%++.}.g.g.g.w.K.K.L.L..+&+*+Y.R.R.R.G.G.@+=+ ",
" -+;+;+;+;+;+;+;+>+Z |.g.w.w.K.K.L.L..+,+Z '+R.R.R.G.G.G.@+)+ ",
" -+-+-+-+-+-+-+-+!+1.~+w.K.K.L.L..+{+]+^+Y.R.R.R.G.G.@+@+ ",
" -+-+-+-+-+-+-+-+/+(+1.x.L.L..+.+,+]+_+:+R.R.R.G.G.G.@+<+ ",
" [+}+-+-+-+}+}+}+}+/+|+Z M.W.W.&+Z 1+2+R.R.R.G.G.G.@+<+3+ ",
" }+}+}+}+}+4+4+4+4+}+5+6+7+8+9+0+a+b+R.R.G.G.G.@+@+<+ ",
" c+4+4+4+4+4+4+4+4+4+d+d+d+e+f+g+h+R.R.G.G.G.@+@+<+i+ ",
" j+4+4+4+4+4+d+d+d+d+e+e+k+l+m+P.R.G.G.G.@+@+<+n+ ",
" o+d+d+d+d+d+e+e+e+e+k+p+q+r+G.G.G.G.@+@+<+n+ ",
" s+e+e+e+e+e+k+k+k+t+u+v+R.G.G.G.@+@+<+n+ ",
" w+k+k+k+k+k+t+t+w+x+y+G.G.G.@+@+<+3+ ",
" z+t+t+t+t+t+t+A+B+G.G.@+@+<+<+C+ ",
" z+D+t+t+E+F+E.@+@+@+G+H+ ",
" I+J+K+L+H+M+ ",
" "};

BIN
logos/product_logo_48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
logos/product_logo_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
logos/product_logo_64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
logos/technetium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

44
logos/technetium.svg Normal file
View file

@ -0,0 +1,44 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="8192.000000pt" height="8192.000000pt" viewBox="0 0 8192.000000 8192.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,8192.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M39940 78460 c-2828 -82 -5542 -453 -8215 -1121 -3543 -886 -6956
-2292 -10102 -4160 -3281 -1948 -6204 -4339 -8804 -7199 -1226 -1349 -2350
-2790 -3444 -4415 -93 -137 -170 -252 -172 -254 -2 -3 -35 26 -74 65 l-70 69
62 -110 c113 -201 1813 -3118 8669 -14875 1021 -1752 3226 -5534 4900 -8405
1673 -2871 3047 -5224 3053 -5230 5 -5 -4 15 -20 45 -139 252 -373 734 -537
1103 -1184 2668 -1665 5588 -1406 8532 213 2410 937 4757 2118 6865 1350 2410
3256 4462 5557 5985 2674 1769 5729 2738 8965 2845 188 6 6486 10 17313 10
9359 0 17017 3 17017 6 0 4 -48 101 -107 215 l-108 209 -115 0 -115 0 -46 88
c-25 48 -119 218 -209 377 -4411 7841 -11490 13891 -19905 17012 -3643 1351
-7473 2129 -11390 2313 -121 6 -337 15 -480 21 -334 13 -1963 20 -2335 9z"/>
<path d="M41748 58193 c23 -2 61 -2 85 0 23 2 4 4 -43 4 -47 0 -66 -2 -42 -4z"/>
<path d="M41907 58188 c2 -5 32 -8 66 -8 301 0 1251 -106 1839 -204 l258 -43
72 17 c50 12 67 19 53 23 -33 10 -476 74 -700 101 -439 53 -854 88 -1255 106
-135 6 -266 12 -292 13 -25 1 -44 -1 -41 -5z"/>
<path d="M40430 54743 c-1624 -71 -3107 -383 -4560 -960 -2369 -941 -4449
-2538 -5975 -4588 -1075 -1443 -1855 -3074 -2295 -4800 -225 -880 -339 -1606
-411 -2615 -17 -240 -23 -1104 -10 -1400 104 -2336 759 -4527 1948 -6508 473
-789 1012 -1514 1642 -2207 187 -206 690 -709 896 -896 1113 -1012 2358 -1825
3705 -2422 1405 -623 2913 -1007 4435 -1132 391 -32 492 -36 975 -42 651 -8
1130 14 1707 77 2901 318 5637 1563 7803 3550 197 181 684 669 861 865 1348
1483 2336 3187 2946 5080 313 972 522 2025 607 3055 37 443 41 553 41 1160 0
687 -14 971 -76 1525 -320 2894 -1530 5574 -3499 7750 -210 231 -704 725 -935
935 -1760 1592 -3852 2691 -6140 3225 -813 190 -1667 306 -2530 345 -194 9
-960 11 -1135 3z"/>
<path d="M55510 31687 c-77 -125 -361 -545 -495 -732 -384 -538 -807 -1065
-1246 -1551 l-116 -129 -265 -465 c-146 -256 -271 -476 -278 -490 l-13 -25 24
20 c13 11 5 -1 -18 -25 -44 -47 -299 -492 -9560 -16700 -2538 -4441 -4618
-8079 -4622 -8083 -17 -17 -1364 81 -1834 133 -84 10 -90 9 -177 -21 l-89 -31
-91 -154 c-50 -85 -88 -158 -86 -163 3 -4 36 -11 73 -15 37 -3 176 -17 308
-31 520 -55 1454 -129 1875 -150 63 -3 147 -8 186 -11 l71 -5 123 218 c150
264 1691 2960 4257 7448 1051 1837 2995 5237 4320 7555 1326 2318 3315 5797
4420 7730 1106 1933 2034 3556 2062 3605 28 50 314 551 636 1114 322 564 583
1026 582 1027 -2 2 -23 -29 -47 -69z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
logos/thorium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View file

@ -0,0 +1,247 @@
// Copyright 2016 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 "media/gpu/gpu_video_decode_accelerator_factory.h"
#include <memory>
#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/media_switches.h"
#include "media/gpu/buildflags.h"
#include "media/gpu/gpu_video_accelerator_util.h"
#include "media/gpu/macros.h"
#include "media/gpu/media_gpu_export.h"
#include "media/media_buildflags.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "media/gpu/windows/dxva_video_decode_accelerator_win.h"
#endif
#if defined(OS_MAC)
#include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
#endif
#if BUILDFLAG(USE_VAAPI)
#include "media/gpu/vaapi/vaapi_video_decode_accelerator.h"
#include "ui/gl/gl_implementation.h"
#elif BUILDFLAG(USE_V4L2_CODEC)
#include "media/gpu/v4l2/v4l2_device.h"
#include "media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h"
#include "media/gpu/v4l2/v4l2_video_decode_accelerator.h"
#include "ui/gl/gl_surface_egl.h"
#endif
namespace media {
namespace {
gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& workarounds) {
if (gpu_preferences.disable_accelerated_video_decode)
return gpu::VideoDecodeAcceleratorCapabilities();
// Query VDAs for their capabilities and construct a set of supported
// profiles for current platform. This must be done in the same order as in
// CreateVDA(), as we currently preserve additional capabilities (such as
// resolutions supported) only for the first VDA supporting the given codec
// profile (instead of calculating a superset).
// TODO(posciak,henryhsu): improve this so that we choose a superset of
// resolutions and other supported profile parameters.
VideoDecodeAccelerator::Capabilities capabilities;
#if defined(OS_WIN)
capabilities.supported_profiles =
DXVAVideoDecodeAccelerator::GetSupportedProfiles(gpu_preferences,
workarounds);
#elif BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#if BUILDFLAG(USE_VAAPI)
capabilities.supported_profiles =
VaapiVideoDecodeAccelerator::GetSupportedProfiles();
#elif BUILDFLAG(USE_V4L2_CODEC)
GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
V4L2VideoDecodeAccelerator::GetSupportedProfiles(),
&capabilities.supported_profiles);
GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(),
&capabilities.supported_profiles);
#endif
#elif defined(OS_MAC)
capabilities.supported_profiles =
VTVideoDecodeAccelerator::GetSupportedProfiles(workarounds);
#endif
return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities(
capabilities);
}
} // namespace
// static
MEDIA_GPU_EXPORT std::unique_ptr<GpuVideoDecodeAcceleratorFactory>
GpuVideoDecodeAcceleratorFactory::Create(
const GpuVideoDecodeGLClient& gl_client) {
return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory(gl_client));
}
// static
MEDIA_GPU_EXPORT gpu::VideoDecodeAcceleratorCapabilities
GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& workarounds) {
// Cache the capabilities so that they will not be computed more than once per
// GPU process. It is assumed that |gpu_preferences| and |workarounds| do not
// change between calls.
// TODO(sandersd): Move cache to GpuMojoMediaClient once
// |video_decode_accelerator_capabilities| is removed from GPUInfo.
static gpu::VideoDecodeAcceleratorCapabilities capabilities =
GetDecoderCapabilitiesInternal(gpu_preferences, workarounds);
#if BUILDFLAG(USE_V4L2_CODEC)
// V4L2-only: the decoder devices may not be visible at the time the GPU
// process is starting. If the capabilities vector is empty, try to query the
// devices again in the hope that they will have appeared in the meantime.
// TODO(crbug.com/948147): trigger query when an device add/remove event
// (e.g. via udev) has happened instead.
if (capabilities.supported_profiles.empty()) {
VLOGF(1) << "Capabilities empty, querying again...";
capabilities = GetDecoderCapabilitiesInternal(gpu_preferences, workarounds);
}
#endif
return capabilities;
}
MEDIA_GPU_EXPORT std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateVDA(
VideoDecodeAccelerator::Client* client,
const VideoDecodeAccelerator::Config& config,
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) {
DCHECK(thread_checker_.CalledOnValidThread());
if (gpu_preferences.disable_accelerated_video_decode)
return nullptr;
// Array of Create..VDA() function pointers, potentially usable on current
// platform. This list is ordered by priority, from most to least preferred,
// if applicable. This list must be in the same order as the querying order
// in GetDecoderCapabilities() above.
using CreateVDAFp = std::unique_ptr<VideoDecodeAccelerator> (
GpuVideoDecodeAcceleratorFactory::*)(const gpu::GpuDriverBugWorkarounds&,
const gpu::GpuPreferences&,
MediaLog* media_log) const;
const CreateVDAFp create_vda_fps[] = {
#if defined(OS_WIN)
&GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA,
#endif
// Usually only one of USE_VAAPI or USE_V4L2_CODEC is defined on ChromeOS,
// except for Chromeboxes with companion video acceleration chips, which have
// both. In those cases prefer the VA creation function.
#if BUILDFLAG(USE_VAAPI)
&GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
#elif BUILDFLAG(USE_V4L2_CODEC)
&GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
&GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA,
#endif
#if defined(OS_MAC)
&GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
#endif
};
std::unique_ptr<VideoDecodeAccelerator> vda;
for (const auto& create_vda_function : create_vda_fps) {
vda = (this->*create_vda_function)(workarounds, gpu_preferences, media_log);
if (vda && vda->Initialize(config, client))
return vda;
else
LOG(ERROR) << "Initialization of one or more VDAs failed.";
}
return nullptr;
}
#if defined(OS_WIN)
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
DVLOG(0) << "Initializing DXVA HW decoder for windows.";
decoder.reset(new DXVAVideoDecodeAccelerator(
gl_client_.get_context, gl_client_.make_context_current,
gl_client_.bind_image, workarounds, gpu_preferences, media_log));
return decoder;
}
#endif
#if BUILDFLAG(USE_VAAPI)
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA(
const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
const gpu::GpuPreferences& /*gpu_preferences*/,
MediaLog* /*media_log*/) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
decoder.reset(new VaapiVideoDecodeAccelerator(gl_client_.make_context_current,
gl_client_.bind_image));
return decoder;
}
#elif BUILDFLAG(USE_V4L2_CODEC)
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
const gpu::GpuPreferences& /*gpu_preferences*/,
MediaLog* /*media_log*/) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
scoped_refptr<V4L2Device> device = V4L2Device::Create();
if (device.get()) {
decoder.reset(new V4L2VideoDecodeAccelerator(
gl::GLSurfaceEGL::GetHardwareDisplay(), gl_client_.get_context,
gl_client_.make_context_current, device));
}
return decoder;
}
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
const gpu::GpuPreferences& /*gpu_preferences*/,
MediaLog* /*media_log*/) const {
std::unique_ptr<VideoDecodeAccelerator> decoder;
scoped_refptr<V4L2Device> device = V4L2Device::Create();
if (device.get()) {
decoder.reset(new V4L2SliceVideoDecodeAccelerator(
device, gl::GLSurfaceEGL::GetHardwareDisplay(), gl_client_.bind_image,
gl_client_.make_context_current));
}
return decoder;
}
#endif
#if defined(OS_MAC)
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateVTVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const {
LOG(WARNING) << "Initializing VAAPI VDA.";
std::unique_ptr<VideoDecodeAccelerator> decoder;
decoder.reset(
new VTVideoDecodeAccelerator(gl_client_, workarounds, media_log));
return decoder;
}
#endif
GpuVideoDecodeAcceleratorFactory::GpuVideoDecodeAcceleratorFactory(
const GpuVideoDecodeGLClient& gl_client)
: gl_client_(gl_client) {}
GpuVideoDecodeAcceleratorFactory::~GpuVideoDecodeAcceleratorFactory() = default;
} // namespace media

View file

@ -0,0 +1,622 @@
// Copyright (c) 2012 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 "media/gpu/ipc/service/gpu_video_decode_accelerator.h"
#include <memory>
#include <vector>
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/bind_post_task.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/message_filter.h"
#include "media/base/limits.h"
#include "media/gpu/gpu_video_accelerator_util.h"
#include "media/gpu/gpu_video_decode_accelerator_factory.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image.h"
namespace media {
namespace {
static gl::GLContext* GetGLContext(
const base::WeakPtr<gpu::CommandBufferStub>& stub) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; no GLContext.";
return nullptr;
}
return stub->decoder_context()->GetGLContext();
}
static bool MakeDecoderContextCurrent(
const base::WeakPtr<gpu::CommandBufferStub>& stub) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
return false;
}
if (!stub->decoder_context()->MakeCurrent()) {
DLOG(ERROR) << "Failed to MakeCurrent()";
return false;
}
return true;
}
static bool BindImage(const base::WeakPtr<gpu::CommandBufferStub>& stub,
uint32_t client_texture_id,
uint32_t texture_target,
const scoped_refptr<gl::GLImage>& image,
bool can_bind_to_sampler) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; won't BindImage().";
return false;
}
gpu::DecoderContext* command_decoder = stub->decoder_context();
command_decoder->BindImage(client_texture_id, texture_target, image.get(),
can_bind_to_sampler);
return true;
}
static gpu::gles2::ContextGroup* GetContextGroup(
const base::WeakPtr<gpu::CommandBufferStub>& stub) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; no DecoderContext.";
return nullptr;
}
return stub->decoder_context()->GetContextGroup();
}
static std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture(
const base::WeakPtr<gpu::CommandBufferStub>& stub,
GLenum target,
GLenum internal_format,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type) {
if (!stub) {
DLOG(ERROR) << "Stub is gone; no DecoderContext.";
return nullptr;
}
return stub->decoder_context()->CreateAbstractTexture(
target, internal_format, width, height, depth, border, format, type);
}
} // anonymous namespace
// DebugAutoLock works like AutoLock but only acquires the lock when
// DCHECK is on.
#if DCHECK_IS_ON()
typedef base::AutoLock DebugAutoLock;
#else
class DebugAutoLock {
public:
explicit DebugAutoLock(base::Lock&) {}
};
#endif
// Receives incoming messages for the decoder. Operates exclusively on the IO
// thread, since sometimes we want to do decodes directly from there.
class GpuVideoDecodeAccelerator::MessageFilter
: public mojom::GpuAcceleratedVideoDecoder {
public:
MessageFilter(GpuVideoDecodeAccelerator* owner,
scoped_refptr<base::SequencedTaskRunner> owner_task_runner,
bool decode_on_io)
: owner_(owner),
owner_task_runner_(std::move(owner_task_runner)),
decode_on_io_(decode_on_io) {}
~MessageFilter() override = default;
// Called from the main thread. Posts to `io_task_runner` to do the binding
// and waits for completion before returning. This ensures the decoder's
// endpoint is established before the synchronous request to establish it is
// acknowledged to the client.
bool Bind(mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder>
receiver,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) {
base::WaitableEvent bound_event;
if (!io_task_runner->PostTask(
FROM_HERE, base::BindOnce(&MessageFilter::BindOnIoThread,
base::Unretained(this),
std::move(receiver), &bound_event))) {
return false;
}
bound_event.Wait();
return true;
}
// Must be called on the IO thread. Posts back to the owner's task runner to
// destroy it.
void RequestShutdown() {
if (!owner_)
return;
// Must be reset here on the IO thread before `this` is destroyed.
receiver_.reset();
GpuVideoDecodeAccelerator* owner = owner_;
owner_ = nullptr;
// Invalidate any IO thread WeakPtrs which may be held by the
// VideoDecodeAccelerator, and post to delete our owner which will in turn
// delete us. Note that it is unsafe to access any members of `this` once
// the task below is posted.
owner->weak_factory_for_io_.InvalidateWeakPtrs();
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::DeleteSelfNow,
base::Unretained(owner)));
}
// mojom::GpuAcceleratedVideoDecoder:
void Decode(BitstreamBuffer buffer) override;
void AssignPictureBuffers(
std::vector<mojom::PictureBufferAssignmentPtr> assignments) override;
void ReusePictureBuffer(int32_t picture_buffer_id) override;
void Flush(FlushCallback callback) override;
void Reset(ResetCallback callback) override;
void SetOverlayInfo(const OverlayInfo& overlay_info) override;
private:
void BindOnIoThread(mojo::PendingAssociatedReceiver<
mojom::GpuAcceleratedVideoDecoder> receiver,
base::WaitableEvent* bound_event) {
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(
base::BindOnce(&MessageFilter::OnDisconnect, base::Unretained(this)));
bound_event->Signal();
}
void OnDisconnect() {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnDestroy,
base::Unretained(owner_)));
}
GpuVideoDecodeAccelerator* owner_;
const scoped_refptr<base::SequencedTaskRunner> owner_task_runner_;
const bool decode_on_io_;
mojo::AssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> receiver_{this};
};
void GpuVideoDecodeAccelerator::MessageFilter::Decode(BitstreamBuffer buffer) {
if (!owner_)
return;
if (decode_on_io_) {
owner_->OnDecode(std::move(buffer));
} else {
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnDecode,
base::Unretained(owner_), std::move(buffer)));
}
}
void GpuVideoDecodeAccelerator::MessageFilter::AssignPictureBuffers(
std::vector<mojom::PictureBufferAssignmentPtr> assignments) {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&GpuVideoDecodeAccelerator::OnAssignPictureBuffers,
base::Unretained(owner_), std::move(assignments)));
}
void GpuVideoDecodeAccelerator::MessageFilter::ReusePictureBuffer(
int32_t picture_buffer_id) {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&GpuVideoDecodeAccelerator::OnReusePictureBuffer,
base::Unretained(owner_), picture_buffer_id));
}
void GpuVideoDecodeAccelerator::MessageFilter::Flush(FlushCallback callback) {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnFlush,
base::Unretained(owner_), std::move(callback)));
}
void GpuVideoDecodeAccelerator::MessageFilter::Reset(ResetCallback callback) {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnReset,
base::Unretained(owner_), std::move(callback)));
}
void GpuVideoDecodeAccelerator::MessageFilter::SetOverlayInfo(
const OverlayInfo& overlay_info) {
if (!owner_)
return;
owner_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnSetOverlayInfo,
base::Unretained(owner_), overlay_info));
}
GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator(
gpu::CommandBufferStub* stub,
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
const AndroidOverlayMojoFactoryCB& overlay_factory_cb)
: stub_(stub),
texture_target_(0),
pixel_format_(PIXEL_FORMAT_UNKNOWN),
textures_per_buffer_(0),
child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
io_task_runner_(io_task_runner),
overlay_factory_cb_(overlay_factory_cb) {
DCHECK(stub_);
stub_->AddDestructionObserver(this);
gl_client_.get_context =
base::BindRepeating(&GetGLContext, stub_->AsWeakPtr());
gl_client_.make_context_current =
base::BindRepeating(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
gl_client_.bind_image = base::BindRepeating(&BindImage, stub_->AsWeakPtr());
gl_client_.get_context_group =
base::BindRepeating(&GetContextGroup, stub_->AsWeakPtr());
gl_client_.create_abstract_texture =
base::BindRepeating(&CreateAbstractTexture, stub_->AsWeakPtr());
gl_client_.is_passthrough =
stub_->decoder_context()->GetFeatureInfo()->is_passthrough_cmd_decoder();
gl_client_.supports_arb_texture_rectangle = stub_->decoder_context()
->GetFeatureInfo()
->feature_flags()
.arb_texture_rectangle;
}
GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() {
// This class can only be self-deleted from OnWillDestroyStub(), which means
// the VDA has already been destroyed in there.
DCHECK(!video_decode_accelerator_);
}
void GpuVideoDecodeAccelerator::DeleteSelfNow() {
delete this;
}
// static
gpu::VideoDecodeAcceleratorCapabilities
GpuVideoDecodeAccelerator::GetCapabilities(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& workarounds) {
return GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities(
gpu_preferences, workarounds);
}
void GpuVideoDecodeAccelerator::NotifyInitializationComplete(Status status) {
decoder_client_->OnInitializationComplete(status.is_ok());
}
void GpuVideoDecodeAccelerator::ProvidePictureBuffers(
uint32_t requested_num_of_buffers,
VideoPixelFormat format,
uint32_t textures_per_buffer,
const gfx::Size& dimensions,
uint32_t texture_target) {
if (dimensions.width() > limits::kMaxDimension ||
dimensions.height() > limits::kMaxDimension ||
dimensions.GetArea() > limits::kMaxCanvas) {
NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
return;
}
texture_dimensions_ = dimensions;
textures_per_buffer_ = textures_per_buffer;
texture_target_ = texture_target;
pixel_format_ = format;
decoder_client_->OnProvidePictureBuffers(requested_num_of_buffers, format,
textures_per_buffer, dimensions,
texture_target);
}
void GpuVideoDecodeAccelerator::DismissPictureBuffer(
int32_t picture_buffer_id) {
// Notify client that picture buffer is now unused.
decoder_client_->OnDismissPictureBuffer(picture_buffer_id);
DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
uncleared_textures_.erase(picture_buffer_id);
}
void GpuVideoDecodeAccelerator::PictureReady(const Picture& picture) {
// VDA may call PictureReady on IO thread. SetTextureCleared should run on
// the child thread. VDA is responsible to call PictureReady on the child
// thread when a picture buffer is delivered the first time.
if (child_task_runner_->BelongsToCurrentThread()) {
SetTextureCleared(picture);
} else {
DCHECK(io_task_runner_->BelongsToCurrentThread());
DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id()));
}
auto params = mojom::PictureReadyParams::New();
params->picture_buffer_id = picture.picture_buffer_id();
params->bitstream_buffer_id = picture.bitstream_buffer_id();
params->visible_rect = picture.visible_rect();
params->color_space = picture.color_space();
params->allow_overlay = picture.allow_overlay();
params->read_lock_fences_enabled = picture.read_lock_fences_enabled();
params->size_changed = picture.size_changed();
params->surface_texture = picture.texture_owner();
params->wants_promotion_hint = picture.wants_promotion_hint();
decoder_client_->OnPictureReady(std::move(params));
}
void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
int32_t bitstream_buffer_id) {
decoder_client_->OnBitstreamBufferProcessed(bitstream_buffer_id);
}
void GpuVideoDecodeAccelerator::NotifyFlushDone() {
DCHECK(!pending_flushes_.empty());
std::move(pending_flushes_.front()).Run();
pending_flushes_.pop_front();
}
void GpuVideoDecodeAccelerator::NotifyResetDone() {
DCHECK(!pending_resets_.empty());
std::move(pending_resets_.front()).Run();
pending_resets_.pop_front();
}
void GpuVideoDecodeAccelerator::NotifyError(
VideoDecodeAccelerator::Error error) {
decoder_client_->OnError(error);
}
void GpuVideoDecodeAccelerator::OnWillDestroyStub(bool have_context) {
// The stub is going away, so we have to stop and destroy VDA here, before
// returning, because the VDA may need the GL context to run and/or do its
// cleanup. We cannot destroy the VDA before the IO thread message filter is
// removed however, since we cannot service incoming messages with VDA gone.
// We cannot simply check for existence of VDA on IO thread though, because
// we don't want to synchronize the IO thread with the ChildThread.
// So we have to wait for the RemoveFilter callback here instead and remove
// the VDA after it arrives and before returning.
stub_->RemoveDestructionObserver(this);
if (filter_) {
io_task_runner_->PostTask(FROM_HERE,
base::BindOnce(&MessageFilter::RequestShutdown,
base::Unretained(filter_.get())));
}
video_decode_accelerator_.reset();
}
bool GpuVideoDecodeAccelerator::Initialize(
const VideoDecodeAccelerator::Config& config,
mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> receiver,
mojo::PendingAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient>
client) {
DCHECK(!video_decode_accelerator_);
#if !defined(OS_WIN)
// Ensure we will be able to get a GL context at all before initializing
// non-Windows VDAs.
if (!gl_client_.make_context_current.Run())
return false;
#endif
std::unique_ptr<GpuVideoDecodeAcceleratorFactory> vda_factory =
GpuVideoDecodeAcceleratorFactory::Create(gl_client_);
if (!vda_factory) {
LOG(ERROR) << "Failed creating the VDA factory";
return false;
}
LOG(WARNING) << "Created the VDA factory";
const gpu::GpuDriverBugWorkarounds& gpu_workarounds =
stub_->channel()->gpu_channel_manager()->gpu_driver_bug_workarounds();
const gpu::GpuPreferences& gpu_preferences =
stub_->channel()->gpu_channel_manager()->gpu_preferences();
if (config.output_mode !=
VideoDecodeAccelerator::Config::OutputMode::ALLOCATE) {
DLOG(ERROR) << "Only ALLOCATE mode is supported";
return false;
}
video_decode_accelerator_ =
vda_factory->CreateVDA(this, config, gpu_workarounds, gpu_preferences);
if (!video_decode_accelerator_) {
LOG(ERROR) << "HW video decode not available for profile "
<< GetProfileName(config.profile)
<< (config.is_encrypted() ? " with encryption" : "");
return false;
}
LOG(WARNING) << "Created VDA";
decoder_client_.Bind(std::move(client), io_task_runner_);
// Attempt to set up performing decoding tasks on IO thread, if supported by
// the VDA.
bool decode_on_io =
video_decode_accelerator_->TryToSetupDecodeOnSeparateThread(
weak_factory_for_io_.GetWeakPtr(), io_task_runner_);
// Bind the receiver on the IO thread. We wait here for it to be bound
// before returning and signaling that the decoder has been created.
filter_ =
std::make_unique<MessageFilter>(this, stub_->task_runner(), decode_on_io);
return filter_->Bind(std::move(receiver), io_task_runner_);
}
// Runs on IO thread if VDA::TryToSetupDecodeOnSeparateThread() succeeded,
// otherwise on the main thread.
void GpuVideoDecodeAccelerator::OnDecode(BitstreamBuffer bitstream_buffer) {
DCHECK(video_decode_accelerator_);
video_decode_accelerator_->Decode(std::move(bitstream_buffer));
}
void GpuVideoDecodeAccelerator::OnAssignPictureBuffers(
std::vector<mojom::PictureBufferAssignmentPtr> assignments) {
gpu::DecoderContext* decoder_context = stub_->decoder_context();
gpu::gles2::TextureManager* texture_manager =
stub_->decoder_context()->GetContextGroup()->texture_manager();
std::vector<PictureBuffer> buffers;
std::vector<std::vector<scoped_refptr<gpu::gles2::TextureRef>>> textures;
for (const auto& assignment : assignments) {
if (assignment->buffer_id < 0) {
DLOG(ERROR) << "Buffer id " << assignment->buffer_id << " out of range";
NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
std::vector<scoped_refptr<gpu::gles2::TextureRef>> current_textures;
PictureBuffer::TextureIds buffer_texture_ids = assignment->texture_ids;
PictureBuffer::TextureIds service_ids;
if (buffer_texture_ids.size() != textures_per_buffer_) {
DLOG(ERROR) << "Requested " << textures_per_buffer_
<< " textures per picture buffer, got "
<< buffer_texture_ids.size();
NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
for (size_t j = 0; j < textures_per_buffer_; j++) {
gpu::TextureBase* texture_base =
decoder_context->GetTextureBase(buffer_texture_ids[j]);
if (!texture_base) {
DLOG(ERROR) << "Failed to find texture id " << buffer_texture_ids[j];
NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
if (texture_base->target() != texture_target_) {
DLOG(ERROR) << "Texture target mismatch for texture id "
<< buffer_texture_ids[j];
NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
if (texture_manager) {
gpu::gles2::TextureRef* texture_ref =
texture_manager->GetTexture(buffer_texture_ids[j]);
if (texture_ref) {
gpu::gles2::Texture* info = texture_ref->texture();
if (texture_target_ == GL_TEXTURE_EXTERNAL_OES ||
texture_target_ == GL_TEXTURE_RECTANGLE_ARB) {
// These textures have their dimensions defined by the underlying
// storage.
// Use |texture_dimensions_| for this size.
texture_manager->SetLevelInfo(
texture_ref, texture_target_, 0, GL_RGBA,
texture_dimensions_.width(), texture_dimensions_.height(), 1, 0,
GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect());
} else {
// For other targets, texture dimensions should already be defined.
GLsizei width = 0, height = 0;
info->GetLevelSize(texture_target_, 0, &width, &height, nullptr);
if (width != texture_dimensions_.width() ||
height != texture_dimensions_.height()) {
DLOG(ERROR) << "Size mismatch for texture id "
<< buffer_texture_ids[j];
NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT);
return;
}
// TODO(dshwang): after moving to D3D11, remove this.
// https://crbug.com/438691
GLenum format =
video_decode_accelerator_->GetSurfaceInternalFormat();
if (format != GL_RGBA) {
DCHECK(format == GL_BGRA_EXT);
texture_manager->SetLevelInfo(texture_ref, texture_target_, 0,
format, width, height, 1, 0, format,
GL_UNSIGNED_BYTE, gfx::Rect());
}
}
current_textures.push_back(texture_ref);
}
}
service_ids.push_back(texture_base->service_id());
}
textures.push_back(current_textures);
buffers.emplace_back(assignment->buffer_id, texture_dimensions_,
buffer_texture_ids, service_ids, texture_target_,
pixel_format_);
}
{
DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
for (uint32_t i = 0; i < assignments.size(); ++i)
uncleared_textures_[assignments[i]->buffer_id] = textures[i];
}
video_decode_accelerator_->AssignPictureBuffers(buffers);
}
void GpuVideoDecodeAccelerator::OnReusePictureBuffer(
int32_t picture_buffer_id) {
DCHECK(video_decode_accelerator_);
video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id);
}
void GpuVideoDecodeAccelerator::OnFlush(base::OnceClosure callback) {
DCHECK(video_decode_accelerator_);
pending_flushes_.push_back(
base::BindPostTask(io_task_runner_, std::move(callback)));
video_decode_accelerator_->Flush();
}
void GpuVideoDecodeAccelerator::OnReset(base::OnceClosure callback) {
DCHECK(video_decode_accelerator_);
pending_resets_.push_back(
base::BindPostTask(io_task_runner_, std::move(callback)));
video_decode_accelerator_->Reset();
}
void GpuVideoDecodeAccelerator::OnSetOverlayInfo(
const OverlayInfo& overlay_info) {
DCHECK(video_decode_accelerator_);
video_decode_accelerator_->SetOverlayInfo(overlay_info);
}
void GpuVideoDecodeAccelerator::OnDestroy() {
DCHECK(video_decode_accelerator_);
OnWillDestroyStub(false);
}
void GpuVideoDecodeAccelerator::SetTextureCleared(const Picture& picture) {
DCHECK(child_task_runner_->BelongsToCurrentThread());
DebugAutoLock auto_lock(debug_uncleared_textures_lock_);
auto it = uncleared_textures_.find(picture.picture_buffer_id());
if (it == uncleared_textures_.end())
return; // the texture has been cleared
for (auto texture_ref : it->second) {
GLenum target = texture_ref->texture()->target();
gpu::gles2::TextureManager* texture_manager =
stub_->decoder_context()->GetContextGroup()->texture_manager();
texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true);
}
uncleared_textures_.erase(it);
}
} // namespace media

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,368 @@
// Copyright (c) 2012 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.
//
// This file contains an implementation of VideoDecoderAccelerator
// that utilizes hardware video decoder present on Intel CPUs.
#ifndef MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
#define MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODE_ACCELERATOR_H_
#include <stddef.h>
#include <stdint.h>
#include <list>
#include <map>
#include <memory>
#include <utility>
#include <vector>
#include "base/containers/queue.h"
#include "base/containers/small_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_provider.h"
#include "media/base/bitstream_buffer.h"
#include "media/gpu/decode_surface_handler.h"
#include "media/gpu/gpu_video_decode_accelerator_helpers.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/vaapi/vaapi_picture_factory.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "media/video/picture.h"
#include "media/video/video_decode_accelerator.h"
namespace gl {
class GLImage;
}
namespace media {
class AcceleratedVideoDecoder;
template <typename T>
class ScopedID;
class VaapiVideoDecoderDelegate;
class VaapiPicture;
// Class to provide video decode acceleration for Intel systems with hardware
// support for it, and on which libva is available.
// Decoding tasks are performed in a separate decoding thread.
//
// Threading/life-cycle: this object is created & destroyed on the GPU
// ChildThread. A few methods on it are called on the decoder thread which is
// stopped during |this->Destroy()|, so any tasks posted to the decoder thread
// can assume |*this| is still alive. See |weak_this_| below for more details.
class MEDIA_GPU_EXPORT VaapiVideoDecodeAccelerator
: public VideoDecodeAccelerator,
public DecodeSurfaceHandler<VASurface>,
public base::trace_event::MemoryDumpProvider {
public:
VaapiVideoDecodeAccelerator(
const MakeGLContextCurrentCallback& make_context_current_cb,
const BindGLImageCallback& bind_image_cb);
VaapiVideoDecodeAccelerator(const VaapiVideoDecodeAccelerator&) = delete;
VaapiVideoDecodeAccelerator& operator=(const VaapiVideoDecodeAccelerator&) =
delete;
~VaapiVideoDecodeAccelerator() override;
// VideoDecodeAccelerator implementation.
bool Initialize(const Config& config, Client* client) override;
void Decode(BitstreamBuffer bitstream_buffer) override;
void Decode(scoped_refptr<DecoderBuffer> buffer,
int32_t bitstream_id) override;
void AssignPictureBuffers(const std::vector<PictureBuffer>& buffers) override;
#if defined(USE_OZONE)
void ImportBufferForPicture(
int32_t picture_buffer_id,
VideoPixelFormat pixel_format,
gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override;
#endif
void ReusePictureBuffer(int32_t picture_buffer_id) override;
void Flush() override;
void Reset() override;
void Destroy() override;
bool TryToSetupDecodeOnSeparateThread(
const base::WeakPtr<Client>& decode_client,
const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
override;
static VideoDecodeAccelerator::SupportedProfiles GetSupportedProfiles();
static bool IsVppProfileSupported();
// DecodeSurfaceHandler implementation.
scoped_refptr<VASurface> CreateSurface() override;
void SurfaceReady(scoped_refptr<VASurface> va_surface,
int32_t bitstream_id,
const gfx::Rect& visible_rect,
const VideoColorSpace& color_space) override;
// base::trace_event::MemoryDumpProvider implementation.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
private:
friend class VaapiVideoDecodeAcceleratorTest;
// An input buffer with id provided by the client and awaiting consumption.
class InputBuffer;
// A self-cleaning VASurfaceID.
using ScopedVASurfaceID = ScopedID<VASurfaceID>;
// Notify the client that an error has occurred and decoding cannot continue.
void NotifyError(Error error);
void NotifyStatus(VaapiStatus status);
// Queue a input buffer for decode.
void QueueInputBuffer(scoped_refptr<DecoderBuffer> buffer,
int32_t bitstream_id);
// Gets a new |current_input_buffer_| from |input_buffers_| and sets it up in
// |decoder_|. This method will sleep if no |input_buffers_| are available.
// Returns true if a new buffer has been set up, false if an early exit has
// been requested (due to initiated reset/flush/destroy).
bool GetCurrInputBuffer_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Signals the client that |curr_input_buffer_| has been read and can be
// returned. Will also release the mapping.
void ReturnCurrInputBuffer_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Waits for more surfaces to become available. Returns true once they do or
// false if an early exit has been requested (due to an initiated
// reset/flush/destroy).
bool WaitForSurfaces_Locked() EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Continue decoding given input buffers and sleep waiting for input/output
// as needed. Will exit if a new set of surfaces or reset/flush/destroy
// is requested.
void DecodeTask();
// Scheduled after receiving a flush request and executed after the current
// decoding task finishes decoding pending inputs. Makes the decoder return
// all remaining output pictures and puts it in an idle state, ready
// to resume if needed and schedules a FinishFlush.
void FlushTask();
// Scheduled by the FlushTask after decoder is flushed to put VAVDA into idle
// state and notify the client that flushing has been finished.
void FinishFlush();
// Scheduled after receiving a reset request and executed after the current
// decoding task finishes decoding the current frame. Puts the decoder into
// an idle state, ready to resume if needed, discarding decoded but not yet
// outputted pictures (decoder keeps ownership of their associated picture
// buffers). Schedules a FinishReset afterwards.
void ResetTask();
// Scheduled by ResetTask after it's done putting VAVDA into an idle state.
// Drops remaining input buffers and notifies the client that reset has been
// finished.
void FinishReset();
// Helper for Destroy(), doing all the actual work except for deleting self.
void Cleanup();
// Get a usable framebuffer configuration for use in binding textures
// or return false on failure.
bool InitializeFBConfig();
// Callback to be executed once we have a |va_surface| to be output and an
// available VaapiPicture in |available_picture_buffers_| for output. Puts
// contents of |va_surface| into the latter, releases the surface and passes
// the resulting picture to |client_| along with |visible_rect|.
void OutputPicture(scoped_refptr<VASurface> va_surface,
int32_t input_id,
gfx::Rect visible_rect,
const VideoColorSpace& picture_color_space);
// Try to OutputPicture() if we have both a ready surface and picture.
void TryOutputPicture();
// Called when a VASurface is no longer in use by |decoder_| nor |client_|.
// Returns it to |available_va_surfaces_|. |va_surface_id| is not used but it
// must be here to bind this method as VASurface::ReleaseCB.
void RecycleVASurface(std::unique_ptr<ScopedVASurfaceID> va_surface,
VASurfaceID va_surface_id);
// Request a new set of |num_pics| PictureBuffers to be allocated by
// |client_|. Up to |num_reference_frames| out of |num_pics_| might be needed
// by |decoder_|.
void InitiateSurfaceSetChange(size_t num_pics,
gfx::Size size,
size_t num_reference_frames,
const gfx::Rect& visible_rect);
// Check if the surfaces have been released or post ourselves for later.
void TryFinishSurfaceSetChange();
// Different modes of internal buffer allocations.
enum class BufferAllocationMode {
// Only using |client_|s provided PictureBuffers, none internal.
kNone,
// Using a reduced amount of |client_|s provided PictureBuffers and
// |decoder_|s GetNumReferenceFrames() internallly.
kSuperReduced,
// Similar to kSuperReduced, but we have to increase slightly the amount of
// PictureBuffers allocated for the |client_|.
kReduced,
// VaapiVideoDecodeAccelerator can work with this mode on all platforms.
// Using |client_|s provided PictureBuffers and as many internally
// allocated.
kNormal,
kWrapVdpau,
};
// Decides the concrete buffer allocation mode, depending on the hardware
// platform and other parameters.
BufferAllocationMode DecideBufferAllocationMode();
bool IsBufferAllocationModeReducedOrSuperReduced() const;
// VAVDA state.
enum State {
// Initialize() not called yet or failed.
kUninitialized,
// DecodeTask running.
kDecoding,
// Resetting, waiting for decoder to finish current task and cleanup.
kResetting,
// Idle, decoder in state ready to start/resume decoding.
kIdle,
// Destroying, waiting for the decoder to finish current task.
kDestroying,
};
base::Lock lock_;
State state_ GUARDED_BY(lock_);
// Only used on |task_runner_|.
Config::OutputMode output_mode_;
// Queue of available InputBuffers.
base::queue<std::unique_ptr<InputBuffer>> input_buffers_ GUARDED_BY(lock_);
// Signalled when input buffers are queued onto |input_buffers_| queue.
base::ConditionVariable input_ready_;
// Current input buffer at decoder. Only used on |decoder_thread_task_runner_|
std::unique_ptr<InputBuffer> curr_input_buffer_;
// Only used on |task_runner_|.
std::unique_ptr<VaapiPictureFactory> vaapi_picture_factory_;
// The following variables are constructed/initialized in Initialize() when
// the codec information is received. |vaapi_wrapper_| is thread safe.
scoped_refptr<VaapiWrapper> vaapi_wrapper_;
// Only used on |decoder_thread_task_runner_|.
std::unique_ptr<AcceleratedVideoDecoder> decoder_;
// TODO(crbug.com/1022246): Instead of having the raw pointer here, getting
// the pointer from AcceleratedVideoDecoder.
VaapiVideoDecoderDelegate* decoder_delegate_ = nullptr;
// Filled in during Initialize().
BufferAllocationMode buffer_allocation_mode_;
// VaapiWrapper for VPP (Video Post Processing). This is used for copying
// from a decoded surface to a surface bound to client's PictureBuffer.
scoped_refptr<VaapiWrapper> vpp_vaapi_wrapper_;
// All allocated VaapiPictures, regardless of their current state. Pictures
// are allocated at AssignPictureBuffers() and are kept until dtor or
// TryFinishSurfaceSetChange(). Comes after |vaapi_wrapper_| to ensure all
// pictures are destroyed before this is destroyed.
base::small_map<std::map<int32_t, std::unique_ptr<VaapiPicture>>> pictures_
GUARDED_BY(lock_);
// List of PictureBuffer ids available to be sent to |client_| via
// OutputPicture() (|client_| returns them via ReusePictureBuffer()).
std::list<int32_t> available_picture_buffers_ GUARDED_BY(lock_);
// VASurfaces available and that can be passed to |decoder_| for its use upon
// CreateSurface() request (and then returned via RecycleVASurface()).
std::list<std::unique_ptr<ScopedVASurfaceID>> available_va_surfaces_
GUARDED_BY(lock_);
// Signalled when output surfaces are queued into |available_va_surfaces_|.
base::ConditionVariable surfaces_available_;
// VASurfaceIDs format, filled in when created.
unsigned int va_surface_format_;
// Pending output requests from the decoder. When it indicates that we should
// output a surface and we have an available Picture (i.e. texture) ready
// to use, we'll execute the callback passing the Picture. The callback
// will put the contents of the surface into the picture and return it to
// the client, releasing the surface as well.
// If we don't have any available |pictures_| at the time when the decoder
// requests output, we'll store the request in this queue for later and run it
// once the client gives us more textures via ReusePictureBuffer().
// Only used on |task_runner_|.
base::queue<base::OnceClosure> pending_output_cbs_;
// WeakPtr<> pointing to |this| for use in posting tasks from the decoder
// thread back to the ChildThread. Because the decoder thread is a member of
// this class, any task running on the decoder thread is guaranteed that this
// object is still alive. As a result, tasks posted from ChildThread to
// decoder thread should use base::Unretained(this), and tasks posted from the
// decoder thread to the ChildThread should use |weak_this_|.
base::WeakPtr<VaapiVideoDecodeAccelerator> weak_this_;
// Callback used to recycle VASurfaces. Only used on |task_runner_|.
base::RepeatingCallback<void(std::unique_ptr<ScopedVASurfaceID>, VASurfaceID)>
va_surface_recycle_cb_;
// To expose client callbacks from VideoDecodeAccelerator. Used only on
// |task_runner_|.
std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_;
base::WeakPtr<Client> client_;
// ChildThread's task runner.
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::Thread decoder_thread_;
// Use this to post tasks to |decoder_thread_| instead of
// |decoder_thread_.task_runner()| because the latter will be NULL once
// |decoder_thread_.Stop()| returns.
scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_;
// Whether we are waiting for any |pending_output_cbs_| to be run before
// NotifyingFlushDone. Only used on |task_runner_|.
bool finish_flush_pending_;
// Decoder requested a new surface set and we are waiting for all the surfaces
// to be returned before we can free them. Only used on |task_runner_|.
bool awaiting_va_surfaces_recycle_;
// Last requested number/resolution/visible rectangle of output
// PictureBuffers.
size_t requested_num_pics_;
gfx::Size requested_pic_size_;
gfx::Rect requested_visible_rect_;
// Potential extra PictureBuffers to request, used only on
// BufferAllocationMode::kNone, see DecideBufferAllocationMode().
size_t num_extra_pics_ = 0;
// Max number of reference frames needed by |decoder_|. Only used on
// |task_runner_| and when in BufferAllocationMode::kNone.
size_t requested_num_reference_frames_;
size_t previously_requested_num_reference_frames_;
// The video stream's profile.
VideoCodecProfile profile_;
// Callback to make GL context current.
MakeGLContextCurrentCallback make_context_current_cb_;
// Callback to bind a GLImage to a given texture.
BindGLImageCallback bind_image_cb_;
// The WeakPtrFactory for |weak_this_|.
base::WeakPtrFactory<VaapiVideoDecodeAccelerator> weak_this_factory_;
};
} // namespace media
#endif // MEDIA_GPU_VAAPI_VAAPI_VIDEO_DECODE_ACCELERATOR_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,627 @@
// 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.
//
// This file contains an implementation of VaapiWrapper, used by
// VaapiVideoDecodeAccelerator and VaapiH264Decoder for decode,
// and VaapiVideoEncodeAccelerator for encode, to interface
// with libva (VA-API library for hardware video codec).
#ifndef MEDIA_GPU_VAAPI_VAAPI_WRAPPER_H_
#define MEDIA_GPU_VAAPI_VAAPI_WRAPPER_H_
#include <stddef.h>
#include <stdint.h>
#include <va/va.h>
#include <memory>
#include <set>
#include <vector>
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "build/chromeos_buildflags.h"
#include "media/gpu/chromeos/fourcc.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_utils.h"
#include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(USE_VAAPI_X11)
#include "ui/gfx/x/xproto.h" // nogncheck
#endif // BUILDFLAG(USE_VAAPI_X11)
namespace gfx {
enum class BufferFormat;
class NativePixmap;
class NativePixmapDmaBuf;
class Rect;
}
namespace media {
constexpr unsigned int kInvalidVaRtFormat = 0u;
class VideoFrame;
// Enum, function and callback type to allow VaapiWrapper to log errors in VA
// function calls executed on behalf of its owner. |histogram_name| is prebound
// to allow for disinguishing such owners.
enum class VaapiFunctions;
void ReportVaapiErrorToUMA(const std::string& histogram_name,
VaapiFunctions value);
using ReportErrorToUMACB = base::RepeatingCallback<void(VaapiFunctions)>;
// This struct holds a NativePixmapDmaBuf, usually the result of exporting a VA
// surface, and some associated size information needed to tell clients about
// the underlying buffer.
struct NativePixmapAndSizeInfo {
NativePixmapAndSizeInfo();
~NativePixmapAndSizeInfo();
// The VA-API internal buffer dimensions, which may be different than the
// dimensions requested at the time of creation of the surface (but always
// larger than or equal to those). This can be used for validation in, e.g.,
// testing.
gfx::Size va_surface_resolution;
// The size of the underlying Buffer Object. A use case for this is when an
// image decode is requested and the caller needs to know the size of the
// allocated buffer for caching purposes.
size_t byte_size = 0u;
// Contains the information needed to use the surface in a graphics API,
// including the visible size (|pixmap|->GetBufferSize()) which should be no
// larger than |va_surface_resolution|.
scoped_refptr<gfx::NativePixmapDmaBuf> pixmap;
};
enum class VAImplementation {
kMesaGallium,
kIntelI965,
kIntelIHD,
kNVIDIAVDPAU,
kOther,
kInvalid,
};
// This class handles VA-API calls and ensures proper locking of VA-API calls
// to libva, the userspace shim to the HW codec driver. libva is not
// thread-safe, so we have to perform locking ourselves. This class is fully
// synchronous and its constructor, all of its methods, and its destructor must
// be called on the same sequence. These methods may wait on the |va_lock_|
// which guards libva calls across all VaapiWrapper instances and other libva
// call sites.
//
// This class is responsible for managing VAAPI connection, contexts and state.
// It is also responsible for managing and freeing VABuffers (not VASurfaces),
// which are used to queue parameters and slice data to the HW codec,
// as well as underlying memory for VASurfaces themselves.
class MEDIA_GPU_EXPORT VaapiWrapper
: public base::RefCountedThreadSafe<VaapiWrapper> {
public:
enum CodecMode {
kDecode,
#if BUILDFLAG(IS_CHROMEOS_ASH)
// NOTE: A kDecodeProtected VaapiWrapper is created using the actual video
// profile and an extra VAProfileProtected, each with some special added
// VAConfigAttribs. Then when CreateProtectedSession() is called, it will
// then create a protected session using protected profile & entrypoint
// which gets attached to the decoding context (or attached when the
// decoding context is created or re-created). This then enables
// decrypt + decode support in the driver and encrypted frame data can then
// be submitted.
kDecodeProtected, // Decrypt + decode to protected surface.
#endif
kEncodeConstantBitrate, // Encode with Constant Bitrate algorithm.
kEncodeConstantQuantizationParameter, // Encode with Constant Quantization
// Parameter algorithm.
kVideoProcess,
kCodecModeMax,
};
// This is enum associated with VASurfaceAttribUsageHint.
enum class SurfaceUsageHint : int32_t {
kGeneric = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC,
kVideoDecoder = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER,
kVideoEncoder = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER,
kVideoProcessWrite = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE,
};
using InternalFormats = struct {
bool yuv420 : 1;
bool yuv420_10 : 1;
bool yuv422 : 1;
bool yuv444 : 1;
};
// Returns the type of the underlying VA-API implementation.
static VAImplementation GetImplementationType();
// Return an instance of VaapiWrapper initialized for |va_profile| and
// |mode|. |report_error_to_uma_cb| will be called independently from
// reporting errors to clients via method return values.
static scoped_refptr<VaapiWrapper> Create(
CodecMode mode,
VAProfile va_profile,
EncryptionScheme encryption_scheme,
const ReportErrorToUMACB& report_error_to_uma_cb);
// Create VaapiWrapper for VideoCodecProfile. It maps VideoCodecProfile
// |profile| to VAProfile.
// |report_error_to_uma_cb| will be called independently from reporting
// errors to clients via method return values.
static scoped_refptr<VaapiWrapper> CreateForVideoCodec(
CodecMode mode,
VideoCodecProfile profile,
EncryptionScheme encryption_scheme,
const ReportErrorToUMACB& report_error_to_uma_cb);
VaapiWrapper(const VaapiWrapper&) = delete;
VaapiWrapper& operator=(const VaapiWrapper&) = delete;
// Returns the supported SVC scalability modes for specified profile.
static std::vector<SVCScalabilityMode> GetSupportedScalabilityModes(
VideoCodecProfile media_profile,
VAProfile va_profile);
// Return the supported video encode profiles.
static VideoEncodeAccelerator::SupportedProfiles GetSupportedEncodeProfiles();
// Return the supported video decode profiles.
static VideoDecodeAccelerator::SupportedProfiles GetSupportedDecodeProfiles();
// Return true when decoding using |va_profile| is supported.
static bool IsDecodeSupported(VAProfile va_profile);
// Returns the supported internal formats for decoding using |va_profile|. If
// decoding is not supported for that profile, returns InternalFormats{}.
static InternalFormats GetDecodeSupportedInternalFormats(
VAProfile va_profile);
// Returns true if |rt_format| is supported for decoding using |va_profile|.
// Returns false if |rt_format| or |va_profile| is not supported for decoding.
static bool IsDecodingSupportedForInternalFormat(VAProfile va_profile,
unsigned int rt_format);
// Gets the minimum surface size allowed for decoding using |va_profile|.
// Returns true if the size can be obtained, false otherwise. The minimum
// dimension (width or height) returned is 1. Particularly, if a dimension is
// not reported by the driver, the dimension is returned as 1.
static bool GetDecodeMinResolution(VAProfile va_profile, gfx::Size* min_size);
// Gets the maximum surface size allowed for decoding using |va_profile|.
// Returns true if the size can be obtained, false otherwise. Because of the
// initialization in VASupportedProfiles::FillProfileInfo_Locked(), the size
// is guaranteed to not be empty (as long as this method returns true).
static bool GetDecodeMaxResolution(VAProfile va_profile, gfx::Size* max_size);
// Obtains a suitable FOURCC that can be used in vaCreateImage() +
// vaGetImage(). |rt_format| corresponds to the JPEG's subsampling format.
// |preferred_fourcc| is the FOURCC of the format preferred by the caller. If
// it is determined that the VAAPI driver can do the conversion from the
// internal format (|rt_format|), *|suitable_fourcc| is set to
// |preferred_fourcc|. Otherwise, it is set to a supported format. Returns
// true if a suitable FOURCC could be determined, false otherwise (e.g., if
// the |rt_format| is unsupported by the driver). If |preferred_fourcc| is not
// a supported image format, *|suitable_fourcc| is set to VA_FOURCC_I420.
static bool GetJpegDecodeSuitableImageFourCC(unsigned int rt_format,
uint32_t preferred_fourcc,
uint32_t* suitable_fourcc);
// Checks to see if VAProfileNone is supported on this decoder
static bool IsVppProfileSupported();
// Checks the surface size is allowed for VPP. Returns true if the size is
// supported, false otherwise.
static bool IsVppResolutionAllowed(const gfx::Size& size);
// Returns true if the VPP supports converting from/to |fourcc|.
static bool IsVppFormatSupported(uint32_t fourcc);
// Returns the pixel formats supported by the VPP.
static std::vector<Fourcc> GetVppSupportedFormats();
// Returns true if VPP supports the format conversion from a JPEG decoded
// internal surface to a FOURCC. |rt_format| corresponds to the JPEG's
// subsampling format. |fourcc| is the output surface's FOURCC.
static bool IsVppSupportedForJpegDecodedSurfaceToFourCC(
unsigned int rt_format,
uint32_t fourcc);
// Return true when JPEG encode is supported.
static bool IsJpegEncodeSupported();
// Return true when the specified image format is supported.
static bool IsImageFormatSupported(const VAImageFormat& format);
// Returns the list of VAImageFormats supported by the driver.
static const std::vector<VAImageFormat>& GetSupportedImageFormatsForTesting();
// Returns the list of supported profiles and entrypoints for a given |mode|.
static std::map<VAProfile, std::vector<VAEntrypoint>>
GetSupportedConfigurationsForCodecModeForTesting(CodecMode mode);
static VAEntrypoint GetDefaultVaEntryPoint(CodecMode mode, VAProfile profile);
static uint32_t BufferFormatToVARTFormat(gfx::BufferFormat fmt);
// Creates |num_surfaces| VASurfaceIDs of |va_format|, |size| and
// |surface_usage_hints| and, if successful, creates a |va_context_id_| of the
// same size. |surface_usage_hints| may affect an alignment and tiling of the
// created surface. Returns true if successful, with the created IDs in
// |va_surfaces|. The client is responsible for destroying |va_surfaces| via
// DestroyContextAndSurfaces() to free the allocated surfaces.
virtual bool CreateContextAndSurfaces(
unsigned int va_format,
const gfx::Size& size,
const std::vector<SurfaceUsageHint>& surface_usage_hints,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces) WARN_UNUSED_RESULT;
// Creates |num_surfaces| ScopedVASurfaces of |va_format| and |size| and, if
// successful, creates a |va_context_id_| of the same size. Returns an empty
// vector if creation failed. If |visible_size| is supplied, the returned
// ScopedVASurface's size is set to it. Otherwise, it's set to |size| (refer
// to CreateScopedVASurfaces() for details).
virtual std::vector<std::unique_ptr<ScopedVASurface>>
CreateContextAndScopedVASurfaces(
unsigned int va_format,
const gfx::Size& size,
const std::vector<SurfaceUsageHint>& usage_hints,
size_t num_surfaces,
const absl::optional<gfx::Size>& visible_size);
// Attempts to create a protected session that will be attached to the
// decoding context to enable encrypted video decoding. If it cannot be
// attached now, it will be attached when the decoding context is created or
// re-created. |encryption| should be the encryption scheme from the
// DecryptConfig. |hw_config| should have been obtained from the OEMCrypto
// implementation via the CdmFactoryDaemonProxy. |hw_identifier_out| is an
// output parameter which will return session specific information which can
// be passed through the ChromeOsCdmContext to retrieve encrypted key
// information. Returns true on success and false otherwise.
bool CreateProtectedSession(media::EncryptionScheme encryption,
const std::vector<uint8_t>& hw_config,
std::vector<uint8_t>* hw_identifier_out);
// Returns true if and only if we have created a protected session and
// querying libva indicates that our protected session is no longer alive,
// otherwise this will return false.
bool IsProtectedSessionDead();
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Returns true if and only if |va_protected_session_id| is not VA_INVALID_ID
// and querying libva indicates that the protected session identified by
// |va_protected_session_id| is no longer alive.
bool IsProtectedSessionDead(VAProtectedSessionID va_protected_session_id);
// Returns the ID of the current protected session or VA_INVALID_ID if there's
// none. This must be called on the same sequence as other methods that use
// the protected session ID internally.
//
// TODO(b/183515581): update this documentation once we force the VaapiWrapper
// to be used on a single sequence.
VAProtectedSessionID GetProtectedSessionID() const;
#endif
// If we have a protected session, destroys it immediately. This should be
// used as part of recovering dead protected sessions.
void DestroyProtectedSession();
// Releases the |va_surfaces| and destroys |va_context_id_|.
void DestroyContextAndSurfaces(std::vector<VASurfaceID> va_surfaces);
// Creates a VAContextID of |size| (unless it's a Vpp context in which case
// |size| is ignored and 0x0 is used instead). The client is responsible for
// releasing said context via DestroyContext() or DestroyContextAndSurfaces(),
// or it will be released on dtor. If a valid |va_protected_session_id_|
// exists, it will be attached to the newly created |va_context_id_| as well.
virtual bool CreateContext(const gfx::Size& size) WARN_UNUSED_RESULT;
// Destroys the context identified by |va_context_id_|.
virtual void DestroyContext();
// Requests |num_surfaces| ScopedVASurfaces of size |size|, |va_rt_format| and
// optionally |va_fourcc|. Returns self-cleaning ScopedVASurfaces or empty
// vector if creation failed. If |visible_size| is supplied, the returned
// ScopedVASurfaces' size are set to it: for example, we may want to request a
// 16x16 surface to decode a 13x12 JPEG: we may want to keep track of the
// visible size 13x12 inside the ScopedVASurface to inform the surface's users
// that that's the only region with meaningful content. If |visible_size| is
// not supplied, we store |size| in the returned ScopedVASurfaces.
virtual std::vector<std::unique_ptr<ScopedVASurface>> CreateScopedVASurfaces(
unsigned int va_rt_format,
const gfx::Size& size,
const std::vector<SurfaceUsageHint>& usage_hints,
size_t num_surfaces,
const absl::optional<gfx::Size>& visible_size,
const absl::optional<uint32_t>& va_fourcc);
// Creates a self-releasing VASurface from |pixmap|. The created VASurface
// shares the ownership of the underlying buffer represented by |pixmap|. The
// ownership of the surface is transferred to the caller. A caller can destroy
// |pixmap| after this method returns and the underlying buffer will be kept
// alive by the VASurface. |protected_content| should only be true if the
// format needs VA_RT_FORMAT_PROTECTED (currently only true for AMD).
virtual scoped_refptr<VASurface> CreateVASurfaceForPixmap(
scoped_refptr<gfx::NativePixmap> pixmap,
bool protected_content = false);
// Creates a self-releasing VASurface from |buffers|. The ownership of the
// surface is transferred to the caller. |buffers| should be a pointer array
// of size 1, with |buffer_size| corresponding to its size. |size| should be
// the desired surface dimensions (which does not need to map to |buffer_size|
// in any relevant way). |buffers| should be kept alive when using the
// VASurface and for accessing the data after the operation is complete.
scoped_refptr<VASurface> CreateVASurfaceForUserPtr(const gfx::Size& size,
uintptr_t* buffers,
size_t buffer_size);
// Syncs and exports |va_surface| as a gfx::NativePixmapDmaBuf. Currently, the
// only VAAPI surface pixel formats supported are VA_FOURCC_IMC3 and
// VA_FOURCC_NV12.
//
// Notes:
//
// - For VA_FOURCC_IMC3, the format of the returned NativePixmapDmaBuf is
// gfx::BufferFormat::YVU_420 because we don't have a YUV_420 format. The
// planes are flipped accordingly, i.e.,
// gfx::NativePixmapDmaBuf::GetDmaBufOffset(1) refers to the V plane.
// TODO(andrescj): revisit once crrev.com/c/1573718 lands.
//
// - For VA_FOURCC_NV12, the format of the returned NativePixmapDmaBuf is
// gfx::BufferFormat::YUV_420_BIPLANAR.
//
// Returns nullptr on failure.
std::unique_ptr<NativePixmapAndSizeInfo> ExportVASurfaceAsNativePixmapDmaBuf(
const ScopedVASurface& va_surface);
// Synchronize the VASurface explicitly. This is useful when sharing a surface
// between contexts.
bool SyncSurface(VASurfaceID va_surface_id) WARN_UNUSED_RESULT;
// Calls SubmitBuffer_Locked() to request libva to allocate a new VABufferID
// of |va_buffer_type| and |size|, and to map-and-copy the |data| into it. The
// allocated VABufferIDs stay alive until DestroyPendingBuffers_Locked(). Note
// that this method does not submit the buffers for execution, they are simply
// stored until ExecuteAndDestroyPendingBuffers()/Execute_Locked(). The
// ownership of |data| stays with the caller. On failure, all pending buffers
// are destroyed.
bool SubmitBuffer(VABufferType va_buffer_type,
size_t size,
const void* data) WARN_UNUSED_RESULT;
// Convenient templatized version of SubmitBuffer() where |size| is deduced to
// be the size of the type of |*data|.
template <typename T>
bool WARN_UNUSED_RESULT SubmitBuffer(VABufferType va_buffer_type,
const T* data) {
CHECK(sequence_checker_.CalledOnValidSequence());
return SubmitBuffer(va_buffer_type, sizeof(T), data);
}
// Batch-version of SubmitBuffer(), where the lock for accessing libva is
// acquired only once.
struct VABufferDescriptor {
VABufferType type;
size_t size;
const void* data;
};
bool SubmitBuffers(const std::vector<VABufferDescriptor>& va_buffers)
WARN_UNUSED_RESULT;
// Destroys all |pending_va_buffers_| sent via SubmitBuffer*(). Useful when a
// pending job is to be cancelled (on reset or error).
void DestroyPendingBuffers();
// Executes job in hardware on target |va_surface_id| and destroys pending
// buffers. Returns false if Execute() fails.
virtual bool ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id)
WARN_UNUSED_RESULT;
// Maps each |va_buffers| ID and copies the data described by the associated
// VABufferDescriptor into it; then calls Execute_Locked() on |va_surface_id|.
bool MapAndCopyAndExecute(
VASurfaceID va_surface_id,
const std::vector<std::pair<VABufferID, VABufferDescriptor>>& va_buffers)
WARN_UNUSED_RESULT;
#if BUILDFLAG(USE_VAAPI_X11)
// Put data from |va_surface_id| into |x_pixmap| of size
// |dest_size|, converting/scaling to it.
bool PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
x11::Pixmap x_pixmap,
gfx::Size dest_size) WARN_UNUSED_RESULT;
#endif // BUILDFLAG(USE_VAAPI_X11)
// Creates a ScopedVAImage from a VASurface |va_surface_id| and map it into
// memory with the given |format| and |size|. If |format| is not equal to the
// internal format, the underlying implementation will do format conversion if
// supported. |size| should be smaller than or equal to the surface. If |size|
// is smaller, the image will be cropped.
std::unique_ptr<ScopedVAImage> CreateVaImage(VASurfaceID va_surface_id,
VAImageFormat* format,
const gfx::Size& size);
// Uploads contents of |frame| into |va_surface_id| for encode.
virtual bool UploadVideoFrameToSurface(const VideoFrame& frame,
VASurfaceID va_surface_id,
const gfx::Size& va_surface_size)
WARN_UNUSED_RESULT;
// Creates a buffer of |size| bytes to be used as encode output.
virtual std::unique_ptr<ScopedVABuffer> CreateVABuffer(VABufferType type,
size_t size);
// Gets the encoded frame linear size of the buffer with given |buffer_id|.
// |sync_surface_id| will be used as a sync point, i.e. it will have to become
// idle before starting the acquirement. |sync_surface_id| should be the
// source surface passed to the encode job. Returns 0 if it fails for any
// reason.
virtual uint64_t GetEncodedChunkSize(VABufferID buffer_id,
VASurfaceID sync_surface_id)
WARN_UNUSED_RESULT;
// Downloads the contents of the buffer with given |buffer_id| into a buffer
// of size |target_size|, pointed to by |target_ptr|. The number of bytes
// downloaded will be returned in |coded_data_size|. |sync_surface_id| will
// be used as a sync point, i.e. it will have to become idle before starting
// the download. |sync_surface_id| should be the source surface passed
// to the encode job. Returns false if it fails for any reason. For example,
// the linear size of the resulted encoded frame is larger than |target_size|.
virtual bool DownloadFromVABuffer(VABufferID buffer_id,
VASurfaceID sync_surface_id,
uint8_t* target_ptr,
size_t target_size,
size_t* coded_data_size) WARN_UNUSED_RESULT;
// Get the max number of reference frames for encoding supported by the
// driver.
// For H.264 encoding, the value represents the maximum number of reference
// frames for both the reference picture list 0 (bottom 16 bits) and the
// reference picture list 1 (top 16 bits).
virtual bool GetVAEncMaxNumOfRefFrames(VideoCodecProfile profile,
size_t* max_ref_frames)
WARN_UNUSED_RESULT;
// Gets packed headers are supported for encoding. This is called for
// H264 encoding. |packed_sps|, |packed_pps| and |packed_slice| stands for
// whether packed slice parameter set, packed picture parameter set and packed
// slice header is supported, respectively.
virtual bool GetSupportedPackedHeaders(VideoCodecProfile profile,
bool& packed_sps,
bool& packed_pps,
bool& packed_slice) WARN_UNUSED_RESULT;
// Checks if the driver supports frame rotation.
bool IsRotationSupported();
// Blits a VASurface |va_surface_src| into another VASurface
// |va_surface_dest| applying pixel format conversion, rotation, cropping
// and scaling if needed. |src_rect| and |dest_rect| are optional. They can
// be used to specify the area used in the blit. If |va_protected_session_id|
// is provided and is not VA_INVALID_ID, the corresponding protected session
// is attached to the VPP context prior to submitting the VPP buffers and
// detached after submitting those buffers.
virtual bool BlitSurface(
const VASurface& va_surface_src,
const VASurface& va_surface_dest,
absl::optional<gfx::Rect> src_rect = absl::nullopt,
absl::optional<gfx::Rect> dest_rect = absl::nullopt,
VideoRotation rotation = VIDEO_ROTATION_0
#if BUILDFLAG(IS_CHROMEOS_ASH)
,
VAProtectedSessionID va_protected_session_id = VA_INVALID_ID
#endif
) WARN_UNUSED_RESULT;
// Initialize static data before sandbox is enabled.
static void PreSandboxInitialization();
// vaDestroySurfaces() a vector or a single VASurfaceID.
virtual void DestroySurfaces(std::vector<VASurfaceID> va_surfaces);
virtual void DestroySurface(VASurfaceID va_surface_id);
protected:
VaapiWrapper(CodecMode mode);
virtual ~VaapiWrapper();
private:
friend class base::RefCountedThreadSafe<VaapiWrapper>;
friend class VaapiWrapperTest;
friend class VaapiVideoEncodeAcceleratorTest;
FRIEND_TEST_ALL_PREFIXES(VaapiTest, LowQualityEncodingSetting);
FRIEND_TEST_ALL_PREFIXES(VaapiUtilsTest, ScopedVAImage);
FRIEND_TEST_ALL_PREFIXES(VaapiUtilsTest, BadScopedVAImage);
FRIEND_TEST_ALL_PREFIXES(VaapiUtilsTest, BadScopedVABufferMapping);
FRIEND_TEST_ALL_PREFIXES(VaapiMinigbmTest, AllocateAndCompareWithMinigbm);
bool Initialize(VAProfile va_profile,
EncryptionScheme encryption_scheme) WARN_UNUSED_RESULT;
void Deinitialize();
bool VaInitialize(const ReportErrorToUMACB& report_error_to_uma_cb)
WARN_UNUSED_RESULT;
// Tries to allocate |num_surfaces| VASurfaceIDs of |size| and |va_format|.
// Fills |va_surfaces| and returns true if successful, or returns false.
bool CreateSurfaces(unsigned int va_format,
const gfx::Size& size,
const std::vector<SurfaceUsageHint>& usage_hints,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces) WARN_UNUSED_RESULT;
// Carries out the vaBeginPicture()-vaRenderPicture()-vaEndPicture() on target
// |va_surface_id|. Returns false if any of these calls fails.
bool Execute_Locked(VASurfaceID va_surface_id,
const std::vector<VABufferID>& va_buffers)
EXCLUSIVE_LOCKS_REQUIRED(va_lock_) WARN_UNUSED_RESULT;
virtual void DestroyPendingBuffers_Locked()
EXCLUSIVE_LOCKS_REQUIRED(va_lock_);
// Requests libva to allocate a new VABufferID of type |va_buffer.type|, then
// maps-and-copies |va_buffer.size| contents of |va_buffer.data| to it. If a
// failure occurs, calls DestroyPendingBuffers_Locked() and returns false.
virtual bool SubmitBuffer_Locked(const VABufferDescriptor& va_buffer)
EXCLUSIVE_LOCKS_REQUIRED(va_lock_) WARN_UNUSED_RESULT;
// Maps |va_buffer_id| and, if successful, copies the contents of |va_buffer|
// into it.
bool MapAndCopy_Locked(VABufferID va_buffer_id,
const VABufferDescriptor& va_buffer)
EXCLUSIVE_LOCKS_REQUIRED(va_lock_) WARN_UNUSED_RESULT;
// Queries whether |va_profile_| and |va_entrypoint_| support encoding quality
// setting and, if available, configures it to its maximum value, for lower
// consumption and maximum speed.
void MaybeSetLowQualityEncoding_Locked() EXCLUSIVE_LOCKS_REQUIRED(va_lock_);
// If a protected session is active, attaches it to the decoding context.
bool MaybeAttachProtectedSession_Locked()
EXCLUSIVE_LOCKS_REQUIRED(va_lock_) WARN_UNUSED_RESULT;
const CodecMode mode_;
base::SequenceCheckerImpl sequence_checker_;
// Pointer to VADisplayState's member |va_lock_|. Guaranteed to be valid for
// the lifetime of VaapiWrapper.
base::Lock* va_lock_;
// VA handles.
// All valid after successful Initialize() and until Deinitialize().
VADisplay va_display_ GUARDED_BY(va_lock_);
VAConfigID va_config_id_{VA_INVALID_ID};
// Created in CreateContext() or CreateContextAndSurfaces() and valid until
// DestroyContext() or DestroyContextAndSurfaces().
VAContextID va_context_id_{VA_INVALID_ID};
// Profile and entrypoint configured for the corresponding |va_context_id_|.
VAProfile va_profile_;
VAEntrypoint va_entrypoint_;
// Data queued up for HW codec, to be committed on next execution.
// TODO(b/166646505): let callers manage the lifetime of these buffers.
std::vector<VABufferID> pending_va_buffers_;
// VA buffer to be used for kVideoProcess. Allocated the first time around,
// and reused afterwards.
std::unique_ptr<ScopedVABuffer> va_buffer_for_vpp_;
#if BUILDFLAG(IS_CHROMEOS_ASH)
// For protected decode mode.
VAConfigID va_protected_config_id_{VA_INVALID_ID};
VAProtectedSessionID va_protected_session_id_{VA_INVALID_ID};
#endif
// Called to report codec errors to UMA. Errors to clients are reported via
// return values from public methods.
ReportErrorToUMACB report_error_to_uma_cb_;
};
} // namespace media
#endif // MEDIA_GPU_VAAPI_VAAPI_WRAPPER_H_

1146
ui/base/x/x11_util.cc Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,677 @@
// Copyright 2019 the V8 project 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 V8_INTL_SUPPORT
#error Internationalization is expected to be enabled.
#endif // V8_INTL_SUPPORT
#include "src/objects/js-display-names.h"
#include <memory>
#include <vector>
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/objects/intl-objects.h"
#include "src/objects/js-display-names-inl.h"
#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/dtfmtsym.h"
#include "unicode/dtptngen.h"
#include "unicode/localebuilder.h"
#include "unicode/locdspnm.h"
#include "unicode/measfmt.h"
#include "unicode/timezone.h"
#include "unicode/tznames.h"
#include "unicode/uloc.h"
#include "unicode/unistr.h"
#include "unicode/uscript.h"
namespace v8 {
namespace internal {
namespace {
// Type: identifying the types of the display names.
//
// ecma402/#sec-properties-of-intl-displaynames-instances
enum class Type {
kUndefined,
kLanguage,
kRegion,
kScript,
kCurrency,
kCalendar,
kDateTimeField
};
bool IsUnicodeScriptSubtag(const std::string& value) {
UErrorCode status = U_ZERO_ERROR;
icu::LocaleBuilder builder;
builder.setScript(value).build(status);
return U_SUCCESS(status);
}
bool IsUnicodeRegionSubtag(const std::string& value) {
UErrorCode status = U_ZERO_ERROR;
icu::LocaleBuilder builder;
builder.setRegion(value).build(status);
return U_SUCCESS(status);
}
UDisplayContext ToUDisplayContext(JSDisplayNames::Style style) {
switch (style) {
case JSDisplayNames::Style::kLong:
return UDISPCTX_LENGTH_FULL;
case JSDisplayNames::Style::kShort:
case JSDisplayNames::Style::kNarrow:
return UDISPCTX_LENGTH_SHORT;
}
}
} // anonymous namespace
// Abstract class for all different types.
class DisplayNamesInternal {
public:
DisplayNamesInternal() = default;
virtual ~DisplayNamesInternal() = default;
virtual const char* type() const = 0;
virtual icu::Locale locale() const = 0;
virtual Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const = 0;
};
namespace {
class LocaleDisplayNamesCommon : public DisplayNamesInternal {
public:
LocaleDisplayNamesCommon(const icu::Locale& locale,
JSDisplayNames::Style style, bool fallback,
bool dialect)
: style_(style) {
UDisplayContext sub =
fallback ? UDISPCTX_SUBSTITUTE : UDISPCTX_NO_SUBSTITUTE;
UDisplayContext dialect_context =
dialect ? UDISPCTX_DIALECT_NAMES : UDISPCTX_STANDARD_NAMES;
UDisplayContext display_context[] = {ToUDisplayContext(style_),
dialect_context,
UDISPCTX_CAPITALIZATION_NONE, sub};
ldn_.reset(
icu::LocaleDisplayNames::createInstance(locale, display_context, 4));
}
~LocaleDisplayNamesCommon() override = default;
icu::Locale locale() const override { return ldn_->getLocale(); }
protected:
icu::LocaleDisplayNames* locale_display_names() const { return ldn_.get(); }
private:
std::unique_ptr<icu::LocaleDisplayNames> ldn_;
JSDisplayNames::Style style_;
};
class LanguageNames : public LocaleDisplayNamesCommon {
public:
LanguageNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~LanguageNames() override = default;
const char* type() const override { return "language"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
UErrorCode status = U_ZERO_ERROR;
// 1.a If code does not match the unicode_language_id production, throw a
// RangeError exception.
// 1.b If IsStructurallyValidLanguageTag(code) is false, throw a RangeError
// exception.
icu::Locale l =
icu::Locale::createCanonical(icu::Locale::forLanguageTag(code, status).getBaseName());
std::string checked = l.toLanguageTag<std::string>(status);
if (U_FAILURE(status)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
icu::UnicodeString result;
locale_display_names()->localeDisplayName(checked.c_str(), result);
return Just(result);
}
};
class RegionNames : public LocaleDisplayNamesCommon {
public:
RegionNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~RegionNames() override = default;
const char* type() const override { return "region"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
if (!IsUnicodeRegionSubtag(code_str)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
icu::UnicodeString result;
locale_display_names()->regionDisplayName(code_str.c_str(), result);
return Just(result);
}
};
class ScriptNames : public LocaleDisplayNamesCommon {
public:
ScriptNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect) {}
~ScriptNames() override = default;
const char* type() const override { return "script"; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
if (!IsUnicodeScriptSubtag(code_str)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
icu::UnicodeString result;
locale_display_names()->scriptDisplayName(code_str.c_str(), result);
return Just(result);
}
};
class KeyValueDisplayNames : public LocaleDisplayNamesCommon {
public:
KeyValueDisplayNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect, const char* key,
bool prevent_fallback)
: LocaleDisplayNamesCommon(locale, style, fallback, dialect),
key_(key),
prevent_fallback_(prevent_fallback) {}
~KeyValueDisplayNames() override = default;
const char* type() const override { return key_.c_str(); }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
icu::UnicodeString result;
locale_display_names()->keyValueDisplayName(key_.c_str(), code_str.c_str(),
result);
// Work around the issue that the keyValueDisplayNames ignore no
// substituion and always fallback.
if (prevent_fallback_ && (result.length() == 3) &&
(code_str.length() == 3) &&
(result == icu::UnicodeString(code_str.c_str(), -1, US_INV))) {
result.setToBogus();
}
return Just(result);
}
private:
std::string key_;
bool prevent_fallback_;
};
class CurrencyNames : public KeyValueDisplayNames {
public:
CurrencyNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: KeyValueDisplayNames(locale, style, fallback, dialect, "currency",
fallback == false) {}
~CurrencyNames() override = default;
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
if (!Intl::IsWellFormedCurrency(code_str)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
return KeyValueDisplayNames::of(isolate, code);
}
};
class CalendarNames : public KeyValueDisplayNames {
public:
CalendarNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback, bool dialect)
: KeyValueDisplayNames(locale, style, fallback, dialect, "calendar",
false) {}
~CalendarNames() override = default;
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
std::string code_str(code);
if (!Intl::IsWellFormedCalendar(code_str)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
return KeyValueDisplayNames::of(isolate, strcmp(code, "gregory") == 0
? "gregorian"
: strcmp(code, "ethioaa") == 0
? "ethiopic-amete-alem"
: code);
}
};
UDateTimePGDisplayWidth StyleToUDateTimePGDisplayWidth(
JSDisplayNames::Style style) {
switch (style) {
case JSDisplayNames::Style::kLong:
return UDATPG_WIDE;
case JSDisplayNames::Style::kShort:
return UDATPG_ABBREVIATED;
case JSDisplayNames::Style::kNarrow:
return UDATPG_NARROW;
}
}
UDateTimePatternField StringToUDateTimePatternField(const char* code) {
switch (code[0]) {
case 'd':
if (strcmp(code, "day") == 0) return UDATPG_DAY_FIELD;
if (strcmp(code, "dayPeriod") == 0) return UDATPG_DAYPERIOD_FIELD;
break;
case 'e':
if (strcmp(code, "era") == 0) return UDATPG_ERA_FIELD;
break;
case 'h':
if (strcmp(code, "hour") == 0) return UDATPG_HOUR_FIELD;
break;
case 'm':
if (strcmp(code, "minute") == 0) return UDATPG_MINUTE_FIELD;
if (strcmp(code, "month") == 0) return UDATPG_MONTH_FIELD;
break;
case 'q':
if (strcmp(code, "quarter") == 0) return UDATPG_QUARTER_FIELD;
break;
case 's':
if (strcmp(code, "second") == 0) return UDATPG_SECOND_FIELD;
break;
case 't':
if (strcmp(code, "timeZoneName") == 0) return UDATPG_ZONE_FIELD;
break;
case 'w':
if (strcmp(code, "weekOfYear") == 0) return UDATPG_WEEK_OF_YEAR_FIELD;
if (strcmp(code, "weekday") == 0) return UDATPG_WEEKDAY_FIELD;
break;
case 'y':
if (strcmp(code, "year") == 0) return UDATPG_YEAR_FIELD;
break;
default:
break;
}
return UDATPG_FIELD_COUNT;
}
class DateTimeFieldNames : public DisplayNamesInternal {
public:
DateTimeFieldNames(const icu::Locale& locale, JSDisplayNames::Style style,
bool fallback)
: locale_(locale), width_(StyleToUDateTimePGDisplayWidth(style)) {
UErrorCode status = U_ZERO_ERROR;
generator_.reset(
icu::DateTimePatternGenerator::createInstance(locale_, status));
DCHECK(U_SUCCESS(status));
}
~DateTimeFieldNames() override = default;
const char* type() const override { return "dateTimeField"; }
icu::Locale locale() const override { return locale_; }
Maybe<icu::UnicodeString> of(Isolate* isolate,
const char* code) const override {
UDateTimePatternField field = StringToUDateTimePatternField(code);
if (field == UDATPG_FIELD_COUNT) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalidArgument),
Nothing<icu::UnicodeString>());
}
return Just(generator_->getFieldDisplayName(field, width_));
}
private:
icu::Locale locale_;
UDateTimePGDisplayWidth width_;
std::unique_ptr<icu::DateTimePatternGenerator> generator_;
};
DisplayNamesInternal* CreateInternal(const icu::Locale& locale,
JSDisplayNames::Style style, Type type,
bool fallback, bool dialect) {
switch (type) {
case Type::kLanguage:
return new LanguageNames(locale, style, fallback, dialect);
case Type::kRegion:
return new RegionNames(locale, style, fallback, false);
case Type::kScript:
return new ScriptNames(locale, style, fallback, false);
case Type::kCurrency:
return new CurrencyNames(locale, style, fallback, false);
case Type::kCalendar:
return new CalendarNames(locale, style, fallback, false);
case Type::kDateTimeField:
return new DateTimeFieldNames(locale, style, fallback);
default:
UNREACHABLE();
}
}
} // anonymous namespace
// ecma402 #sec-Intl.DisplayNames
MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
Handle<Map> map,
Handle<Object> locales,
Handle<Object> input_options) {
const char* service = "Intl.DisplayNames";
Factory* factory = isolate->factory();
Handle<JSReceiver> options;
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales);
MAYBE_RETURN(maybe_requested_locales, Handle<JSDisplayNames>());
std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust();
// 4. Let options be ? GetOptionsObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
GetOptionsObject(isolate, input_options, service),
JSDisplayNames);
// Note: No need to create a record. It's not observable.
// 5. Let opt be a new Record.
// 6. Let localeData be %DisplayNames%.[[LocaleData]].
// 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDisplayNames>());
// 8. Set opt.[[localeMatcher]] to matcher.
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
// ecma402/#sec-Intl.DisplayNames-internal-slots
// The value of the [[RelevantExtensionKeys]] internal slot is
// « ».
std::set<std::string> relevant_extension_keys = {};
// 9. Let r be ResolveLocale(%DisplayNames%.[[AvailableLocales]],
// requestedLocales, opt, %DisplayNames%.[[RelevantExtensionKeys]]).
Maybe<Intl::ResolvedLocale> maybe_resolve_locale =
Intl::ResolveLocale(isolate, JSDisplayNames::GetAvailableLocales(),
requested_locales, matcher, relevant_extension_keys);
if (maybe_resolve_locale.IsNothing()) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
JSDisplayNames);
}
Intl::ResolvedLocale r = maybe_resolve_locale.FromJust();
icu::Locale icu_locale = r.icu_locale;
// 10. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = GetStringOption<Style>(
isolate, options, "style", service, {"long", "short", "narrow"},
{Style::kLong, Style::kShort, Style::kNarrow}, Style::kLong);
MAYBE_RETURN(maybe_style, MaybeHandle<JSDisplayNames>());
Style style_enum = maybe_style.FromJust();
// 11. Set displayNames.[[Style]] to style.
// 12. Let type be ? GetOption(options, "type", "string", « "language",
// "region", "script", "currency" , "calendar", "dateTimeField", "unit"»,
// undefined).
Maybe<Type> maybe_type =
FLAG_harmony_intl_displaynames_v2
? GetStringOption<Type>(
isolate, options, "type", service,
{"language", "region", "script", "currency", "calendar",
"dateTimeField"},
{Type::kLanguage, Type::kRegion, Type::kScript, Type::kCurrency,
Type::kCalendar, Type::kDateTimeField},
Type::kUndefined)
: GetStringOption<Type>(isolate, options, "type", service,
{"language", "region", "script", "currency"},
{
Type::kLanguage,
Type::kRegion,
Type::kScript,
Type::kCurrency,
},
Type::kUndefined);
MAYBE_RETURN(maybe_type, MaybeHandle<JSDisplayNames>());
Type type_enum = maybe_type.FromJust();
// 13. If type is undefined, throw a TypeError exception.
if (type_enum == Type::kUndefined) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kInvalidArgument),
JSDisplayNames);
}
// 14. Set displayNames.[[Type]] to type.
// 15. Let fallback be ? GetOption(options, "fallback", "string",
// « "code", "none" », "code").
Maybe<Fallback> maybe_fallback = GetStringOption<Fallback>(
isolate, options, "fallback", service, {"code", "none"},
{Fallback::kCode, Fallback::kNone}, Fallback::kCode);
MAYBE_RETURN(maybe_fallback, MaybeHandle<JSDisplayNames>());
Fallback fallback_enum = maybe_fallback.FromJust();
// 16. Set displayNames.[[Fallback]] to fallback.
LanguageDisplay language_display_enum = LanguageDisplay::kDialect;
if (FLAG_harmony_intl_displaynames_v2) {
// 24. Let languageDisplay be ? GetOption(options, "languageDisplay",
// "string", « "dialect", "standard" », "dialect").
Maybe<LanguageDisplay> maybe_language_display =
GetStringOption<LanguageDisplay>(
isolate, options, "languageDisplay", service,
{"dialect", "standard"},
{LanguageDisplay::kDialect, LanguageDisplay::kStandard},
LanguageDisplay::kDialect);
MAYBE_RETURN(maybe_language_display, MaybeHandle<JSDisplayNames>());
// 25. If type is "language", then
if (type_enum == Type::kLanguage) {
// a. Set displayNames.[[LanguageDisplay]] to languageDisplay.
language_display_enum = maybe_language_display.FromJust();
}
}
// Set displayNames.[[Fallback]] to fallback.
// 17. Set displayNames.[[Locale]] to the value of r.[[Locale]].
// Let dataLocale be r.[[dataLocale]].
// Let dataLocaleData be localeData.[[<dataLocale>]].
// Let types be dataLocaleData.[[types]].
// Assert: types is a Record (see 1.3.3).
// Let typeFields be types.[[<type>]].
// Assert: typeFields is a Record (see 1.3.3).
// Let styleFields be typeFields.[[<style>]].
// Assert: styleFields is a Record (see 1.3.3).
// Set displayNames.[[Fields]] to styleFields.
DisplayNamesInternal* internal = CreateInternal(
icu_locale, style_enum, type_enum, fallback_enum == Fallback::kCode,
language_display_enum == LanguageDisplay::kDialect);
if (internal == nullptr) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError),
JSDisplayNames);
}
Handle<Managed<DisplayNamesInternal>> managed_internal =
Managed<DisplayNamesInternal>::FromRawPtr(isolate, 0, internal);
Handle<JSDisplayNames> display_names =
Handle<JSDisplayNames>::cast(factory->NewFastOrSlowJSObjectFromMap(map));
display_names->set_flags(0);
display_names->set_style(style_enum);
display_names->set_fallback(fallback_enum);
display_names->set_language_display(language_display_enum);
DisallowGarbageCollection no_gc;
display_names->set_internal(*managed_internal);
// Return displayNames.
return display_names;
}
// ecma402 #sec-Intl.DisplayNames.prototype.resolvedOptions
Handle<JSObject> JSDisplayNames::ResolvedOptions(
Isolate* isolate, Handle<JSDisplayNames> display_names) {
Factory* factory = isolate->factory();
// 4. Let options be ! ObjectCreate(%ObjectPrototype%).
Handle<JSObject> options = factory->NewJSObject(isolate->object_function());
DisplayNamesInternal* internal = display_names->internal().raw();
Maybe<std::string> maybe_locale = Intl::ToLanguageTag(internal->locale());
DCHECK(maybe_locale.IsJust());
Handle<String> locale = isolate->factory()->NewStringFromAsciiChecked(
maybe_locale.FromJust().c_str());
Handle<String> style = display_names->StyleAsString();
Handle<String> type = factory->NewStringFromAsciiChecked(internal->type());
Handle<String> fallback = display_names->FallbackAsString();
Handle<String> language_display = display_names->LanguageDisplayAsString();
Maybe<bool> maybe_create_locale = JSReceiver::CreateDataProperty(
isolate, options, factory->locale_string(), locale, Just(kDontThrow));
DCHECK(maybe_create_locale.FromJust());
USE(maybe_create_locale);
Maybe<bool> maybe_create_style = JSReceiver::CreateDataProperty(
isolate, options, factory->style_string(), style, Just(kDontThrow));
DCHECK(maybe_create_style.FromJust());
USE(maybe_create_style);
Maybe<bool> maybe_create_type = JSReceiver::CreateDataProperty(
isolate, options, factory->type_string(), type, Just(kDontThrow));
DCHECK(maybe_create_type.FromJust());
USE(maybe_create_type);
Maybe<bool> maybe_create_fallback = JSReceiver::CreateDataProperty(
isolate, options, factory->fallback_string(), fallback, Just(kDontThrow));
DCHECK(maybe_create_fallback.FromJust());
USE(maybe_create_fallback);
if (FLAG_harmony_intl_displaynames_v2) {
if (std::strcmp("language", internal->type()) == 0) {
Maybe<bool> maybe_create_language_display =
JSReceiver::CreateDataProperty(isolate, options,
factory->languageDisplay_string(),
language_display, Just(kDontThrow));
DCHECK(maybe_create_language_display.FromJust());
USE(maybe_create_language_display);
}
}
return options;
}
// ecma402 #sec-Intl.DisplayNames.prototype.of
MaybeHandle<Object> JSDisplayNames::Of(Isolate* isolate,
Handle<JSDisplayNames> display_names,
Handle<Object> code_obj) {
Handle<String> code;
ASSIGN_RETURN_ON_EXCEPTION(isolate, code, Object::ToString(isolate, code_obj),
Object);
DisplayNamesInternal* internal = display_names->internal().raw();
Maybe<icu::UnicodeString> maybe_result =
internal->of(isolate, code->ToCString().get());
MAYBE_RETURN(maybe_result, Handle<Object>());
icu::UnicodeString result = maybe_result.FromJust();
if (result.isBogus()) {
return isolate->factory()->undefined_value();
}
return Intl::ToString(isolate, result).ToHandleChecked();
}
namespace {
struct CheckCalendar {
static const char* key() { return "calendar"; }
static const char* path() { return nullptr; }
};
} // namespace
const std::set<std::string>& JSDisplayNames::GetAvailableLocales() {
static base::LazyInstance<Intl::AvailableLocales<CheckCalendar>>::type
available_locales = LAZY_INSTANCE_INITIALIZER;
return available_locales.Pointer()->Get();
}
Handle<String> JSDisplayNames::StyleAsString() const {
switch (style()) {
case Style::kLong:
return GetReadOnlyRoots().long_string_handle();
case Style::kShort:
return GetReadOnlyRoots().short_string_handle();
case Style::kNarrow:
return GetReadOnlyRoots().narrow_string_handle();
}
UNREACHABLE();
}
Handle<String> JSDisplayNames::FallbackAsString() const {
switch (fallback()) {
case Fallback::kCode:
return GetReadOnlyRoots().code_string_handle();
case Fallback::kNone:
return GetReadOnlyRoots().none_string_handle();
}
UNREACHABLE();
}
Handle<String> JSDisplayNames::LanguageDisplayAsString() const {
switch (language_display()) {
case LanguageDisplay::kDialect:
return GetReadOnlyRoots().dialect_string_handle();
case LanguageDisplay::kStandard:
return GetReadOnlyRoots().standard_string_handle();
}
UNREACHABLE();
}
} // namespace internal
} // namespace v8