diff --git a/build/cromite_patches_list.txt b/build/cromite_patches_list.txt index 7efc4742..92f557af 100644 --- a/build/cromite_patches_list.txt +++ b/build/cromite_patches_list.txt @@ -24,7 +24,6 @@ Restore-classic-new-tab-page.patch Always-use-new-tab-page-for-default-home-page.patch disable-battery-status-updater.patch Battery-API-return-nothing.patch -updater-disable-updater-pings.patch Disable-omission-of-URL-elements.patch Modify-default-preferences.patch Do-not-store-passwords-by-default.patch @@ -183,7 +182,6 @@ WIN-Add-some-prefs-to-secure-preferences.patch WIN-Disable-search-for-image.patch AudioBuffer-AnalyserNode-fp-mitigations.patch -Disable-Component-Updates.patch add-browser-policy.patch Always-open-browser-controls-in-new-tab.patch Partitioning-all-cookies-by-top-frame-domain.patch @@ -304,6 +302,8 @@ Never-treat-Proguard-warnings-as-errors.patch Temp-disable-experimental-web-platform-features.patch Block-leakage-of-urls-in-sandbox-iframes.patch Fix-chromium-build-bugs.patch +Enable-component-updater.patch +Android-fonts-fingerprinting-mitigation.patch # adblock patches eyeo-beta-118.0.5993.48-base.patch diff --git a/build/patches/Add-cromite-flags-support.patch b/build/patches/Add-cromite-flags-support.patch index 03c79c73..b65de278 100644 --- a/build/patches/Add-cromite-flags-support.patch +++ b/build/patches/Add-cromite-flags-support.patch @@ -25,6 +25,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html .../privacy/settings/PrivacySettings.java | 2 +- .../settings/FragmentDependencyProvider.java | 10 +- .../browser/settings/SettingsActivity.java | 42 ++++- + .../tracing/settings/DeveloperSettings.java | 5 +- chrome/browser/about_flags.cc | 11 ++ chrome/browser/browser_features.cc | 1 + chrome/browser/browser_features.h | 1 + @@ -105,7 +106,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html third_party/blink/public/common/features.h | 1 + ui/base/ui_base_features.cc | 1 + ui/base/ui_base_features.h | 1 + - 92 files changed, 805 insertions(+), 28 deletions(-) + 93 files changed, 808 insertions(+), 30 deletions(-) create mode 100644 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/include_all_directory.java create mode 100644 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/java_template/CromiteCachedFlag.java.tmpl create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-cromite-flags-support.grdp @@ -602,6 +603,32 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/Settin true /* recursive */); fragmentManager.registerFragmentLifecycleCallbacks( new WideDisplayPaddingApplier(), false /* recursive */); +diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java +--- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java +@@ -17,11 +17,12 @@ import org.chromium.base.version_info.VersionInfo; + import org.chromium.chrome.R; + import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; + import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; ++import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; + import org.chromium.components.browser_ui.settings.EmbeddableSettingsPage; + import org.chromium.components.browser_ui.settings.SettingsUtils; + + /** Settings fragment containing preferences aimed at Chrome and web developers. */ +-public class DeveloperSettings extends PreferenceFragmentCompat implements EmbeddableSettingsPage { ++public class DeveloperSettings extends ChromeBaseSettingsFragment implements EmbeddableSettingsPage { + private static final String UI_PREF_BETA_STABLE_HINT = "beta_stable_hint"; + + // Non-translated strings: +@@ -52,7 +53,7 @@ public class DeveloperSettings extends PreferenceFragmentCompat implements Embed + } + + @Override +- public void onCreatePreferences(Bundle savedInstanceState, String s) { ++ public void onCreatePreferencesCromite(Bundle savedInstanceState, String s) { + SettingsUtils.addPreferencesFromResource(this, R.xml.developer_preferences); + + if (VersionInfo.isBetaBuild() || VersionInfo.isStableBuild()) { diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc diff --git a/build/patches/Android-fonts-fingerprinting-mitigation.patch b/build/patches/Android-fonts-fingerprinting-mitigation.patch new file mode 100644 index 00000000..86be447f --- /dev/null +++ b/build/patches/Android-fonts-fingerprinting-mitigation.patch @@ -0,0 +1,3004 @@ +From: uazo +Date: Sat, 15 Feb 2025 16:25:31 +0000 +Subject: Android fonts fingerprinting mitigation + +Replaces system fonts with a predefined set downloaded from www.cromite.org + +License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html +--- + .../java/res/xml/developer_preferences.xml | 5 + + chrome/browser/BUILD.gn | 11 + + .../fonts_pack_component_installer.cc | 97 + + .../fonts_pack_component_installer.h | 60 + + .../browser/component_updater/registration.cc | 10 + + ...droid-fonts-fingerprinting-mitigation.grdp | 9 + + chrome/renderer/BUILD.gn | 3 + + components/services/font/BUILD.gn | 10 + + components/services/font/font_service_app.cc | 44 + + components/services/font/font_service_app.h | 1 + + .../services/font/public/cpp/font_loader.cc | 11 + + .../services/font/public/cpp/font_loader.h | 1 + + .../font/public/cpp/font_service_thread.cc | 48 + + .../font/public/cpp/font_service_thread.h | 5 + + .../font/public/mojom/font_service.mojom | 2 + + content/browser/BUILD.gn | 11 + + ...der_process_host_impl_receiver_bindings.cc | 12 + + content/child/BUILD.gn | 7 + + content/renderer/BUILD.gn | 4 + + .../renderer/renderer_blink_platform_impl.cc | 55 +- + ...ndroid-fonts-fingerprinting-mitigation.inc | 12 + + ...ndroid-fonts-fingerprinting-mitigation.inc | 7 + + ...ndroid-fonts-fingerprinting-mitigation.inc | 5 + + skia/BUILD.gn | 12 + + .../include/ports/SkFontConfigInterface.h | 2 + + .../skia/include/ports/SkFontMgr_android.h | 42 +- + .../skia/src/ports/SkFontConfigInterface.cpp | 4 + + .../ports/SkFontConfigInterface_direct.cpp | 5 + + .../src/ports/SkFontConfigInterface_direct.h | 1 + + .../skia/src/ports/SkFontMgr_android.cpp | 200 +- + .../skia/src/ports/SkFontMgr_android_data.cpp | 1640 +++++++++++++++++ + .../src/ports/SkFontMgr_android_parser.cpp | 49 +- + .../skia/src/ports/SkFontMgr_android_parser.h | 5 +- + 33 files changed, 2338 insertions(+), 52 deletions(-) + create mode 100644 chrome/browser/component_updater/fonts_pack_component_installer.cc + create mode 100644 chrome/browser/component_updater/fonts_pack_component_installer.h + create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp + create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc + create mode 100644 cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc + create mode 100644 cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc + create mode 100644 third_party/skia/src/ports/SkFontMgr_android_data.cpp + +diff --git a/chrome/android/java/res/xml/developer_preferences.xml b/chrome/android/java/res/xml/developer_preferences.xml +--- a/chrome/android/java/res/xml/developer_preferences.xml ++++ b/chrome/android/java/res/xml/developer_preferences.xml +@@ -23,4 +23,9 @@ found in the LICENSE file. + android:title="Hint: You can also enable Developer options on Beta/Stable channels by tapping the Chrome version in "Settings > About Chrome" multiple times." + app:allowDividerAbove="false" + app:allowDividerBelow="false" /> ++ + +diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -7864,6 +7864,17 @@ static_library("browser") { + } + } + ++ if (is_android) { ++ sources += [ ++ "component_updater/fonts_pack_component_installer.cc", ++ "component_updater/fonts_pack_component_installer.h", ++ ] ++ deps += [ ++ "//components/services/font:lib", ++ "//components/services/font/public/mojom", ++ ] ++ } ++ + if (enable_chrome_notifications) { + assert(enable_message_center) + sources += [ +diff --git a/chrome/browser/component_updater/fonts_pack_component_installer.cc b/chrome/browser/component_updater/fonts_pack_component_installer.cc +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/component_updater/fonts_pack_component_installer.cc +@@ -0,0 +1,97 @@ ++#include "chrome/browser/component_updater/fonts_pack_component_installer.h" ++ ++#include ++#include ++ ++#include "base/logging.h" ++#include "base/files/file_path.h" ++#include "base/files/file_util.h" ++#include "base/functional/callback.h" ++#include "base/memory/ref_counted.h" ++#include "base/path_service.h" ++#include "base/values.h" ++#include "base/version.h" ++#include "chrome/browser/browser_process.h" ++#include "components/component_updater/component_updater_paths.h" ++ ++using component_updater::ComponentUpdateService; ++ ++namespace component_updater { ++ ++// The extension id is: gcmjkmgdlgnkkcocmoeiminaijmmjnii ++const uint8_t kFontsPackPublicKeySHA256[32] = { ++ 0x62, 0xc9, 0xac, 0x63, 0xb6, 0xda, 0xa2, 0xe2, 0xce, 0x48, 0xc8, ++ 0xd0, 0x89, 0xcc, 0x9d, 0x88, 0x02, 0x7c, 0x3e, 0x71, 0xcf, 0x5d, ++ 0x6b, 0xb5, 0xdf, 0x21, 0x65, 0x82, 0x08, 0x97, 0x6a, 0x26}; ++ ++const char kFontsPackSetFetcherManifestName[] = ++ "System Fonts Pack"; ++ ++FontsPackComponentInstallerPolicy:: ++ FontsPackComponentInstallerPolicy() = default; ++ ++FontsPackComponentInstallerPolicy:: ++ ~FontsPackComponentInstallerPolicy() = default; ++ ++bool FontsPackComponentInstallerPolicy:: ++ SupportsGroupPolicyEnabledComponentUpdates() const { ++ return false; ++} ++ ++bool FontsPackComponentInstallerPolicy::RequiresNetworkEncryption() ++ const { ++ return true; ++} ++ ++update_client::CrxInstaller::Result ++FontsPackComponentInstallerPolicy::OnCustomInstall( ++ const base::Value::Dict& manifest, ++ const base::FilePath& install_dir) { ++ return update_client::CrxInstaller::Result(0); // Nothing custom here. ++} ++ ++void FontsPackComponentInstallerPolicy::OnCustomUninstall() {} ++ ++void FontsPackComponentInstallerPolicy::ComponentReady( ++ const base::Version& version, ++ const base::FilePath& install_dir, ++ base::Value::Dict manifest) { ++ DCHECK(!install_dir.empty()); ++ LOG(INFO) << "Fonts Pack Version Ready: " << install_dir.value(); ++} ++ ++// Called during startup and installation before ComponentReady(). ++bool FontsPackComponentInstallerPolicy::VerifyInstallation( ++ const base::Value::Dict& manifest, ++ const base::FilePath& install_dir) const { ++ return base::PathExists(install_dir); ++} ++ ++base::FilePath ++FontsPackComponentInstallerPolicy::GetRelativeInstallDir() const { ++ return base::FilePath("fonts"); ++} ++ ++void FontsPackComponentInstallerPolicy::GetHash( ++ std::vector* hash) const { ++ hash->assign(std::begin(kFontsPackPublicKeySHA256), ++ std::end(kFontsPackPublicKeySHA256)); ++} ++ ++std::string FontsPackComponentInstallerPolicy::GetName() const { ++ return kFontsPackSetFetcherManifestName; ++} ++ ++update_client::InstallerAttributes ++FontsPackComponentInstallerPolicy::GetInstallerAttributes() const { ++ update_client::InstallerAttributes attributes; ++ return attributes; ++} ++ ++void RegisterFontsPackComponent(ComponentUpdateService* cus) { ++ auto installer = base::MakeRefCounted( ++ std::make_unique()); ++ installer->Register(cus, base::OnceClosure(), /*allowed*/true); ++} ++ ++} // namespace component_updater +diff --git a/chrome/browser/component_updater/fonts_pack_component_installer.h b/chrome/browser/component_updater/fonts_pack_component_installer.h +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/component_updater/fonts_pack_component_installer.h +@@ -0,0 +1,60 @@ ++#ifndef CHROME_BROWSER_COMPONENT_UPDATER_FONTS_PACK_COMPONENT_INSTALLER_H_ ++#define CHROME_BROWSER_COMPONENT_UPDATER_FONTS_PACK_COMPONENT_INSTALLER_H_ ++ ++#include ++#include ++#include ++ ++#include "base/values.h" ++#include "components/component_updater/component_installer.h" ++ ++namespace base { ++class FilePath; ++} // namespace base ++ ++namespace component_updater { ++ ++class ComponentUpdateService; ++ ++// Component for receiving System fonts overrides. ++class FontsPackComponentInstallerPolicy ++ : public ComponentInstallerPolicy { ++ public: ++ static const char kManifestRulesetFormatKey[]; ++ static const int kCurrentRulesetFormat; ++ ++ FontsPackComponentInstallerPolicy(); ++ ++ FontsPackComponentInstallerPolicy( ++ const FontsPackComponentInstallerPolicy&) = delete; ++ FontsPackComponentInstallerPolicy& operator=( ++ const FontsPackComponentInstallerPolicy&) = delete; ++ ++ ~FontsPackComponentInstallerPolicy() override; ++ ++ private: ++ static std::string GetInstallerTag(); ++ ++ // ComponentInstallerPolicy implementation. ++ bool SupportsGroupPolicyEnabledComponentUpdates() const override; ++ bool RequiresNetworkEncryption() const override; ++ update_client::CrxInstaller::Result OnCustomInstall( ++ const base::Value::Dict& manifest, ++ const base::FilePath& install_dir) override; ++ void OnCustomUninstall() override; ++ bool VerifyInstallation(const base::Value::Dict& manifest, ++ const base::FilePath& install_dir) const override; ++ void ComponentReady(const base::Version& version, ++ const base::FilePath& install_dir, ++ base::Value::Dict manifest) override; ++ base::FilePath GetRelativeInstallDir() const override; ++ void GetHash(std::vector* hash) const override; ++ std::string GetName() const override; ++ update_client::InstallerAttributes GetInstallerAttributes() const override; ++}; ++ ++void RegisterFontsPackComponent(ComponentUpdateService* cus); ++ ++} // namespace component_updater ++ ++#endif // CHROME_BROWSER_COMPONENT_UPDATER_FONTS_PACK_COMPONENT_INSTALLER_H_ +diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc +--- a/chrome/browser/component_updater/registration.cc ++++ b/chrome/browser/component_updater/registration.cc +@@ -55,6 +55,7 @@ + #include "device/vr/buildflags/buildflags.h" + #include "ppapi/buildflags/buildflags.h" + #include "third_party/widevine/cdm/buildflags.h" ++#include "third_party/blink/public/common/features.h" + + #if BUILDFLAG(IS_WIN) + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) +@@ -110,10 +111,19 @@ + #include "ui/aura/env.h" + #endif + ++#if BUILDFLAG(IS_ANDROID) ++#include "chrome/browser/component_updater/fonts_pack_component_installer.h" ++#endif ++ + namespace component_updater { + + void RegisterComponentsForUpdate() { + auto* const cus = g_browser_process->component_updater(); ++#if BUILDFLAG(IS_ANDROID) ++ if (base::FeatureList::IsEnabled(blink::features::kAndroidFontsFingerprintingMitigation)) { ++ RegisterFontsPackComponent(cus); ++ } ++#endif + + if ((true)) return; + +diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp +new file mode 100644 +--- /dev/null ++++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp +@@ -0,0 +1,9 @@ ++ ++ ++ ++ Android fonts fingerprinting mitigation ++ ++ ++ Replaces all system fonts with the same for all devices ++ ++ +diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn +--- a/chrome/renderer/BUILD.gn ++++ b/chrome/renderer/BUILD.gn +@@ -295,6 +295,9 @@ static_library("renderer") { + "//ppapi/shared_impl", + ] + ++ if (is_android) { ++ deps += [ "//components/services/font/public/cpp" ] ++ } + if (is_linux || is_chromeos) { + deps += [ "//components/services/font/public/cpp" ] + } +diff --git a/components/services/font/BUILD.gn b/components/services/font/BUILD.gn +--- a/components/services/font/BUILD.gn ++++ b/components/services/font/BUILD.gn +@@ -24,6 +24,16 @@ source_set("lib") { + "//ui/gfx", + ] + ++ if (is_android) { ++ sources -= [ ++ "fontconfig_matching.cc", ++ "fontconfig_matching.h", ++ ] ++ deps -= [ ++ "//third_party/fontconfig", ++ ] ++ } ++ + public_deps = [ "//skia" ] + + if (enable_pdf && (is_linux || is_chromeos)) { +diff --git a/components/services/font/font_service_app.cc b/components/services/font/font_service_app.cc +--- a/components/services/font/font_service_app.cc ++++ b/components/services/font/font_service_app.cc +@@ -20,6 +20,12 @@ + #include "ui/gfx/font_fallback_linux.h" + #include "ui/gfx/font_render_params.h" + ++#if BUILDFLAG(IS_ANDROID) ++#include "base/path_service.h" ++#include "base/files/file_util.h" ++#include "components/component_updater/component_updater_paths.h" ++#endif ++ + #if BUILDFLAG(ENABLE_PDF) + #include "components/services/font/pdf_fontconfig_matching.h" // nogncheck + #endif +@@ -95,6 +101,7 @@ void FontServiceApp::BindReceiver( + void FontServiceApp::MatchFamilyName(const std::string& family_name, + mojom::TypefaceStylePtr requested_style, + MatchFamilyNameCallback callback) { ++#if !BUILDFLAG(IS_ANDROID) + TRACE_EVENT0("fonts", "FontServiceApp::MatchFamilyName"); + + SkFontConfigInterface::FontIdentity result_identity; +@@ -155,6 +162,7 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name, + + std::move(callback).Run(std::move(identity), result_family_cppstring, + std::move(style)); ++#endif + } + + void FontServiceApp::OpenStream(uint32_t id_number, +@@ -169,12 +177,43 @@ void FontServiceApp::OpenStream(uint32_t id_number, + std::move(callback).Run(std::move(file)); + } + ++void FontServiceApp::OpenStreamFromName(const std::string& name, ++ OpenStreamCallback callback) { ++#if BUILDFLAG(IS_ANDROID) ++ TRACE_EVENT0("fonts", "FontServiceApp::OpenStreamFromName"); ++ ++ base::File empty_file; ++ ++ base::FilePath local_install_path; ++ if (!base::PathService::Get(component_updater::DIR_COMPONENT_USER, &local_install_path)) { ++ std::move(callback).Run(std::move(empty_file)); ++ return; ++ } ++ local_install_path = local_install_path ++ .Append("fonts") ++ .Append("1.0.0") ++ .AppendASCII(name); ++ ++ if (!base::PathExists(local_install_path)) { ++ LOG(ERROR) << "System font " << local_install_path << " not found"; ++ std::move(callback).Run(std::move(empty_file)); ++ return; ++ } ++ ++ base::File font_file(local_install_path, base::File::FLAG_OPEN | base::File::FLAG_READ); ++ std::move(callback).Run(std::move(font_file)); ++#endif ++} ++ + void FontServiceApp::FallbackFontForCharacter( + uint32_t character, + const std::string& locale, + FallbackFontForCharacterCallback callback) { + TRACE_EVENT0("fonts", "FontServiceApp::FallbackFontForCharacter"); + ++#if BUILDFLAG(IS_ANDROID) ++ std::move(callback).Run(nullptr, "", false, false); ++#else + gfx::FallbackFontData fallback_font; + if (gfx::GetFallbackFontForChar(character, locale, &fallback_font)) { + size_t index = FindOrAddPath(fallback_font.filepath); +@@ -189,6 +228,7 @@ void FontServiceApp::FallbackFontForCharacter( + } else { + std::move(callback).Run(nullptr, "", false, false); + } ++#endif + } + + void FontServiceApp::FontRenderStyleForStrike( +@@ -232,6 +272,9 @@ void FontServiceApp::MatchFontByPostscriptNameOrFullFontName( + TRACE_EVENT0("fonts", + "FontServiceApp::MatchFontByPostscriptNameOrFullFontName"); + ++#if BUILDFLAG(IS_ANDROID) ++ std::move(callback).Run(nullptr); ++#else + std::optional match_result = + FontConfigLocalMatching::FindFontByPostscriptNameOrFullFontName(family); + if (match_result) { +@@ -243,6 +286,7 @@ void FontServiceApp::MatchFontByPostscriptNameOrFullFontName( + return; + } + std::move(callback).Run(nullptr); ++#endif + } + + #if BUILDFLAG(ENABLE_PDF) +diff --git a/components/services/font/font_service_app.h b/components/services/font/font_service_app.h +--- a/components/services/font/font_service_app.h ++++ b/components/services/font/font_service_app.h +@@ -36,6 +36,7 @@ class FontServiceApp : public mojom::FontService { + mojom::TypefaceStylePtr requested_style, + MatchFamilyNameCallback callback) override; + void OpenStream(uint32_t id_number, OpenStreamCallback callback) override; ++ void OpenStreamFromName(const std::string& name, OpenStreamCallback callback) override; + void FallbackFontForCharacter( + uint32_t character, + const std::string& locale, +diff --git a/components/services/font/public/cpp/font_loader.cc b/components/services/font/public/cpp/font_loader.cc +--- a/components/services/font/public/cpp/font_loader.cc ++++ b/components/services/font/public/cpp/font_loader.cc +@@ -63,6 +63,17 @@ SkStreamAsset* FontLoader::openStream(const FontIdentity& identity) { + } + } + ++SkStreamAsset* FontLoader::openStreamFromName(const char* filename) { ++ scoped_refptr mapped_font_file = ++ thread_->OpenStreamFromFile(filename); ++ if (!mapped_font_file) ++ return nullptr; ++ ++ // Get notified with |mapped_font_file| is destroyed. ++ mapped_font_file->set_observer(this); ++ return mapped_font_file->CreateMemoryStream(); ++} ++ + sk_sp FontLoader::makeTypeface(const FontIdentity& identity, + sk_sp mgr) { + TRACE_EVENT0("fonts", "FontServiceThread::makeTypeface"); +diff --git a/components/services/font/public/cpp/font_loader.h b/components/services/font/public/cpp/font_loader.h +--- a/components/services/font/public/cpp/font_loader.h ++++ b/components/services/font/public/cpp/font_loader.h +@@ -47,6 +47,7 @@ class FontLoader : public SkFontConfigInterface, + SkString* out_family_name, + SkFontStyle* out_style) override; + SkStreamAsset* openStream(const FontIdentity& identity) override; ++ SkStreamAsset* openStreamFromName(const char* filename) override; + sk_sp makeTypeface(const FontIdentity& identity, + sk_sp mgr) override; + +diff --git a/components/services/font/public/cpp/font_service_thread.cc b/components/services/font/public/cpp/font_service_thread.cc +--- a/components/services/font/public/cpp/font_service_thread.cc ++++ b/components/services/font/public/cpp/font_service_thread.cc +@@ -247,6 +247,54 @@ void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event, + done_event, output_file)); + } + ++scoped_refptr FontServiceThread::OpenStreamFromFile( ++ const std::string& filename) { ++ DCHECK(!task_runner_->RunsTasksInCurrentSequence()); ++ ++ base::ElapsedTimer timer; ++ ++ base::File stream_file; ++ // This proxies to the other thread, which proxies to mojo. Only on the ++ // reply from mojo do we return from this. ++ base::WaitableEvent done_event; ++ task_runner_->PostTask( ++ FROM_HERE, base::BindOnce(&FontServiceThread::OpenStreamFromFileImpl, this, ++ &done_event, &stream_file, filename)); ++ done_event.Wait(); ++ ++ base::UmaHistogramMicrosecondsTimes( ++ "Blink.Fonts.FontServiceThread.OpenStreamTime", timer.Elapsed()); ++ ++ if (!stream_file.IsValid()) { ++ // The font-service may have been killed. ++ return nullptr; ++ } ++ ++ // Converts the file to out internal type. ++ scoped_refptr mapped_font_file = ++ new MappedFontFile(0); ++ if (!mapped_font_file->Initialize(std::move(stream_file))) ++ return nullptr; ++ ++ return mapped_font_file; ++} ++ ++void FontServiceThread::OpenStreamFromFileImpl(base::WaitableEvent* done_event, ++ base::File* output_file, ++ const std::string& file) { ++ DCHECK(task_runner_->RunsTasksInCurrentSequence()); ++ ++ if (!font_service_.is_connected()) { ++ done_event->Signal(); ++ return; ++ } ++ ++ pending_waitable_events_.insert(done_event); ++ font_service_->OpenStreamFromName( ++ file, base::BindOnce(&FontServiceThread::OnOpenStreamComplete, this, ++ done_event, output_file)); ++} ++ + void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event, + base::File* output_file, + base::File file) { +diff --git a/components/services/font/public/cpp/font_service_thread.h b/components/services/font/public/cpp/font_service_thread.h +--- a/components/services/font/public/cpp/font_service_thread.h ++++ b/components/services/font/public/cpp/font_service_thread.h +@@ -55,6 +55,8 @@ class FontServiceThread : public base::RefCountedThreadSafe { + SkFontStyle* out_style); + scoped_refptr OpenStream( + const SkFontConfigInterface::FontIdentity& identity); ++ scoped_refptr OpenStreamFromFile( ++ const std::string& filename); + + bool FallbackFontForCharacter( + uint32_t character, +@@ -118,6 +120,9 @@ class FontServiceThread : public base::RefCountedThreadSafe { + void OpenStreamImpl(base::WaitableEvent* done_event, + base::File* output_file, + const uint32_t id_number); ++ void OpenStreamFromFileImpl(base::WaitableEvent* done_event, ++ base::File* output_file, ++ const std::string& filename); + void OnOpenStreamComplete(base::WaitableEvent* done_event, + base::File* output_file, + base::File file); +diff --git a/components/services/font/public/mojom/font_service.mojom b/components/services/font/public/mojom/font_service.mojom +--- a/components/services/font/public/mojom/font_service.mojom ++++ b/components/services/font/public/mojom/font_service.mojom +@@ -66,6 +66,8 @@ interface FontService { + // Returns a handle to the raw font specified by |id_number|. + OpenStream(uint32 id_number) => (mojo_base.mojom.ReadOnlyFile? font_handle); + ++ OpenStreamFromName(string family_name) => (mojo_base.mojom.ReadOnlyFile? font_handle); ++ + // Returns a fallback FontIdentity and Typeface style for the given character + // and locale. If no fallback font can be found, returns a null identity. + FallbackFontForCharacter(uint32 character, string locale) +diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn +--- a/content/browser/BUILD.gn ++++ b/content/browser/BUILD.gn +@@ -2505,6 +2505,17 @@ source_set("browser") { + ] + } + ++ if (is_android) { ++ sources += [ ++ "font_service.cc", ++ "font_service.h", ++ ] ++ ++ deps += [ "//pdf:buildflags" ] ++ ++ public_deps += [ "//components/services/font/public/mojom" ] ++ } ++ + if (is_linux || is_chromeos) { + sources -= + [ "file_system_access/file_path_watcher/file_path_watcher_stub.cc" ] +diff --git a/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc b/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc +--- a/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc ++++ b/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc +@@ -52,6 +52,11 @@ + #include "third_party/blink/public/mojom/webdatabase/web_database.mojom.h" + #endif + ++#if BUILDFLAG(IS_ANDROID) ++#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck ++#include "content/browser/font_service.h" // nogncheck ++#endif ++ + #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + #include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck + #include "content/browser/font_service.h" // nogncheck +@@ -341,6 +346,13 @@ void RenderProcessHostImpl::IOThreadHostImpl::BindHostReceiver( + } + #endif + ++#if BUILDFLAG(IS_ANDROID) ++ if (auto font_receiver = receiver.As()) { ++ ConnectToFontService(std::move(font_receiver)); ++ return; ++ } ++#endif ++ + #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + if (auto font_receiver = receiver.As()) { + ConnectToFontService(std::move(font_receiver)); +diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn +--- a/content/child/BUILD.gn ++++ b/content/child/BUILD.gn +@@ -135,6 +135,13 @@ target(link_target_type, "child") { + ] + } + ++ if (is_android) { ++ deps += [ ++ "//components/services/font/public/cpp", ++ "//components/services/font/public/mojom", ++ ] ++ } ++ + if (is_win) { + sources += [ + "dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc", +diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn +--- a/content/renderer/BUILD.gn ++++ b/content/renderer/BUILD.gn +@@ -353,6 +353,10 @@ target(link_target_type, "renderer") { + deps += [ "//services/screen_ai/public/mojom" ] + } + ++ if (is_android) { ++ deps += [ "//components/services/font/public/cpp" ] ++ } ++ + if (is_linux || is_chromeos) { + deps += [ "//components/services/font/public/cpp" ] + } +diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc +--- a/content/renderer/renderer_blink_platform_impl.cc ++++ b/content/renderer/renderer_blink_platform_impl.cc +@@ -142,6 +142,23 @@ + #include "content/common/android/sync_compositor_statics.h" + #endif + ++#if BUILDFLAG(IS_ANDROID) ++#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck ++#include "components/services/font/public/cpp/font_loader.h" ++#include "content/browser/font_service.h" // nogncheck ++ ++#include "base/path_service.h" ++#include "base/base_paths_android.h" ++#include "base/file_descriptor_store.h" ++#include "base/strings/string_number_conversions.h" ++#include "base/files/file_path.h" ++#include "content/public/common/content_descriptor_keys.h" ++#include "skia/ext/font_utils.h" ++#include "third_party/skia/include/core/SkFontMgr.h" ++#include "third_party/skia/include/ports/SkFontMgr_android.h" ++#include "third_party/blink/public/platform/web_font_render_style.h" ++#endif ++ + using blink::Platform; + using blink::WebAudioDevice; + using blink::WebAudioLatencyHint; +@@ -185,6 +202,37 @@ gpu::ContextType ToGpuContextType(blink::Platform::ContextType type) { + NOTREACHED(); + } + ++#if BUILDFLAG(IS_ANDROID) ++void InitializeCustomFonts() { ++ if (!base::FeatureList::IsEnabled(blink::features::kAndroidFontsFingerprintingMitigation)) { ++ return; ++ } ++ std::string font_config = "cromite_fonts.xml"; ++ sk_sp fci(SkFontConfigInterface::RefGlobal()); ++ SkStreamAsset* asset = fci->openStreamFromName(font_config.c_str()); ++ if (!asset) { ++ LOG(ERROR) << "Unable to activate custom fonts."; ++ return; ++ } ++ ++ std::string android_fonts_dir = "use_fd"; ++ ++ auto custom = std::make_unique(); ++ custom->fSystemFontUse = ++ SkFontMgr_Android_CustomFonts::SystemFontUse::kOnlyCustom; ++ custom->fBasePath = android_fonts_dir.c_str(); ++ custom->fFontsXml = font_config.c_str(); ++ custom->fFallbackFontsXml = font_config.c_str(); ++ // If set to true the SkFontMgr will acquire all requisite ++ // system IO resources on initialization. ++ custom->fIsolated = false; ++ ++ sk_sp skia_font_manager = ++ SkFontMgr_New_Android(std::move(custom)); ++ skia::OverrideDefaultSkFontMgr(std::move(skia_font_manager)); ++} ++#endif ++ + } // namespace + + //------------------------------------------------------------------------------ +@@ -198,18 +246,21 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl( + is_locked_to_site_(false), + main_thread_scheduler_(main_thread_scheduler), + next_frame_sink_id_(uint32_t{std::numeric_limits::max()} + 1) { +-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ++#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) + sk_sp font_loader; + #endif + + // RenderThread may not exist in some tests. + if (RenderThreadImpl::current()) { +-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ++#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) + mojo::PendingRemote font_service; + RenderThreadImpl::current()->BindHostReceiver( + font_service.InitWithNewPipeAndPassReceiver()); + font_loader = sk_make_sp(std::move(font_service)); + SkFontConfigInterface::SetGlobal(font_loader); ++#if BUILDFLAG(IS_ANDROID) ++ InitializeCustomFonts(); ++#endif + #endif + + #if BUILDFLAG(IS_WIN) +diff --git a/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc +new file mode 100644 +--- /dev/null ++++ b/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc +@@ -0,0 +1,12 @@ ++#if BUILDFLAG(IS_ANDROID) ++ ++#ifdef FLAG_SECTION ++ ++ {"android-fonts-fingerprinting-mitigation", ++ "Android fonts fingerprinting mitigation", ++ "Replaces all system fonts with the same for all devices.", kOsAndroid, ++ FEATURE_VALUE_TYPE(blink::features::kAndroidFontsFingerprintingMitigation)}, ++ ++#endif ++ ++#endif +diff --git a/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc +new file mode 100644 +--- /dev/null ++++ b/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc +@@ -0,0 +1,7 @@ ++#if BUILDFLAG(IS_ANDROID) ++ ++CROMITE_FEATURE(kAndroidFontsFingerprintingMitigation, ++ "AndroidFontsFingerprintingMitigation", ++ base::FEATURE_ENABLED_BY_DEFAULT); ++ ++#endif +diff --git a/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc +new file mode 100644 +--- /dev/null ++++ b/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc +@@ -0,0 +1,5 @@ ++#if BUILDFLAG(IS_ANDROID) ++ ++BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kAndroidFontsFingerprintingMitigation); ++ ++#endif +diff --git a/skia/BUILD.gn b/skia/BUILD.gn +--- a/skia/BUILD.gn ++++ b/skia/BUILD.gn +@@ -455,6 +455,18 @@ component("skia") { + sources += skia_ports_fci_sources + } + ++ if (is_android) { ++ sources += [ ++ "//third_party/skia/src/ports/SkFontConfigInterface.cpp", ++ "//third_party/skia/src/ports/SkFontMgr_FontConfigInterface.cpp", ++ ] ++ public += [ ++ "include/ports/SkFontConfigInterface.h", ++ "include/ports/SkFontMgr_FontConfigInterface.h", ++ ] ++ defines += [ "CROMITE_IS_ANDROID" ] ++ } ++ + if (is_linux || is_chromeos || is_android) { + # Retain the files for the SkFontMgr_Android on linux to emulate android + # fonts. See content/zygote/zygote_main_linux.cc +diff --git a/third_party/skia/include/ports/SkFontConfigInterface.h b/third_party/skia/include/ports/SkFontConfigInterface.h +--- a/third_party/skia/include/ports/SkFontConfigInterface.h ++++ b/third_party/skia/include/ports/SkFontConfigInterface.h +@@ -91,6 +91,8 @@ public: + */ + virtual SkStreamAsset* openStream(const FontIdentity&) = 0; + ++ virtual SkStreamAsset* openStreamFromName(const char* filename) = 0; ++ + /** + * Return an SkTypeface for the given FontIdentity. + * +diff --git a/third_party/skia/include/ports/SkFontMgr_android.h b/third_party/skia/include/ports/SkFontMgr_android.h +--- a/third_party/skia/include/ports/SkFontMgr_android.h ++++ b/third_party/skia/include/ports/SkFontMgr_android.h +@@ -9,6 +9,11 @@ + #define SkFontMgr_android_DEFINED + + #include "include/core/SkRefCnt.h" ++#include "include/core/SkStream.h" ++#include "src/core/SkTHash.h" ++ ++#include "include/ports/SkFontConfigInterface.h" ++#include "include/ports/SkFontMgr_FontConfigInterface.h" + + #include + +@@ -40,13 +45,46 @@ struct SkFontMgr_Android_CustomFonts { + * system IO resources on initialization. + */ + bool fIsolated; ++ ++ struct SkFontMgr_Android_CustomFonts_MappedData { ++ int fd; ++ int64_t offset; ++ size_t size; ++ }; ++ skia_private::THashMap platform_file_map; ++ ++ void add_platform_file(std::string key, int fd, int64_t offset, size_t size) { ++ SkFontMgr_Android_CustomFonts_MappedData data = {fd, offset, size}; ++ platform_file_map.set(key, std::move(data)); ++ } ++ ++ std::unique_ptr getPlatformFile(const char* filename) const { ++ // SkDebugf("-- open platform file '%s'\n", filename); ++ sk_sp fci(SkFontConfigInterface::RefGlobal()); ++ SkStreamAsset* asset = fci->openStreamFromName(filename); ++ if (asset) { ++ return std::unique_ptr(asset); ++ } ++ ++ const auto* it = platform_file_map.find(filename); ++ if (!it) { ++ return nullptr; ++ } ++ auto whole_data = SkData::MakeFromFD(it->fd); ++ auto data = SkData::MakeSubset(whole_data.get(), it->offset, it->size); ++ if (!data) { ++ return nullptr; ++ } ++ return std::unique_ptr(new SkMemoryStream(std::move(data))); ++ } + }; + + /** Create a font manager for Android. If 'custom' is NULL, use only system fonts. */ + + // Deprecated +-SK_API sk_sp SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom); ++SK_API sk_sp SkFontMgr_New_Android(std::unique_ptr custom); + +-SK_API sk_sp SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom, ++SK_API sk_sp SkFontMgr_New_Android(std::unique_ptr custom, + std::unique_ptr scanner); + #endif // SkFontMgr_android_DEFINED +diff --git a/third_party/skia/src/ports/SkFontConfigInterface.cpp b/third_party/skia/src/ports/SkFontConfigInterface.cpp +--- a/third_party/skia/src/ports/SkFontConfigInterface.cpp ++++ b/third_party/skia/src/ports/SkFontConfigInterface.cpp +@@ -22,7 +22,11 @@ sk_sp SkFontConfigInterface::RefGlobal() { + if (gFontConfigInterface) { + return sk_ref_sp(gFontConfigInterface); + } ++#if defined(CROMITE_IS_ANDROID) ++ return nullptr; ++#else + return sk_ref_sp(SkFontConfigInterface::GetSingletonDirectInterface()); ++#endif + } + + void SkFontConfigInterface::SetGlobal(sk_sp fc) { +diff --git a/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp b/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp +--- a/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp ++++ b/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp +@@ -707,3 +707,8 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], + SkStreamAsset* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) { + return SkStream::MakeFromFile(identity.fString.c_str()).release(); + } ++ ++SkStreamAsset* SkFontConfigInterfaceDirect::openStreamFromName(const char* filename) { ++ SkASSERT(false); ++ return nullptr; ++} +diff --git a/third_party/skia/src/ports/SkFontConfigInterface_direct.h b/third_party/skia/src/ports/SkFontConfigInterface_direct.h +--- a/third_party/skia/src/ports/SkFontConfigInterface_direct.h ++++ b/third_party/skia/src/ports/SkFontConfigInterface_direct.h +@@ -29,6 +29,7 @@ public: + SkFontStyle* outStyle) override; + + SkStreamAsset* openStream(const FontIdentity&) override; ++ SkStreamAsset* openStreamFromName(const char* filename) override; + + protected: + virtual bool isAccessible(const char* filename); +diff --git a/third_party/skia/src/ports/SkFontMgr_android.cpp b/third_party/skia/src/ports/SkFontMgr_android.cpp +--- a/third_party/skia/src/ports/SkFontMgr_android.cpp ++++ b/third_party/skia/src/ports/SkFontMgr_android.cpp +@@ -26,6 +26,7 @@ + #include "src/core/SkTypefaceCache.h" + #include "src/ports/SkFontMgr_android_parser.h" + #include "src/ports/SkTypeface_proxy.h" ++#include "src/ports/SkFontScanner_FreeType_priv.h" + + #include + #include +@@ -35,6 +36,91 @@ using namespace skia_private; + class SkData; + + namespace { ++ ++#include "SkFontMgr_android_data.cpp" ++ ++class SkTypeface_AndroidSystemCustom : public SkTypeface_FreeType { ++public: ++ SkTypeface_AndroidSystemCustom(const SkString& pathName, ++ int index, ++ const SkFixed* axes, int axesCount, ++ const SkFontStyle& style, ++ bool isFixedPitch, ++ const SkString& familyName, ++ const TArray& lang, ++ FontVariant variantStyle, ++ const SkFontMgr_Android_CustomFonts* custom) ++ : INHERITED(style, isFixedPitch) ++ , fPathName(pathName) ++ , fFamilyName(familyName) ++ , fIndex(index) ++ , fAxes(axes, axesCount) ++ , fLang(lang) ++ , fVariantStyle(variantStyle) ++ , fFile(nullptr) ++ , custom_(custom) {} ++ ++ std::unique_ptr makeStream() const { ++ if (custom_) { ++ return custom_->getPlatformFile(fPathName.c_str()); ++ } ++ if (fFile) { ++ sk_sp data(SkData::MakeFromFILE(fFile)); ++ return data ? std::make_unique(std::move(data)) : nullptr; ++ } ++ return SkStream::MakeFromFile(fPathName.c_str()); ++ } ++ ++ void onGetFamilyName(SkString* familyName) const override { ++ *familyName = fFamilyName; ++ } ++ ++ void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override { ++ SkASSERT(desc); ++ SkASSERT(serialize); ++ desc->setFamilyName(fFamilyName.c_str()); ++ desc->setStyle(this->fontStyle()); ++ desc->setFactoryId(SkTypeface_FreeType::FactoryId); ++ *serialize = false; ++ } ++ std::unique_ptr onOpenStream(int* ttcIndex) const override { ++ *ttcIndex = fIndex; ++ return this->makeStream(); ++ } ++ std::unique_ptr onMakeFontData() const override { ++ return std::make_unique( ++ this->makeStream(), fIndex, 0, fAxes.begin(), fAxes.size(), nullptr, 0); ++ } ++ sk_sp onMakeClone(const SkFontArguments& args) const override { ++ SkFontStyle style = this->fontStyle(); ++ std::unique_ptr data = this->cloneFontData(args, &style); ++ if (!data) { ++ return nullptr; ++ } ++ return sk_make_sp( ++ fPathName, ++ fIndex, ++ data->getAxis(), ++ data->getAxisCount(), ++ style, ++ this->isFixedPitch(), ++ fFamilyName, ++ fLang, ++ fVariantStyle, custom_); ++ } ++ ++ const SkString fPathName; ++ const SkString fFamilyName; ++ int fIndex; ++ const STArray<4, SkFixed, true> fAxes; ++ const STArray<4, SkLanguage, true> fLang; ++ const FontVariant fVariantStyle; ++ SkAutoTCallVProc fFile; ++ const SkFontMgr_Android_CustomFonts* custom_; ++ ++ using INHERITED = SkTypeface_FreeType; ++}; ++ + class SkTypeface_AndroidSystem : public SkTypeface_proxy { + public: + SkTypeface_AndroidSystem(sk_sp proxy, +@@ -144,7 +230,7 @@ template sk_sp sk_sp_static_cast(sk_sp&& s) { + class SkFontStyleSet_Android : public SkFontStyleSet { + public: + explicit SkFontStyleSet_Android(const FontFamily& family, const SkFontScanner* scanner, +- const bool cacheFontFiles) { ++ const bool cacheFontFiles, const SkFontMgr_Android_CustomFonts* custom) { + const SkString* cannonicalFamilyName = nullptr; + if (!family.fNames.empty()) { + cannonicalFamilyName = &family.fNames[0]; +@@ -153,30 +239,52 @@ public: + + // TODO? make this lazy + for (int i = 0; i < family.fFonts.size(); ++i) { ++ bool use_custom = false; + const FontFileInfo& fontFile = family.fFonts[i]; + + SkString pathName(family.fBasePath); + pathName.append(fontFile.fFileName); + +- std::unique_ptr stream = SkStream::MakeFromFile(pathName.c_str()); +- if (!stream) { +- SkDEBUGF("Requested font file %s does not exist or cannot be opened.\n", +- pathName.c_str()); +- continue; ++ const int ttcIndex = fontFile.fIndex; ++ SkString familyName; ++ SkFontStyle style; ++ bool isFixedWidth; ++ SkFontScanner::AxisDefinitions axisDefinitions; ++ SkFontScanner::VariationPosition current; ++ SkFontArguments::VariationPosition position; ++ ++ std::unique_ptr stream; ++ if (!custom && !fontFile.fFileName.startsWith('#')) { ++ stream = SkStream::MakeFromFile(pathName.c_str()); ++ if (!stream) { ++ SkDEBUGF("Requested font file %s does not exist or cannot be opened.\n", ++ pathName.c_str()); ++ continue; ++ } ++ } else if (custom) { ++ use_custom = true; ++ if (!GetFontData(fontFile.fFileName, ++ &familyName, &style, &isFixedWidth, &axisDefinitions)) { ++ stream = custom->getPlatformFile(pathName.c_str()); ++ } ++ pathName = fontFile.fFileName; + } + +- SkFontArguments::VariationPosition position = { ++ sk_sp proxy; ++ if (!use_custom || stream) { ++ position = { + fontFile.fVariationDesignPosition.begin(), + fontFile.fVariationDesignPosition.size() +- }; +- auto proxy = scanner->MakeFromStream( +- std::move(stream), +- SkFontArguments().setCollectionIndex(fontFile.fIndex) +- .setVariationDesignPosition(position)); +- if (!proxy) { +- SkDEBUGF("Requested font file %s does not have valid font data.\n", +- pathName.c_str()); +- continue; ++ }; ++ proxy = scanner->MakeFromStream( ++ std::move(stream), ++ SkFontArguments().setCollectionIndex(fontFile.fIndex) ++ .setVariationDesignPosition(position)); ++ if (!proxy) { ++ SkDEBUGF("Requested font file %s does not have valid font data.\n", ++ pathName.c_str()); ++ continue; ++ } + } + + uint32_t variant = family.fVariant; +@@ -187,13 +295,25 @@ public: + // The first specified family name overrides the family name found in the font. + // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return + // all of the specified family names in addition to the names found in the font. +- SkString familyName; +- proxy->getFamilyName(&familyName); +- if (cannonicalFamilyName != nullptr) { +- familyName = *cannonicalFamilyName; +- } ++ SkFontStyle fontStyle; ++ AutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.size()); + +- SkFontStyle fontStyle = proxy->fontStyle(); ++ if (!use_custom || stream) { ++ proxy->getFamilyName(&familyName); ++ if (cannonicalFamilyName != nullptr) { ++ familyName = *cannonicalFamilyName; ++ } ++ fontStyle = proxy->fontStyle(); ++ isFixedWidth = proxy->isFixedPitch(); ++ } else { ++ if (cannonicalFamilyName != nullptr) { ++ familyName = *cannonicalFamilyName; ++ } ++ SkFontScanner_FreeType::computeAxisValues( ++ axisDefinitions, ++ SkFontArguments::VariationPosition{current.data(), current.size()}, ++ position, axisValues, familyName, &style); ++ } + int weight = fontFile.fWeight != 0 ? fontFile.fWeight : fontStyle.weight(); + SkFontStyle::Slant slant = fontStyle.slant(); + switch (fontFile.fStyle) { +@@ -204,6 +324,19 @@ public: + } + fontStyle = SkFontStyle(weight, fontStyle.width(), slant); + ++ if (use_custom) { ++ fStyles.push_back().reset( ++ new SkTypeface_AndroidSystemCustom(pathName, ++ fontFile.fIndex, ++ axisValues.get(), axisDefinitions.size(), ++ fontStyle, ++ isFixedWidth, ++ familyName, ++ family.fLanguages, ++ variant, ++ custom)); ++ continue; ++ } + fStyles.push_back().reset( + new SkTypeface_AndroidSystem(proxy, + pathName, +@@ -246,7 +379,7 @@ public: + } + + private: +- TArray> fStyles; ++ TArray> fStyles; + SkString fFallbackFor; + + friend struct NameToFamily; +@@ -267,24 +400,26 @@ struct NameToFamily { + + class SkFontMgr_Android : public SkFontMgr { + public: +- SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom, ++ SkFontMgr_Android(std::unique_ptr custom_in, + std::unique_ptr scanner) + : fScanner(std::move(scanner)) { ++ custom_ = std::move(custom_in); ++ auto* custom = custom_.get(); + SkTDArray families; + if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fSystemFontUse) { + SkString base(custom->fBasePath); + SkFontMgr_Android_Parser::GetCustomFontFamilies( +- families, base, custom->fFontsXml, custom->fFallbackFontsXml); ++ families, base, custom, custom->fFontsXml, custom->fFallbackFontsXml); + } + if (!custom || + (custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSystemFontUse)) + { +- SkFontMgr_Android_Parser::GetSystemFontFamilies(families); ++ SkFontMgr_Android_Parser::GetSystemFontFamilies(families, custom); + } + if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem == custom->fSystemFontUse) { + SkString base(custom->fBasePath); + SkFontMgr_Android_Parser::GetCustomFontFamilies( +- families, base, custom->fFontsXml, custom->fFallbackFontsXml); ++ families, base, custom, custom->fFontsXml, custom->fFallbackFontsXml); + } + this->buildNameToFamilyMap(families, custom ? custom->fIsolated : false); + this->findDefaultStyleSet(); +@@ -453,6 +588,7 @@ protected: + private: + + std::unique_ptr fScanner; ++ std::unique_ptr custom_; + + TArray> fStyleSets; + sk_sp fDefaultStyleSet; +@@ -472,7 +608,7 @@ private: + } + + sk_sp newSet = +- sk_make_sp(family, fScanner.get(), isolated); ++ sk_make_sp(family, fScanner.get(), isolated, custom_.get()); + if (0 == newSet->count()) { + return; + } +@@ -516,11 +652,11 @@ static char const * const gSystemFontUseStrings[] = { + + } // namespace + +-sk_sp SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom) { +- return SkFontMgr_New_Android(custom, SkFontScanner_Make_FreeType()); ++sk_sp SkFontMgr_New_Android(std::unique_ptr custom) { ++ return SkFontMgr_New_Android(std::move(custom), SkFontScanner_Make_FreeType()); + } + +-sk_sp SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom, std::unique_ptr scanner) { ++sk_sp SkFontMgr_New_Android(std::unique_ptr custom, std::unique_ptr scanner) { + if (custom) { + SkASSERT(0 <= custom->fSystemFontUse); + SkASSERT(custom->fSystemFontUse < std::size(gSystemFontUseStrings)); +@@ -530,5 +666,5 @@ sk_sp SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* cust + custom->fFontsXml, + custom->fFallbackFontsXml); + } +- return sk_make_sp(custom, std::move(scanner)); ++ return sk_make_sp(std::move(custom), std::move(scanner)); + } +diff --git a/third_party/skia/src/ports/SkFontMgr_android_data.cpp b/third_party/skia/src/ports/SkFontMgr_android_data.cpp +new file mode 100644 +--- /dev/null ++++ b/third_party/skia/src/ports/SkFontMgr_android_data.cpp +@@ -0,0 +1,1640 @@ ++// AUTOGENERATED ++// ++// SkString dumpAxis("axis|"); ++// dumpAxis.appendS32(axisDefinitions.size()); ++// dumpAxis.append("|"); ++// for (auto& def : axisDefinitions) { ++// dumpAxis.appendS32(def.fTag); ++// dumpAxis.append("|"); ++// dumpAxis.appendScalar(def.fMinimum); ++// dumpAxis.append("|"); ++// dumpAxis.appendScalar(def.fDefault); ++// dumpAxis.append("|"); ++// dumpAxis.appendScalar(def.fMaximum); ++// dumpAxis.append("|"); ++// } ++// SkDEBUGF("font file='%s' familyName='%s' width=%d weight=%d slant=%d axisDefinitions=%d isFixedWidth=%d axis=%s\n", ++// pathName.c_str(), ++// familyName.c_str(), ++// style.width(), ++// style.weight(), ++// style.slant(), ++// axisDefinitions.size(), ++// (int)isFixedWidth, ++// dumpAxis.c_str()); ++ ++bool GetFontData(const SkString& file, ++ SkString* familyName, ++ SkFontStyle* style, ++ bool* isFixedPitch, ++ SkFontScanner::AxisDefinitions* axes) { ++ if (file.equals("CarroisGothicSC-Regular.ttf")) { ++ familyName->set("Carrois Gothic SC"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("ComingSoon.ttf")) { ++ familyName->set("Coming Soon"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("CutiveMono.ttf")) { ++ familyName->set("Cutive Mono"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = true; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("DancingScript-Bold.ttf")) { ++ familyName->set("Dancing Script"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("DancingScript-Regular.ttf")) { ++ familyName->set("Dancing Script"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("DroidSansMono.ttf")) { ++ familyName->set("Droid Sans Mono"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = true; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoColorEmoji.ttf")) { ++ familyName->set("Noto Color Emoji"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoColorEmojiFlags.ttf")) { ++ familyName->set("Noto Color Emoji Flags"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = true; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoColorEmojiLegacy.ttf")) { ++ familyName->set("Noto Color Emoji"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = true; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoNaskhArabic-Bold.ttf")) { ++ familyName->set("Noto Naskh Arabic"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoNaskhArabic-Regular.ttf")) { ++ familyName->set("Noto Naskh Arabic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoNaskhArabicUI-Bold.ttf")) { ++ familyName->set("Noto Naskh Arabic UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoNaskhArabicUI-Regular.ttf")) { ++ familyName->set("Noto Naskh Arabic UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansAdlam-VF.ttf")) { ++ familyName->set("Noto Sans Adlam"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansAhom-Regular.otf")) { ++ familyName->set("Noto Sans Ahom"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansAnatolianHieroglyphs-Regular.otf")) { ++ familyName->set("Noto Sans Anatolian Hieroglyphs"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansArmenian-VF.ttf")) { ++ familyName->set("Noto Sans Armenian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansAvestan-Regular.ttf")) { ++ familyName->set("Noto Sans Avestan"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBalinese-Regular.ttf")) { ++ familyName->set("Noto Sans Balinese"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBamum-Regular.ttf")) { ++ familyName->set("Noto Sans Bamum"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBassaVah-Regular.otf")) { ++ familyName->set("Noto Sans Bassa Vah"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBatak-Regular.ttf")) { ++ familyName->set("Noto Sans Batak"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBengaliUI-VF.ttf")) { ++ familyName->set("Noto Sans Bengali UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansBengali-VF.ttf")) { ++ familyName->set("Noto Sans Bengali"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansBhaiksuki-Regular.otf")) { ++ familyName->set("Noto Sans Bhaiksuki"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBrahmi-Regular.ttf")) { ++ familyName->set("Noto Sans Brahmi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBuginese-Regular.ttf")) { ++ familyName->set("Noto Sans Buginese"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansBuhid-Regular.ttf")) { ++ familyName->set("Noto Sans Buhid"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCanadianAboriginal-Regular.ttf")) { ++ familyName->set("Noto Sans Canadian Aboriginal"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCarian-Regular.ttf")) { ++ familyName->set("Noto Sans Carian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansChakma-Regular.otf")) { ++ familyName->set("Noto Sans Chakma"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCham-Bold.ttf")) { ++ familyName->set("Noto Sans Cham"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCham-Regular.ttf")) { ++ familyName->set("Noto Sans Cham"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCherokee-Regular.ttf")) { ++ familyName->set("Noto Sans Cherokee"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCJK-Regular.ttc")) { ++ familyName->set("Noto Sans CJK SC"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCoptic-Regular.ttf")) { ++ familyName->set("Noto Sans Coptic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCuneiform-Regular.ttf")) { ++ familyName->set("Noto Sans Cuneiform"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansCypriot-Regular.ttf")) { ++ familyName->set("Noto Sans Cypriot"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansDeseret-Regular.ttf")) { ++ familyName->set("Noto Sans Deseret"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansDevanagariUI-VF.ttf")) { ++ familyName->set("Noto Sans Devanagari UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansDevanagari-VF.ttf")) { ++ familyName->set("Noto Sans Devanagari"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansEgyptianHieroglyphs-Regular.ttf")) { ++ familyName->set("Noto Sans Egyptian Hieroglyphs"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansElbasan-Regular.otf")) { ++ familyName->set("Noto Sans Elbasan"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansEthiopic-VF.ttf")) { ++ familyName->set("Noto Sans Ethiopic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansGeorgian-VF.ttf")) { ++ familyName->set("Noto Sans Georgian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansGlagolitic-Regular.ttf")) { ++ familyName->set("Noto Sans Glagolitic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGothic-Regular.ttf")) { ++ familyName->set("Noto Sans Gothic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGrantha-Regular.ttf")) { ++ familyName->set("Noto Sans Grantha"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGujarati-Bold.ttf")) { ++ familyName->set("Noto Sans Gujarati"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGujarati-Regular.ttf")) { ++ familyName->set("Noto Sans Gujarati"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGujaratiUI-Bold.ttf")) { ++ familyName->set("Noto Sans Gujarati UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGujaratiUI-Regular.ttf")) { ++ familyName->set("Noto Sans Gujarati UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGunjalaGondi-Regular.otf")) { ++ familyName->set("Noto Sans Gunjala Gondi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansGurmukhiUI-VF.ttf")) { ++ familyName->set("Noto Sans Gurmukhi UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansGurmukhi-VF.ttf")) { ++ familyName->set("Noto Sans Gurmukhi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansHanifiRohingya-Regular.otf")) { ++ familyName->set("Noto Sans Hanifi Rohingya"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansHanunoo-Regular.ttf")) { ++ familyName->set("Noto Sans Hanunoo"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansHatran-Regular.otf")) { ++ familyName->set("Noto Sans Hatran"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansHebrew-Bold.ttf")) { ++ familyName->set("Noto Sans Hebrew"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansHebrew-Regular.ttf")) { ++ familyName->set("Noto Sans Hebrew"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansImperialAramaic-Regular.ttf")) { ++ familyName->set("Noto Sans Imperial Aramaic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansInscriptionalPahlavi-Regular.ttf")) { ++ familyName->set("Noto Sans Inscriptional Pahlavi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansInscriptionalParthian-Regular.ttf")) { ++ familyName->set("Noto Sans Inscriptional Parthian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansJavanese-Regular.otf")) { ++ familyName->set("Noto Sans Javanese"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKaithi-Regular.ttf")) { ++ familyName->set("Noto Sans Kaithi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKannadaUI-VF.ttf")) { ++ familyName->set("Noto Sans Kannada UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansKannada-VF.ttf")) { ++ familyName->set("Noto Sans Kannada"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansKayahLi-Regular.ttf")) { ++ familyName->set("Noto Sans Kayah Li"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKharoshthi-Regular.ttf")) { ++ familyName->set("Noto Sans Kharoshthi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKhmerUI-Bold.ttf")) { ++ familyName->set("Noto Sans Khmer UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKhmerUI-Regular.ttf")) { ++ familyName->set("Noto Sans Khmer UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansKhmer-VF.ttf")) { ++ familyName->set("Noto Sans Khmer"); ++ *style = SkFontStyle(5, 90, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(2); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 26; ++ (*axes)[0].def = 90; ++ (*axes)[0].max = 190; ++ (*axes)[1].tag = 2003072104; ++ (*axes)[1].min = 70; ++ (*axes)[1].def = 100; ++ (*axes)[1].max = 100; ++ return true; ++ } ++ else if (file.equals("NotoSansKhojki-Regular.otf")) { ++ familyName->set("Noto Sans Khojki"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLao-Bold.ttf")) { ++ familyName->set("Noto Sans Lao"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLao-Regular.ttf")) { ++ familyName->set("Noto Sans Lao"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLaoUI-Bold.ttf")) { ++ familyName->set("Noto Sans Lao UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLaoUI-Regular.ttf")) { ++ familyName->set("Noto Sans Lao UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLepcha-Regular.ttf")) { ++ familyName->set("Noto Sans Lepcha"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLimbu-Regular.ttf")) { ++ familyName->set("Noto Sans Limbu"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLinearA-Regular.otf")) { ++ familyName->set("Noto Sans Linear A"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLinearB-Regular.ttf")) { ++ familyName->set("Noto Sans Linear B"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLisu-Regular.ttf")) { ++ familyName->set("Noto Sans Lisu"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLycian-Regular.ttf")) { ++ familyName->set("Noto Sans Lycian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansLydian-Regular.ttf")) { ++ familyName->set("Noto Sans Lydian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMalayalamUI-VF.ttf")) { ++ familyName->set("Noto Sans Malayalam UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansMalayalam-VF.ttf")) { ++ familyName->set("Noto Sans Malayalam"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansMandaic-Regular.ttf")) { ++ familyName->set("Noto Sans Mandaic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansManichaean-Regular.otf")) { ++ familyName->set("Noto Sans Manichaean"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMarchen-Regular.otf")) { ++ familyName->set("Noto Sans Marchen"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMasaramGondi-Regular.otf")) { ++ familyName->set("Noto Sans Masaram Gondi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMedefaidrin-VF.ttf")) { ++ familyName->set("Noto Sans Medefaidrin"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansMeeteiMayek-Regular.ttf")) { ++ familyName->set("Noto Sans Meetei Mayek"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMeroitic-Regular.otf")) { ++ familyName->set("Noto Sans Meroitic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMiao-Regular.otf")) { ++ familyName->set("Noto Sans Miao"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansModi-Regular.ttf")) { ++ familyName->set("Noto Sans Modi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMongolian-Regular.ttf")) { ++ familyName->set("Noto Sans Mongolian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMro-Regular.otf")) { ++ familyName->set("Noto Sans Mro"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMultani-Regular.otf")) { ++ familyName->set("Noto Sans Multani"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmar-Bold.otf")) { ++ familyName->set("Noto Sans Myanmar"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmar-Medium.otf")) { ++ familyName->set("Noto Sans Myanmar"); ++ *style = SkFontStyle(5, 500, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmar-Regular.otf")) { ++ familyName->set("Noto Sans Myanmar"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmarUI-Bold.otf")) { ++ familyName->set("Noto Sans Myanmar UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmarUI-Medium.otf")) { ++ familyName->set("Noto Sans Myanmar UI"); ++ *style = SkFontStyle(5, 500, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansMyanmarUI-Regular.otf")) { ++ familyName->set("Noto Sans Myanmar UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansNabataean-Regular.otf")) { ++ familyName->set("Noto Sans Nabataean"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansNewa-Regular.otf")) { ++ familyName->set("Noto Sans Newa"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansNewTaiLue-Regular.ttf")) { ++ familyName->set("Noto Sans New Tai Lue"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansNKo-Regular.ttf")) { ++ familyName->set("Noto Sans NKo"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOgham-Regular.ttf")) { ++ familyName->set("Noto Sans Ogham"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOlChiki-Regular.ttf")) { ++ familyName->set("Noto Sans Ol Chiki"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldItalic-Regular.ttf")) { ++ familyName->set("Noto Sans Old Italic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldNorthArabian-Regular.otf")) { ++ familyName->set("Noto Sans Old North Arabian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldPermic-Regular.otf")) { ++ familyName->set("Noto Sans Old Permic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldPersian-Regular.ttf")) { ++ familyName->set("Noto Sans Old Persian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldSouthArabian-Regular.ttf")) { ++ familyName->set("Noto Sans Old South Arabian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOldTurkic-Regular.ttf")) { ++ familyName->set("Noto Sans Old Turkic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOriya-Bold.ttf")) { ++ familyName->set("Noto Sans Oriya"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOriya-Regular.ttf")) { ++ familyName->set("Noto Sans Oriya"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOriyaUI-Bold.ttf")) { ++ familyName->set("Noto Sans Oriya UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOriyaUI-Regular.ttf")) { ++ familyName->set("Noto Sans Oriya UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOsage-Regular.ttf")) { ++ familyName->set("Noto Sans Osage"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansOsmanya-Regular.ttf")) { ++ familyName->set("Noto Sans Osmanya"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansPahawhHmong-Regular.otf")) { ++ familyName->set("Noto Sans Pahawh Hmong"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansPalmyrene-Regular.otf")) { ++ familyName->set("Noto Sans Palmyrene"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansPauCinHau-Regular.otf")) { ++ familyName->set("Noto Sans Pau Cin Hau"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansPhagsPa-Regular.ttf")) { ++ familyName->set("Noto Sans Phags Pa"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansPhoenician-Regular.ttf")) { ++ familyName->set("Noto Sans Phoenician"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansRejang-Regular.ttf")) { ++ familyName->set("Noto Sans Rejang"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansRunic-Regular.ttf")) { ++ familyName->set("Noto Sans Runic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSamaritan-Regular.ttf")) { ++ familyName->set("Noto Sans Samaritan"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSaurashtra-Regular.ttf")) { ++ familyName->set("Noto Sans Saurashtra"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSharada-Regular.otf")) { ++ familyName->set("Noto Sans Sharada"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansShavian-Regular.ttf")) { ++ familyName->set("Noto Sans Shavian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSinhalaUI-VF.ttf")) { ++ familyName->set("Noto Sans Sinhala UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansSinhala-VF.ttf")) { ++ familyName->set("Noto Sans Sinhala"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansSoraSompeng-Regular.otf")) { ++ familyName->set("Noto Sans Sora Sompeng"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSoyombo-VF.ttf")) { ++ familyName->set("Noto Sans Soyombo"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansSundanese-Regular.ttf")) { ++ familyName->set("Noto Sans Sundanese"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSylotiNagri-Regular.ttf")) { ++ familyName->set("Noto Sans Syloti Nagri"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSymbols-Regular-Subsetted.ttf")) { ++ familyName->set("Noto Sans Symbols"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSymbols-Regular-Subsetted2.ttf")) { ++ familyName->set("Noto Sans Symbols"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSyriacEastern-Regular.ttf")) { ++ familyName->set("Noto Sans Syriac Eastern"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSyriacEstrangela-Regular.ttf")) { ++ familyName->set("Noto Sans Syriac Estrangela"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansSyriacWestern-Regular.ttf")) { ++ familyName->set("Noto Sans Syriac Western"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTagalog-Regular.ttf")) { ++ familyName->set("Noto Sans Tagalog"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTagbanwa-Regular.ttf")) { ++ familyName->set("Noto Sans Tagbanwa"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTaiLe-Regular.ttf")) { ++ familyName->set("Noto Sans Tai Le"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTaiTham-Regular.ttf")) { ++ familyName->set("Noto Sans Tai Tham"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTaiViet-Regular.ttf")) { ++ familyName->set("Noto Sans Tai Viet"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTakri-VF.ttf")) { ++ familyName->set("Noto Sans Takri"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansTamilUI-VF.ttf")) { ++ familyName->set("Noto Sans Tamil"); ++ *style = SkFontStyle(2, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansTamil-VF.ttf")) { ++ familyName->set("Noto Sans Tamil"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansTeluguUI-VF.ttf")) { ++ familyName->set("Noto Sans Telugu UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansTelugu-VF.ttf")) { ++ familyName->set("Noto Sans Telugu"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSansThaana-Bold.ttf")) { ++ familyName->set("Noto Sans Thaana"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansThaana-Regular.ttf")) { ++ familyName->set("Noto Sans Thaana"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansThai-Bold.ttf")) { ++ familyName->set("Noto Sans Thai"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansThai-Regular.ttf")) { ++ familyName->set("Noto Sans Thai"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansThaiUI-Bold.ttf")) { ++ familyName->set("Noto Sans Thai UI"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansThaiUI-Regular.ttf")) { ++ familyName->set("Noto Sans Thai UI"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansTifinagh-Regular.otf")) { ++ familyName->set("Noto Sans Tifinagh"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansUgaritic-Regular.ttf")) { ++ familyName->set("Noto Sans Ugaritic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansVai-Regular.ttf")) { ++ familyName->set("Noto Sans Vai"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansWancho-Regular.otf")) { ++ familyName->set("Noto Sans Wancho"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansWarangCiti-Regular.otf")) { ++ familyName->set("Noto Sans Warang Citi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSansYi-Regular.ttf")) { ++ familyName->set("Noto Sans Yi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifArmenian-VF.ttf")) { ++ familyName->set("Noto Serif Armenian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifBengali-VF.ttf")) { ++ familyName->set("Noto Serif Bengali"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerif-Bold.ttf")) { ++ familyName->set("Noto Serif"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerif-BoldItalic.ttf")) { ++ familyName->set("Noto Serif"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifCJK-Regular.ttc")) { ++ familyName->set("Noto Serif CJK SC"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifDevanagari-VF.ttf")) { ++ familyName->set("Noto Serif Devanagari"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifDogra-Regular.ttf")) { ++ familyName->set("Noto Serif Dogra"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifEthiopic-VF.ttf")) { ++ familyName->set("Noto Serif Ethiopic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifGeorgian-VF.ttf")) { ++ familyName->set("Noto Serif Georgian"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifGujarati-VF.ttf")) { ++ familyName->set("Noto Serif Gujarati"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifGurmukhi-VF.ttf")) { ++ familyName->set("Noto Serif Gurmukhi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifHebrew-Bold.ttf")) { ++ familyName->set("Noto Serif Hebrew"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifHebrew-Regular.ttf")) { ++ familyName->set("Noto Serif Hebrew"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerif-Italic.ttf")) { ++ familyName->set("Noto Serif"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifKannada-VF.ttf")) { ++ familyName->set("Noto Serif Kannada"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifKhmer-Bold.otf")) { ++ familyName->set("Noto Serif Khmer"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifKhmer-Regular.otf")) { ++ familyName->set("Noto Serif Khmer"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifLao-Bold.ttf")) { ++ familyName->set("Noto Serif Lao"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifLao-Regular.ttf")) { ++ familyName->set("Noto Serif Lao"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifMalayalam-VF.ttf")) { ++ familyName->set("Noto Serif Malayalam"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifMyanmar-Bold.otf")) { ++ familyName->set("Noto Serif Myanmar"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifMyanmar-Regular.otf")) { ++ familyName->set("Noto Serif Myanmar"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifNyiakengPuachueHmong-VF.ttf")) { ++ familyName->set("Noto Serif Nyiakeng Puachue Hmong"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerif-Regular.ttf")) { ++ familyName->set("Noto Serif"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifSinhala-VF.ttf")) { ++ familyName->set("Noto Serif Sinhala"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifTamil-VF.ttf")) { ++ familyName->set("Noto Serif Tamil"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifTelugu-VF.ttf")) { ++ familyName->set("Noto Serif Telugu"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifThai-Bold.ttf")) { ++ familyName->set("Noto Serif Thai"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifThai-Regular.ttf")) { ++ familyName->set("Noto Serif Thai"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("NotoSerifTibetan-VF.ttf")) { ++ familyName->set("Noto Serif Tibetan"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("NotoSerifYezidi-VF.ttf")) { ++ familyName->set("Noto Serif Yezidi"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(1); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 400; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 700; ++ return true; ++ } ++ else if (file.equals("Roboto-Regular.ttf")) { ++ familyName->set("Roboto"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(3); ++ (*axes)[0].tag = 2003265652; ++ (*axes)[0].min = 100; ++ (*axes)[0].def = 400; ++ (*axes)[0].max = 900; ++ (*axes)[1].tag = 2003072104; ++ (*axes)[1].min = 75; ++ (*axes)[1].def = 100; ++ (*axes)[1].max = 100; ++ (*axes)[2].tag = 1769234796; ++ (*axes)[2].min = 0; ++ (*axes)[2].def = 0; ++ (*axes)[2].max = 1; ++ return true; ++ } ++ else if (file.equals("RobotoStatic-Regular.ttf")) { ++ familyName->set("RobotoStatic"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-Bold.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-BoldItalic.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 700, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-Italic.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-Regular.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 400, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-SemiBold.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 600, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ else if (file.equals("SourceSansPro-SemiBoldItalic.ttf")) { ++ familyName->set("Source Sans Pro"); ++ *style = SkFontStyle(5, 600, SkFontStyle::kUpright_Slant); ++ *isFixedPitch = false; ++ axes->reset(0); ++ return true; ++ } ++ ++ return false; ++} +diff --git a/third_party/skia/src/ports/SkFontMgr_android_parser.cpp b/third_party/skia/src/ports/SkFontMgr_android_parser.cpp +--- a/third_party/skia/src/ports/SkFontMgr_android_parser.cpp ++++ b/third_party/skia/src/ports/SkFontMgr_android_parser.cpp +@@ -652,14 +652,27 @@ static const XML_Memory_Handling_Suite sk_XML_alloc = { + * families array. Returns the version of the file, negative if the file does not exist. + */ + static int parse_config_file(const char* filename, SkTDArray& families, +- const SkString& basePath, bool isFallback) ++ const SkString& basePath, bool isFallback, ++ const SkFontMgr_Android_CustomFonts* custom = nullptr) + { + SkFILEStream file(filename); +- +- // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml) +- // are optional - failure here is okay because one of these optional files may not exist. +- if (!file.isValid()) { +- SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n", filename); ++ std::unique_ptr stream; ++ if (!custom && filename[0] != '#') { ++ // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml) ++ // are optional - failure here is okay because one of these optional files may not exist. ++ if (!file.isValid()) { ++ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n", filename); ++ return -1; ++ } ++ stream = file.fork(); ++ } else if (custom) { ++ stream = custom->getPlatformFile(filename); ++ if (!stream) { ++ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' platform file map not found\n", filename); ++ return -1; ++ } ++ } else { ++ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' custom fonts not set\n", filename); + return -1; + } + +@@ -691,8 +704,8 @@ static int parse_config_file(const char* filename, SkTDArray& famil + SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not buffer enough to continue\n"); + return -1; + } +- size_t len = file.read(buffer, bufferSize); +- done = file.isAtEnd(); ++ size_t len = stream->read(buffer, bufferSize); ++ done = stream->isAtEnd(); + XML_Status status = XML_ParseBuffer(parser, len, done); + if (XML_STATUS_ERROR == status) { + XML_Error error = XML_GetErrorCode(parser); +@@ -765,8 +778,10 @@ static void append_fallback_font_families_for_locale(SkTDArray& fal + } + + static void append_system_fallback_font_families(SkTDArray& fallbackFonts, +- const SkString& basePath) ++ const SkString& basePath, ++ const SkFontMgr_Android_CustomFonts* custom) + { ++ if (custom) return; + parse_config_file(FALLBACK_FONTS_FILE, fallbackFonts, basePath, true); + append_fallback_font_families_for_locale(fallbackFonts, + LOCALE_FALLBACK_FONTS_SYSTEM_DIR, +@@ -774,8 +789,10 @@ static void append_system_fallback_font_families(SkTDArray& fallbac + } + + static void mixin_vendor_fallback_font_families(SkTDArray& fallbackFonts, +- const SkString& basePath) ++ const SkString& basePath, ++ const SkFontMgr_Android_CustomFonts* custom) + { ++ if (custom) return; + SkTDArray vendorFonts; + parse_config_file(VENDOR_FONTS_FILE, vendorFonts, basePath, true); + append_fallback_font_families_for_locale(vendorFonts, +@@ -806,7 +823,8 @@ static void mixin_vendor_fallback_font_families(SkTDArray& fallback + } + } + +-void SkFontMgr_Android_Parser::GetSystemFontFamilies(SkTDArray& fontFamilies) { ++void SkFontMgr_Android_Parser::GetSystemFontFamilies(SkTDArray& fontFamilies, ++ const SkFontMgr_Android_CustomFonts* custom) { + // Version 21 of the system font configuration does not need any fallback configuration files. + SkString basePath(getenv("ANDROID_ROOT")); + basePath.append(SK_FONT_FILE_PREFIX, sizeof(SK_FONT_FILE_PREFIX) - 1); +@@ -817,22 +835,23 @@ void SkFontMgr_Android_Parser::GetSystemFontFamilies(SkTDArray& fon + + // Append all the fallback fonts to system fonts + SkTDArray fallbackFonts; +- append_system_fallback_font_families(fallbackFonts, basePath); +- mixin_vendor_fallback_font_families(fallbackFonts, basePath); ++ append_system_fallback_font_families(fallbackFonts, basePath, custom); ++ mixin_vendor_fallback_font_families(fallbackFonts, basePath, custom); + fontFamilies.append(fallbackFonts.size(), fallbackFonts.begin()); + } + + void SkFontMgr_Android_Parser::GetCustomFontFamilies(SkTDArray& fontFamilies, + const SkString& basePath, ++ const SkFontMgr_Android_CustomFonts* custom, + const char* fontsXml, + const char* fallbackFontsXml, + const char* langFallbackFontsDir) + { + if (fontsXml) { +- parse_config_file(fontsXml, fontFamilies, basePath, false); ++ parse_config_file(fontsXml, fontFamilies, basePath, false, custom); + } + if (fallbackFontsXml) { +- parse_config_file(fallbackFontsXml, fontFamilies, basePath, true); ++ parse_config_file(fallbackFontsXml, fontFamilies, basePath, true, custom); + } + if (langFallbackFontsDir) { + append_fallback_font_families_for_locale(fontFamilies, +diff --git a/third_party/skia/src/ports/SkFontMgr_android_parser.h b/third_party/skia/src/ports/SkFontMgr_android_parser.h +--- a/third_party/skia/src/ports/SkFontMgr_android_parser.h ++++ b/third_party/skia/src/ports/SkFontMgr_android_parser.h +@@ -15,6 +15,7 @@ + #include "include/private/base/SkTArray.h" + #include "include/private/base/SkTDArray.h" + #include "src/core/SkTHash.h" ++#include "include/ports/SkFontMgr_android.h" + + #include + #include +@@ -105,11 +106,13 @@ struct FontFamily { + namespace SkFontMgr_Android_Parser { + + /** Parses system font configuration files and appends result to fontFamilies. */ +-void GetSystemFontFamilies(SkTDArray& fontFamilies); ++void GetSystemFontFamilies(SkTDArray& fontFamilies, ++ const SkFontMgr_Android_CustomFonts* custom); + + /** Parses font configuration files and appends result to fontFamilies. */ + void GetCustomFontFamilies(SkTDArray& fontFamilies, + const SkString& basePath, ++ const SkFontMgr_Android_CustomFonts* custom, + const char* fontsXml, + const char* fallbackFontsXml, + const char* langFallbackFontsDir = nullptr); +-- diff --git a/build/patches/Disable-Component-Updates.patch b/build/patches/Disable-Component-Updates.patch deleted file mode 100644 index 0b933785..00000000 --- a/build/patches/Disable-Component-Updates.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: uazo -Date: Tue, 8 Nov 2022 12:41:22 +0000 -Subject: Disable Component Updates - -License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html ---- - chrome/browser/component_updater/registration.cc | 1 + - components/component_updater/component_installer.cc | 1 + - components/component_updater/component_updater_service.cc | 8 +------- - 3 files changed, 3 insertions(+), 7 deletions(-) - -diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc ---- a/chrome/browser/component_updater/registration.cc -+++ b/chrome/browser/component_updater/registration.cc -@@ -113,6 +113,7 @@ - namespace component_updater { - - void RegisterComponentsForUpdate() { -+ if ((true)) return; - auto* const cus = g_browser_process->component_updater(); - - #if BUILDFLAG(IS_WIN) -diff --git a/components/component_updater/component_installer.cc b/components/component_updater/component_installer.cc ---- a/components/component_updater/component_installer.cc -+++ b/components/component_updater/component_installer.cc -@@ -123,6 +123,7 @@ void ComponentInstaller::Register( - base::OnceClosure callback, - const base::Version& registered_version, - const base::Version& max_previous_product_version) { -+ if ((true)) return; - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (!installer_policy_) { -diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc ---- a/components/component_updater/component_updater_service.cc -+++ b/components/component_updater/component_updater_service.cc -@@ -542,14 +542,8 @@ std::unique_ptr ComponentUpdateServiceFactory( - - // Register prefs required by the component update service. - void RegisterComponentUpdateServicePrefs(PrefRegistrySimple* registry) { -- // If the preference is not set the component updates are enabled by default -- // unless in Chrome for Testing where we never want components to be updated -- // automatically. -- constexpr bool kComponentUpdatesEnabledByDefault = -- !BUILDFLAG(CHROME_FOR_TESTING); -- - registry->RegisterBooleanPref(prefs::kComponentUpdatesEnabled, -- kComponentUpdatesEnabledByDefault); -+ false); - } - - } // namespace component_updater --- diff --git a/build/patches/Enable-component-updater.patch b/build/patches/Enable-component-updater.patch new file mode 100644 index 00000000..381cab4e --- /dev/null +++ b/build/patches/Enable-component-updater.patch @@ -0,0 +1,536 @@ +From: uazo +Date: Wed, 29 Jan 2025 12:50:13 +0000 +Subject: Enable component updater + +Activates component updaters in one-shot mode: downloading occurs +only once and updates are inhibited. +Only cromite-specific components can be enabled. + +License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html +--- + .../browser/component_updater/registration.cc | 2 + + .../component_updater/component_installer.cc | 48 +++++++++++-------- + .../component_updater/component_installer.h | 4 +- + .../component_updater_url_constants.cc | 4 +- + .../component_updater/configurator_impl.cc | 8 +--- + .../component_updater/configurator_impl.h | 2 - + components/crx_file/crx_build_action_main.cc | 11 +++-- + components/crx_file/crx_verifier.cc | 16 +++++++ + components/update_client/component.cc | 12 +++++ + components/update_client/crx_downloader.cc | 5 ++ + components/update_client/net/network_impl.cc | 2 + + .../update_client/protocol_parser_json.cc | 2 + + components/update_client/request_sender.cc | 3 +- + components/update_client/update_checker.cc | 6 ++- + components/update_client/update_engine.cc | 9 ++++ + components/update_client/utils.cc | 3 ++ + 16 files changed, 100 insertions(+), 37 deletions(-) + +diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc +--- a/chrome/browser/component_updater/registration.cc ++++ b/chrome/browser/component_updater/registration.cc +@@ -115,6 +115,8 @@ namespace component_updater { + void RegisterComponentsForUpdate() { + auto* const cus = g_browser_process->component_updater(); + ++ if ((true)) return; ++ + #if BUILDFLAG(IS_WIN) + RegisterRecoveryImprovedComponent(cus, g_browser_process->local_state()); + #endif // BUILDFLAG(IS_WIN) +diff --git a/components/component_updater/component_installer.cc b/components/component_updater/component_installer.cc +--- a/components/component_updater/component_installer.cc ++++ b/components/component_updater/component_installer.cc +@@ -105,7 +105,9 @@ ComponentInstaller::ComponentInstaller( + ComponentInstaller::~ComponentInstaller() = default; + + void ComponentInstaller::Register(ComponentUpdateService* cus, +- base::OnceClosure callback) { ++ base::OnceClosure callback, ++ bool allowed) { ++ if (!allowed) return; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(cus); + +@@ -115,14 +117,16 @@ void ComponentInstaller::Register(ComponentUpdateService* cus, + Register(base::BindOnce(&ComponentUpdateService::RegisterComponent, + base::Unretained(cus)), + std::move(callback), cus->GetRegisteredVersion(crx_id), +- cus->GetMaxPreviousProductVersion(crx_id)); ++ cus->GetMaxPreviousProductVersion(crx_id), allowed); + } + + void ComponentInstaller::Register( + RegisterCallback register_callback, + base::OnceClosure callback, + const base::Version& registered_version, +- const base::Version& max_previous_product_version) { ++ const base::Version& max_previous_product_version, ++ bool allowed) { ++ if (!allowed) return; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!installer_policy_) { +@@ -143,7 +147,7 @@ void ComponentInstaller::Register( + } + + void ComponentInstaller::OnUpdateError(int error) { +- VLOG(0) << "Component update error: " << error; ++ LOG(INFO) << "Component update error: " << error; + } + + Result ComponentInstaller::InstallHelper(const base::FilePath& unpack_path, +@@ -153,6 +157,7 @@ Result ComponentInstaller::InstallHelper(const base::FilePath& unpack_path, + std::optional local_manifest = + update_client::ReadManifest(unpack_path); + if (!local_manifest) { ++ LOG(ERROR) << "Bad manifest"; + return Result(InstallError::BAD_MANIFEST); + } + +@@ -163,7 +168,7 @@ Result ComponentInstaller::InstallHelper(const base::FilePath& unpack_path, + + const base::Version manifest_version(*version_ascii); + +- VLOG(1) << "Install: version=" << manifest_version.GetString() ++ LOG(INFO) << "Install: version=" << manifest_version.GetString() + << " current version=" << current_version_.GetString(); + + if (!manifest_version.IsValid()) { +@@ -182,11 +187,11 @@ Result ComponentInstaller::InstallHelper(const base::FilePath& unpack_path, + } + } + +- VLOG(1) << "unpack_path=" << unpack_path.AsUTF8Unsafe() ++ LOG(INFO) << "unpack_path=" << unpack_path.AsUTF8Unsafe() + << " install_path=" << local_install_path.AsUTF8Unsafe(); + + if (!base::Move(unpack_path, local_install_path)) { +- VPLOG(0) << "Move failed."; ++ LOG(INFO) << "Move failed."; + base::DeletePathRecursively(local_install_path); + return Result(InstallError::MOVE_FILES_ERROR); + } +@@ -247,6 +252,9 @@ void ComponentInstaller::Install( + InstallHelper(unpack_path, &manifest, &version, &install_path); + base::DeletePathRecursively(unpack_path); + if (result.result.category_ != update_client::ErrorCategory::kNone) { ++ LOG(ERROR) << "ComponentInstaller:" ++ << " Install error " << result.result.code_ ++ << " extra " << result.result.extra_; + main_task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), result)); + return; +@@ -286,34 +294,34 @@ bool ComponentInstaller::FindPreinstallation( + scoped_refptr registration_info) { + base::FilePath path = root.Append(installer_policy_->GetRelativeInstallDir()); + if (!base::PathExists(path)) { +- DVLOG(1) << "Relative install dir does not exist: " << path.MaybeAsASCII(); ++ LOG(INFO) << "Relative install dir does not exist: " << path.MaybeAsASCII(); + return false; + } + + std::optional manifest = update_client::ReadManifest(path); + if (!manifest) { +- DVLOG(1) << "Manifest does not exist: " << path.MaybeAsASCII(); ++ LOG(INFO) << "Manifest does not exist: " << path.MaybeAsASCII(); + return false; + } + + if (!installer_policy_->VerifyInstallation(*manifest, path)) { +- DVLOG(1) << "Installation verification failed: " << path.MaybeAsASCII(); ++ LOG(INFO) << "Installation verification failed: " << path.MaybeAsASCII(); + return false; + } + + std::string* version_lexical = manifest->FindString("version"); + if (!version_lexical || !base::IsStringASCII(*version_lexical)) { +- DVLOG(1) << "Failed to get component version from the manifest."; ++ LOG(INFO) << "Failed to get component version from the manifest."; + return false; + } + + const base::Version version(*version_lexical); + if (!version.IsValid()) { +- DVLOG(1) << "Version in the manifest is invalid:" << *version_lexical; ++ LOG(INFO) << "Version in the manifest is invalid:" << *version_lexical; + return false; + } + +- VLOG(1) << "Preinstalled component found for " << installer_policy_->GetName() ++ LOG(INFO) << "Preinstalled component found for " << installer_policy_->GetName() + << " at " << path.MaybeAsASCII() << " with version " << version + << "."; + +@@ -330,13 +338,13 @@ std::optional + ComponentInstaller::GetValidInstallationManifest(const base::FilePath& path) { + std::optional manifest = update_client::ReadManifest(path); + if (!manifest) { +- VPLOG(0) << "Failed to read manifest for " << installer_policy_->GetName() ++ LOG(INFO) << "Failed to read manifest for " << installer_policy_->GetName() + << " (" << path.MaybeAsASCII() << ")."; + return std::nullopt; + } + + if (!installer_policy_->VerifyInstallation(*manifest, path)) { +- VPLOG(0) << "Failed to verify installation for " ++ LOG(INFO) << "Failed to verify installation for " + << installer_policy_->GetName() << " (" << path.MaybeAsASCII() + << ")."; + return std::nullopt; +@@ -453,7 +461,7 @@ std::optional ComponentInstaller::GetComponentDirectory() { + base::FilePath base_dir = + base_component_dir.Append(installer_policy_->GetRelativeInstallDir()); + if (!base::CreateDirectory(base_dir)) { +- VPLOG(0) << "Could not create the base directory for " ++ LOG(INFO) << "Could not create the base directory for " + << installer_policy_->GetName() << " (" << base_dir.MaybeAsASCII() + << ")."; + return std::nullopt; +@@ -538,14 +546,14 @@ void ComponentInstaller::UninstallOnTaskRunner() { + } + + if (!base::DeletePathRecursively(path)) { +- DVLOG(0) << "Couldn't delete " << path.value(); ++ LOG(INFO) << "Couldn't delete " << path.value(); + } + } + + // Delete the base directory if it's empty now. + if (base::IsDirectoryEmpty(*base_dir)) { + if (!base::DeleteFile(*base_dir)) { +- DVLOG(0) << "Couldn't delete " << base_dir->value(); ++ LOG(INFO) << "Couldn't delete " << base_dir->value(); + } + } + +@@ -589,7 +597,7 @@ void ComponentInstaller::FinishRegistration( + if (registration_info->manifest) { + ComponentReady(std::move(*registration_info->manifest)); + } else { +- DVLOG(1) << "No component found for " << installer_policy_->GetName(); ++ LOG(INFO) << "No component found for " << installer_policy_->GetName(); + } + + if (!callback.is_null()) { +@@ -598,7 +606,7 @@ void ComponentInstaller::FinishRegistration( + } + + void ComponentInstaller::ComponentReady(base::Value::Dict manifest) { +- VLOG(1) << "Component ready, version " << current_version_.GetString() ++ LOG(INFO) << "Component ready, version " << current_version_.GetString() + << " in " << current_install_dir_.value(); + installer_policy_->ComponentReady(current_version_, current_install_dir_, + std::move(manifest)); +diff --git a/components/component_updater/component_installer.h b/components/component_updater/component_installer.h +--- a/components/component_updater/component_installer.h ++++ b/components/component_updater/component_installer.h +@@ -152,7 +152,7 @@ class ComponentInstaller final : public update_client::CrxInstaller { + // |cus| provides the registration logic. + // The passed |callback| will be called once the initial check for installed + // versions is done and the component has been registered. +- void Register(ComponentUpdateService* cus, base::OnceClosure callback); ++ void Register(ComponentUpdateService* cus, base::OnceClosure callback, bool allowed = false); + + // Registers the component for update checks and installs. + // |register_callback| is called to do the registration. +@@ -162,7 +162,7 @@ class ComponentInstaller final : public update_client::CrxInstaller { + base::OnceClosure callback, + const base::Version& registered_version = base::Version(kNullVersion), + const base::Version& max_previous_product_version = +- base::Version(kNullVersion)); ++ base::Version(kNullVersion), bool allowed = false); + + // Overrides from update_client::CrxInstaller. + void OnUpdateError(int error) override; +diff --git a/components/component_updater/component_updater_url_constants.cc b/components/component_updater/component_updater_url_constants.cc +--- a/components/component_updater/component_updater_url_constants.cc ++++ b/components/component_updater/component_updater_url_constants.cc +@@ -15,9 +15,9 @@ namespace component_updater { + // The value of |kDefaultUrlSource| can be overridden with + // --component-updater=url-source=someurl. + const char kUpdaterJSONDefaultUrl[] = +- "https://update.googleapis.com/service/update2/json"; ++ "https://www.cromite.org/components/query.json"; + + const char kUpdaterJSONFallbackUrl[] = +- "http://update.googleapis.com/service/update2/json"; ++ "about:blank"; + + } // namespace component_updater +diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc +--- a/components/component_updater/configurator_impl.cc ++++ b/components/component_updater/configurator_impl.cc +@@ -40,8 +40,6 @@ ConfiguratorImpl::ConfiguratorImpl( + : background_downloads_enabled_(config_policy.BackgroundDownloadsEnabled()), + deltas_enabled_(config_policy.DeltaUpdatesEnabled()), + fast_update_(config_policy.FastUpdate()), +- pings_enabled_(config_policy.PingsEnabled()), +- require_encryption_(require_encryption), + url_source_override_(config_policy.UrlSourceOverride()), + initial_delay_(config_policy.InitialDelay()) { + if (config_policy.TestRequest()) { +@@ -83,16 +81,14 @@ std::vector ConfiguratorImpl::UpdateUrl() const { + + std::vector urls{GURL(kUpdaterJSONDefaultUrl), + GURL(kUpdaterJSONFallbackUrl)}; +- if (require_encryption_) { +- update_client::RemoveUnsecureUrls(&urls); +- } ++ update_client::RemoveUnsecureUrls(&urls); + + return urls; + } + + std::vector ConfiguratorImpl::PingUrl() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +- return pings_enabled_ ? UpdateUrl() : std::vector(); ++ return std::vector(); + } + + const base::Version& ConfiguratorImpl::GetBrowserVersion() const { +diff --git a/components/component_updater/configurator_impl.h b/components/component_updater/configurator_impl.h +--- a/components/component_updater/configurator_impl.h ++++ b/components/component_updater/configurator_impl.h +@@ -106,8 +106,6 @@ class ConfiguratorImpl { + const bool background_downloads_enabled_; + const bool deltas_enabled_; + const bool fast_update_; +- const bool pings_enabled_; +- const bool require_encryption_; + const GURL url_source_override_; + const base::TimeDelta initial_delay_; + }; +diff --git a/components/crx_file/crx_build_action_main.cc b/components/crx_file/crx_build_action_main.cc +--- a/components/crx_file/crx_build_action_main.cc ++++ b/components/crx_file/crx_build_action_main.cc +@@ -14,6 +14,7 @@ + #include "base/files/file_path.h" + #include "base/files/file_util.h" + #include "base/logging.h" ++#include "base/strings/string_number_conversions.h" + #include "components/crx_file/crx_creator.h" + #include "crypto/rsa_private_key.h" + +@@ -30,9 +31,13 @@ int main(int argc, char* argv[]) { + VLOG(0) << "Failed to read key material from " << argv[3]; + return -1; + } ++ auto signing_key = crypto::RSAPrivateKey::CreateFromPrivateKeyInfo( ++ std::vector(key_file.begin(), key_file.end())); ++ std::vector public_key; ++ signing_key->ExportPublicKey(&public_key); ++ VLOG(0) << "Pubkey: " << base::HexEncode(public_key); ++ + return static_cast(crx_file::Create( + base::FilePath::FromASCII(argv[1]), base::FilePath::FromASCII(argv[2]), +- crypto::RSAPrivateKey::CreateFromPrivateKeyInfo( +- std::vector(key_file.begin(), key_file.end())) +- .get())); ++ signing_key.get())); + } +diff --git a/components/crx_file/crx_verifier.cc b/components/crx_file/crx_verifier.cc +--- a/components/crx_file/crx_verifier.cc ++++ b/components/crx_file/crx_verifier.cc +@@ -18,6 +18,7 @@ + #include + #include + ++#include "base/logging.h" + #include "base/base64.h" + #include "base/files/file.h" + #include "base/files/file_path.h" +@@ -39,9 +40,15 @@ namespace { + + // The SHA256 hash of the DER SPKI "ecdsa_2017_public" Crx3 key. + constexpr uint8_t kPublisherKeyHash[] = { ++#if BUILDFLAG(IS_ANDROID) ++ 0x9F, 0x4A, 0x10, 0x80, 0x0F, 0x84, 0x13, 0xCB, 0x8F, 0x69, 0x92, ++ 0xA6, 0x03, 0x44, 0x9D, 0xC5, 0xFE, 0x01, 0x4D, 0x00, 0xF3, 0x4E, ++ 0x16, 0x79, 0xA1, 0x81, 0x95, 0x77, 0x1C, 0x5A, 0x21, 0x24}; ++#else + 0x61, 0xf7, 0xf2, 0xa6, 0xbf, 0xcf, 0x74, 0xcd, 0x0b, 0xc1, 0xfe, + 0x24, 0x97, 0xcc, 0x9b, 0x04, 0x25, 0x4c, 0x65, 0x8f, 0x79, 0xf2, + 0x14, 0x53, 0x92, 0x86, 0x7e, 0xa8, 0x36, 0x63, 0x67, 0xcf}; ++#endif + + // The SHA256 hash of the DER SPKI "ecdsa_2017_public" Crx3 test key. + constexpr uint8_t kPublisherTestKeyHash[] = { +@@ -210,6 +217,13 @@ VerifierResult VerifyCrx3( + found_publisher_key = + found_publisher_key || key_hash == publisher_key || + (accept_publisher_test_key && key_hash == *publisher_test_key); ++ ++ DLOG(INFO) << "---key_hash: " << base::HexEncode(key_hash); ++ DLOG(INFO) << "---publisher_key: " << base::HexEncode(publisher_key); ++ DLOG(INFO) << "---found_publisher_key: " << found_publisher_key; ++ DLOG(INFO) << "---sig: " << sig; ++ DLOG(INFO) << "---key: " << key; ++ + auto v = std::make_unique(); + static_assert(sizeof(unsigned char) == sizeof(uint8_t), + "Unsupported char size."); +@@ -223,9 +237,11 @@ VerifierResult VerifyCrx3( + verifiers.push_back(std::move(v)); + } + } ++#if !BUILDFLAG(IS_ANDROID) + if (public_key_bytes.empty() || !required_key_set.empty()) { + return VerifierResult::ERROR_REQUIRED_PROOF_MISSING; + } ++#endif + + if (require_publisher_key && !found_publisher_key) { + return VerifierResult::ERROR_REQUIRED_PROOF_MISSING; +diff --git a/components/update_client/component.cc b/components/update_client/component.cc +--- a/components/update_client/component.cc ++++ b/components/update_client/component.cc +@@ -398,6 +398,18 @@ void Component::StateChecking::DoHandle() { + return; + } + ++ LOG(INFO) << "Component: StateChecking" ++ << " component.id=" << component.id() ++ << " previous_version()=" << component.previous_version().GetString() ++ << " next_version()=" << component.next_version().GetString(); ++ ++#if BUILDFLAG(IS_ANDROID) ++ if (component.previous_version().CompareTo(component.next_version()) == 0) { ++ TransitionState(std::make_unique(&component)); ++ return; ++ } ++#endif ++ + if (component.pipeline_.has_value()) { + metrics::RecordUpdateCheckResult(metrics::UpdateCheckResult::kHasUpdate); + TransitionState(std::make_unique(&component)); +diff --git a/components/update_client/crx_downloader.cc b/components/update_client/crx_downloader.cc +--- a/components/update_client/crx_downloader.cc ++++ b/components/update_client/crx_downloader.cc +@@ -24,6 +24,7 @@ + #include "components/update_client/update_client_metrics.h" + #include "components/update_client/url_fetcher_downloader.h" + #include "components/update_client/utils.h" ++#include "base/logging.h" + + namespace update_client { + +@@ -89,6 +90,9 @@ base::OnceClosure CrxDownloader::StartDownload( + current_url_ = urls_.begin(); + download_callback_ = std::move(download_callback); + ++ LOG(INFO) << "CrxDownloader: StartDownload" ++ << " current_url_=" << *current_url_ ++ << " expected_hash=" << expected_hash; + return DoStartDownload(*current_url_); + } + +@@ -125,6 +129,7 @@ void CrxDownloader::OnDownloadComplete( + return CrxDownloaderError::NONE; + } + DeleteFileAndEmptyParentDirectory(filepath); ++ LOG(ERROR) << "CrxDownloaderError: BAD_HASH"; + return CrxDownloaderError::BAD_HASH; + }, + result.response, expected_hash_), +diff --git a/components/update_client/net/network_impl.cc b/components/update_client/net/network_impl.cc +--- a/components/update_client/net/network_impl.cc ++++ b/components/update_client/net/network_impl.cc +@@ -130,7 +130,9 @@ void NetworkFetcherImpl::PostRequest( + network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE); + // The `Content-Type` header set by |AttachStringForUpload| overwrites any + // `Content-Type` header present in the |ResourceRequest| above. ++#if !BUILDFLAG(IS_ANDROID) + simple_url_loader->AttachStringForUpload(post_data, content_type); ++#endif + simple_url_loader->SetOnResponseStartedCallback(base::BindOnce( + &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this), + std::move(response_started_callback))); +diff --git a/components/update_client/protocol_parser_json.cc b/components/update_client/protocol_parser_json.cc +--- a/components/update_client/protocol_parser_json.cc ++++ b/components/update_client/protocol_parser_json.cc +@@ -16,6 +16,7 @@ + #include "base/values.h" + #include "base/version.h" + #include "components/update_client/protocol_definition.h" ++#include "base/logging.h" + + namespace update_client { + +@@ -323,6 +324,7 @@ bool ProtocolParserJSON::DoParse(const std::string& response_json, + Results* results) { + CHECK(results); + ++ DLOG(INFO) << "ProtocolParserJSON: DoParse " << response_json; + if (response_json.empty()) { + ParseError("Empty JSON."); + return false; +diff --git a/components/update_client/request_sender.cc b/components/update_client/request_sender.cc +--- a/components/update_client/request_sender.cc ++++ b/components/update_client/request_sender.cc +@@ -104,7 +104,8 @@ void RequestSender::SendInternal() { + } + VLOG_IF(2, !url.is_valid()) << "url is not valid."; + +- VLOG(2) << "Sending Omaha request: " << request_body_; ++ LOG(INFO) << "Sending Omaha request: " << url.spec(); ++ DLOG(INFO) << "Request body (not send): " << request_body_; + + if (!fetcher_factory_) { + // The request was cancelled. +diff --git a/components/update_client/update_checker.cc b/components/update_client/update_checker.cc +--- a/components/update_client/update_checker.cc ++++ b/components/update_client/update_checker.cc +@@ -239,6 +239,10 @@ void UpdateCheckerImpl::CheckForUpdatesHelper( + config_->IsMachineExternallyManaged(), additional_attributes, + updater_state_attributes, std::move(apps)); + ++ bool enabled_cup_signing = config_->EnabledCupSigning(); ++#if BUILDFLAG(IS_ANDROID) ++ enabled_cup_signing = false; ++#endif + cancellation_->OnCancel( + base::MakeRefCounted(config_->GetNetworkFetcherFactory()) + ->Send({url}, +@@ -248,7 +252,7 @@ void UpdateCheckerImpl::CheckForUpdatesHelper( + config_->GetProtocolHandlerFactory() + ->CreateSerializer() + ->Serialize(request), +- config_->EnabledCupSigning(), ++ enabled_cup_signing, + base::BindOnce( + &UpdateCheckerImpl::OnRequestSenderComplete, + weak_factory_.GetWeakPtr(), context, +diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc +--- a/components/update_client/update_engine.cc ++++ b/components/update_client/update_engine.cc +@@ -212,6 +212,15 @@ void UpdateEngine::StartOperation( + component->set_crx_component(*crx_component); + component->set_previous_version(component->crx_component()->version); + component->set_previous_fp(component->crx_component()->fingerprint); ++#if BUILDFLAG(IS_ANDROID) ++ if (!update_context->is_foreground && component->crx_component()->version.IsValid() ++ && component->crx_component()->version.components()[0] != 0) { ++ LOG(INFO) << "Component " << id << " do not need updates. " ++ << "Current Version: " << component->crx_component()->version.GetString(); ++ continue; ++ } ++#endif ++ LOG(INFO) << "Component " << id << " can be checked for updates."; + update_context->components_to_check_for_updates.push_back(id); + } else { + // |CrxDataCallback| did not return a CrxComponent instance for this +diff --git a/components/update_client/utils.cc b/components/update_client/utils.cc +--- a/components/update_client/utils.cc ++++ b/components/update_client/utils.cc +@@ -106,6 +106,9 @@ bool VerifyFileHash256(const base::FilePath& filepath, + uint8_t actual_hash[crypto::kSHA256Length] = {}; + hasher->Finish(actual_hash, sizeof(actual_hash)); + ++ DLOG(INFO) << "VerifyFileHash256 " ++ << "actual_hash=" << base::HexEncode(actual_hash); ++ + return memcmp(actual_hash, &expected_hash[0], sizeof(actual_hash)) == 0; + } + +-- diff --git a/build/patches/Enable-gwp-asan-on-Android.patch b/build/patches/Enable-gwp-asan-on-Android.patch index 9e5cfe2f..11d6fe84 100644 --- a/build/patches/Enable-gwp-asan-on-Android.patch +++ b/build/patches/Enable-gwp-asan-on-Android.patch @@ -83,20 +83,20 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/setting import androidx.preference.PreferenceFragmentCompat; import org.chromium.base.ResettersForTesting; -@@ -19,10 +21,12 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; - import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; +@@ -20,10 +22,12 @@ import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; + import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; import org.chromium.components.browser_ui.settings.EmbeddableSettingsPage; import org.chromium.components.browser_ui.settings.SettingsUtils; +import org.chromium.chrome.browser.util.PlatformUtil; /** Settings fragment containing preferences aimed at Chrome and web developers. */ - public class DeveloperSettings extends PreferenceFragmentCompat implements EmbeddableSettingsPage { + public class DeveloperSettings extends ChromeBaseSettingsFragment implements EmbeddableSettingsPage { private static final String UI_PREF_BETA_STABLE_HINT = "beta_stable_hint"; + private static final String TEST_GWP_ASAN_KEY = "test_gwp_asan"; // Non-translated strings: private static final String MSG_DEVELOPER_OPTIONS_TITLE = "Developer options"; -@@ -58,6 +62,22 @@ public class DeveloperSettings extends PreferenceFragmentCompat implements Embed +@@ -59,6 +63,22 @@ public class DeveloperSettings extends ChromeBaseSettingsFragment implements Emb if (VersionInfo.isBetaBuild() || VersionInfo.isStableBuild()) { getPreferenceScreen().removePreference(findPreference(UI_PREF_BETA_STABLE_HINT)); } diff --git a/build/patches/Fonts-fingerprinting-mitigation.patch b/build/patches/Fonts-fingerprinting-mitigation.patch index 853bb095..c5e5e824 100644 --- a/build/patches/Fonts-fingerprinting-mitigation.patch +++ b/build/patches/Fonts-fingerprinting-mitigation.patch @@ -17,7 +17,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html --- .../Fonts-fingerprinting-mitigation.inc | 8 + .../Fonts-fingerprinting-mitigation.inc | 2 + - .../Fonts-fingerprinting-mitigation.inc | 5 + + .../Fonts-fingerprinting-mitigation.inc | 10 + skia/ext/skia_utils_win.cc | 20 ++ skia/ext/skia_utils_win.h | 3 + third_party/blink/public/common/features.h | 3 + @@ -26,7 +26,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html .../fonts/skia/bromite_allowed_fonts.h | 271 ++++++++++++++++++ .../platform/fonts/skia/font_cache_skia.cc | 44 ++- .../platform/fonts/win/font_cache_skia_win.cc | 7 +- - 11 files changed, 357 insertions(+), 9 deletions(-) + 11 files changed, 362 insertions(+), 9 deletions(-) create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Fonts-fingerprinting-mitigation.inc create mode 100644 cromite_flags/content/common/features_cc/Fonts-fingerprinting-mitigation.inc create mode 100644 cromite_flags/third_party/blink/common/features_cc/Fonts-fingerprinting-mitigation.inc @@ -41,7 +41,7 @@ new file mode 100644 + + {"fonts-fingerprint-mitigation", + "Enable fonts fingerprint mitigation", -+ "Filters the list of fonts allowing only standard ones to be used.", kOsAll, ++ "Filters the list of fonts allowing only standard ones to be used.", kOsDesktop, + FEATURE_VALUE_TYPE(blink::features::kFontsFingerprintMitigation)}, + +#endif @@ -56,12 +56,17 @@ diff --git a/cromite_flags/third_party/blink/common/features_cc/Fonts-fingerprin new file mode 100644 --- /dev/null +++ b/cromite_flags/third_party/blink/common/features_cc/Fonts-fingerprinting-mitigation.inc -@@ -0,0 +1,5 @@ +@@ -0,0 +1,10 @@ +SET_CROMITE_FEATURE_DISABLED(kGMSCoreEmoji); + +CROMITE_FEATURE(kFontsFingerprintMitigation, + "FontsFingerprintMitigation", -+ base::FEATURE_ENABLED_BY_DEFAULT); ++#if BUILDFLAG(IS_ANDROID) ++ base::FEATURE_DISABLED_BY_DEFAULT ++#else ++ base::FEATURE_ENABLED_BY_DEFAULT ++#endif ++); diff --git a/skia/ext/skia_utils_win.cc b/skia/ext/skia_utils_win.cc --- a/skia/ext/skia_utils_win.cc +++ b/skia/ext/skia_utils_win.cc diff --git a/build/patches/Internal-firewall.patch b/build/patches/Internal-firewall.patch index 2c375c31..fd317151 100644 --- a/build/patches/Internal-firewall.patch +++ b/build/patches/Internal-firewall.patch @@ -31,7 +31,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html services/firewall/tools/codegen.py | 82 +++ services/firewall/tools/decode_template.py | 85 +++ services/firewall/tools/gen_builders.py | 65 +++ - services/firewall/tools/rules.xml | 93 ++++ + services/firewall/tools/rules.xml | 96 ++++ services/firewall/tools/rules_model.py | 35 ++ services/network/network_context.cc | 73 +++ .../network/public/cpp/simple_url_loader.cc | 18 + @@ -40,7 +40,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html .../loader/fetch/url_loader/url_loader.cc | 4 +- .../scripts/auditor/auditor.py | 1 + .../scripts/auditor/util.py | 1 + - 31 files changed, 1652 insertions(+), 22 deletions(-) + 31 files changed, 1655 insertions(+), 22 deletions(-) create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Internal-firewall.inc create mode 100644 services/firewall/public/BUILD.gn create mode 100644 services/firewall/public/firewall_features.cc @@ -1514,7 +1514,7 @@ diff --git a/services/firewall/tools/rules.xml b/services/firewall/tools/rules.x new file mode 100644 --- /dev/null +++ b/services/firewall/tools/rules.xml -@@ -0,0 +1,93 @@ +@@ -0,0 +1,96 @@ + + + + ++ ++ ++ + diff --git a/services/firewall/tools/rules_model.py b/services/firewall/tools/rules_model.py new file mode 100644 diff --git a/build/patches/updater-disable-updater-pings.patch b/build/patches/updater-disable-updater-pings.patch deleted file mode 100644 index 92b47af3..00000000 --- a/build/patches/updater-disable-updater-pings.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Jan Engelhardt -Date: Tue, 2 Jun 2015 11:01:50 +0200 -Subject: updater: disable updater pings - -Despite auto-updater being arguably disabled (see previous commit), -Chromium would still send background requests. Kill it. -(trk:170, trk:171) - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../component_updater/component_updater_url_constants.cc | 4 ++-- - components/component_updater/configurator_impl.cc | 9 +++------ - components/component_updater/configurator_impl.h | 2 -- - 3 files changed, 5 insertions(+), 10 deletions(-) - -diff --git a/components/component_updater/component_updater_url_constants.cc b/components/component_updater/component_updater_url_constants.cc ---- a/components/component_updater/component_updater_url_constants.cc -+++ b/components/component_updater/component_updater_url_constants.cc -@@ -15,9 +15,9 @@ namespace component_updater { - // The value of |kDefaultUrlSource| can be overridden with - // --component-updater=url-source=someurl. - const char kUpdaterJSONDefaultUrl[] = -- "https://update.googleapis.com/service/update2/json"; -+ "about:blank"; - - const char kUpdaterJSONFallbackUrl[] = -- "http://update.googleapis.com/service/update2/json"; -+ "about:blank"; - - } // namespace component_updater -diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc ---- a/components/component_updater/configurator_impl.cc -+++ b/components/component_updater/configurator_impl.cc -@@ -40,8 +40,6 @@ ConfiguratorImpl::ConfiguratorImpl( - : background_downloads_enabled_(config_policy.BackgroundDownloadsEnabled()), - deltas_enabled_(config_policy.DeltaUpdatesEnabled()), - fast_update_(config_policy.FastUpdate()), -- pings_enabled_(config_policy.PingsEnabled()), -- require_encryption_(require_encryption), - url_source_override_(config_policy.UrlSourceOverride()), - initial_delay_(config_policy.InitialDelay()) { - if (config_policy.TestRequest()) { -@@ -77,22 +75,21 @@ base::TimeDelta ConfiguratorImpl::UpdateDelay() const { - - std::vector ConfiguratorImpl::UpdateUrl() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -+ if ((true)) return std::vector(); - if (url_source_override_.is_valid()) { - return {GURL(url_source_override_)}; - } - - std::vector urls{GURL(kUpdaterJSONDefaultUrl), - GURL(kUpdaterJSONFallbackUrl)}; -- if (require_encryption_) { -- update_client::RemoveUnsecureUrls(&urls); -- } -+ update_client::RemoveUnsecureUrls(&urls); - - return urls; - } - - std::vector ConfiguratorImpl::PingUrl() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -- return pings_enabled_ ? UpdateUrl() : std::vector(); -+ return std::vector(); - } - - const base::Version& ConfiguratorImpl::GetBrowserVersion() const { -diff --git a/components/component_updater/configurator_impl.h b/components/component_updater/configurator_impl.h ---- a/components/component_updater/configurator_impl.h -+++ b/components/component_updater/configurator_impl.h -@@ -106,8 +106,6 @@ class ConfiguratorImpl { - const bool background_downloads_enabled_; - const bool deltas_enabled_; - const bool fast_update_; -- const bool pings_enabled_; -- const bool require_encryption_; - const GURL url_source_override_; - const base::TimeDelta initial_delay_; - }; --- diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 56e1e39f..cd8fb607 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -25,7 +25,6 @@ Also disable gamepadconnected and gamepaddisconnected, see https://jshelter.org/ - Disable WebGL by default - Disable WebRTC by default - Disable MIDI permission by default -- Disable the use of non-standard and local fonts - Enable Canvas and Rect API fingerprinting mitigations - Enable Media API fingerprinting mitigations - AudioBuffer and AnalyserNode fingerprinting mitigations (https://fingerprint.com/blog/audio-fingerprinting/) @@ -49,6 +48,8 @@ Also disable gamepadconnected and gamepaddisconnected, see https://jshelter.org/ - (WINDOWS) Hide the presence of the webcam if the user has not given permission - (WINDOWS) PublicKeyCredential fingerprinting mitigations, see #1758 - (DESKTOP) Disable Bluetooth API by default +- (WINDOWS) Disable the use of non-standard and local fonts +- (ANDROID) Replaces system fonts with a predefined set (https://github.com/uazo/cromite/issues/1829) #### Tracking navigation - Enable network isolation features diff --git a/docs/PRIVACY_POLICY.md b/docs/PRIVACY_POLICY.md index 2acd8ae4..b372d4b6 100644 --- a/docs/PRIVACY_POLICY.md +++ b/docs/PRIVACY_POLICY.md @@ -75,7 +75,10 @@ On desktop platforms it is possible to activate the automatic update of extensio In Android, the installation of PWAs is disabled and cannot be re-enabled. -Cromite does not download or update any external components. +Cromite does not download or update any google components. + +Cromite, by default, downloads from www.cromite.org a zip containing the fonts it uses for anti-fingerpriting protection. If the zip has already been downloaded, no connection is made again. +In www.cromite.org, no log is active. #### NETWORK TIME Cromite never uses network time to verify SSL certificates, and no call is made to verify it.