summaryrefslogtreecommitdiff
path: root/chromium/content/child/dwrite_font_proxy
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/child/dwrite_font_proxy')
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc6
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc76
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h18
3 files changed, 67 insertions, 33 deletions
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
index 7d717652d05..c06ca35000b 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
@@ -59,12 +59,8 @@ void InitializeDWriteFontProxy() {
if (!g_font_collection) {
mojo::PendingRemote<blink::mojom::DWriteFontProxy> dwrite_font_proxy;
- if (g_connection_callback_override) {
+ if (g_connection_callback_override)
dwrite_font_proxy = g_connection_callback_override->Run();
- } else if (auto* thread = ChildThread::Get()) {
- thread->BindHostReceiver(
- dwrite_font_proxy.InitWithNewPipeAndPassReceiver());
- }
DWriteFontCollectionProxy::Create(&g_font_collection, factory.Get(),
std::move(dwrite_font_proxy));
}
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
index 23330b6374b..b788c4ded4f 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
@@ -17,7 +17,6 @@
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
-#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "content/child/dwrite_font_proxy/dwrite_localized_strings_win.h"
#include "content/public/child/child_thread.h"
@@ -29,6 +28,33 @@ namespace content {
namespace {
+// Limits to 20 the number of family names that can be accessed by a renderer.
+// This feature will be enabled for a subset of users to assess the impact on
+// input delay. It will not ship as-is, because it breaks some pages. Local
+// experiments show that accessing >20 fonts is typically done by fingerprinting
+// scripts.
+// TODO(https://crbug.com/1089390): Remove this feature when the experiment is
+// complete. If the experiment shows a significant input delay improvement,
+// replace with a more refined mitigation for pages that access many fonts.
+const base::Feature kLimitFontFamilyNamesPerRenderer{
+ "LimitFontFamilyNamesPerRenderer", base::FEATURE_DISABLED_BY_DEFAULT};
+constexpr size_t kFamilyNamesLimit = 20;
+
+// Family names that opted-out from the limit enforced by
+// |kLimitFontFamilyNamesPerRenderer|. This is required because Blink uses these
+// fonts as last resort and crashes if they can't be loaded.
+const wchar_t* kLastResortFontNames[] = {
+ L"Sans", L"Arial", L"MS UI Gothic", L"Microsoft Sans Serif",
+ L"Segoe UI", L"Calibri", L"Times New Roman", L"Courier New"};
+
+bool IsLastResortFontName(const base::string16& font_name) {
+ for (const wchar_t* last_resort_font_name : kLastResortFontNames) {
+ if (font_name == last_resort_font_name)
+ return true;
+ }
+ return false;
+}
+
// This enum is used to define the buckets for an enumerated UMA histogram.
// Hence,
// (a) existing enumerated constants should never be deleted or reordered, and
@@ -73,6 +99,13 @@ void LogFontProxyError(FontProxyError error) {
FONT_PROXY_ERROR_MAX_VALUE);
}
+// Binds a DWriteFontProxy pending receiver. Must be invoked from the main
+// thread.
+void BindHostReceiverOnMainThread(
+ mojo::PendingReceiver<blink::mojom::DWriteFontProxy> pending_receiver) {
+ ChildThread::Get()->BindHostReceiver(std::move(pending_receiver));
+}
+
} // namespace
HRESULT DWriteFontCollectionProxy::Create(
@@ -95,7 +128,6 @@ HRESULT DWriteFontCollectionProxy::FindFamilyName(const WCHAR* family_name,
DCHECK(exists);
TRACE_EVENT0("dwrite,fonts", "FontProxy::FindFamilyName");
- uint32_t family_index = 0;
base::string16 name(family_name);
auto iter = family_names_.find(name);
@@ -105,6 +137,14 @@ HRESULT DWriteFontCollectionProxy::FindFamilyName(const WCHAR* family_name,
return S_OK;
}
+ if (base::FeatureList::IsEnabled(kLimitFontFamilyNamesPerRenderer) &&
+ family_names_.size() > kFamilyNamesLimit && !IsLastResortFontName(name)) {
+ *exists = FALSE;
+ *index = UINT32_MAX;
+ return S_OK;
+ }
+
+ uint32_t family_index = 0;
if (!GetFontProxy().FindFamily(name, &family_index)) {
LogFontProxyError(FIND_FAMILY_SEND_FAILED);
return E_FAIL;
@@ -269,9 +309,8 @@ HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize(
factory_ = factory;
if (proxy)
- SetProxy(std::move(proxy));
- else
- main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ font_proxy_.GetOrCreateValue().Bind(std::move(proxy));
+ main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
HRESULT hr = factory->RegisterFontCollectionLoader(this);
DCHECK(SUCCEEDED(hr));
@@ -358,32 +397,19 @@ bool DWriteFontCollectionProxy::CreateFamily(UINT32 family_index) {
return true;
}
-void DWriteFontCollectionProxy::SetProxy(
- mojo::PendingRemote<blink::mojom::DWriteFontProxy> proxy) {
- font_proxy_ = blink::mojom::ThreadSafeDWriteFontProxyPtr::Create(
- std::move(proxy), base::ThreadPool::CreateSequencedTaskRunner(
- {base::WithBaseSyncPrimitives()}));
-}
-
blink::mojom::DWriteFontProxy& DWriteFontCollectionProxy::GetFontProxy() {
- if (!font_proxy_) {
- mojo::PendingRemote<blink::mojom::DWriteFontProxy> dwrite_font_proxy;
+ mojo::Remote<blink::mojom::DWriteFontProxy>& font_proxy =
+ font_proxy_.GetOrCreateValue();
+ if (!font_proxy) {
if (main_task_runner_->RunsTasksInCurrentSequence()) {
- ChildThread::Get()->BindHostReceiver(
- dwrite_font_proxy.InitWithNewPipeAndPassReceiver());
+ BindHostReceiverOnMainThread(font_proxy.BindNewPipeAndPassReceiver());
} else {
main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](mojo::PendingReceiver<blink::mojom::DWriteFontProxy>
- receiver) {
- ChildThread::Get()->BindHostReceiver(std::move(receiver));
- },
- dwrite_font_proxy.InitWithNewPipeAndPassReceiver()));
+ FROM_HERE, base::BindOnce(&BindHostReceiverOnMainThread,
+ font_proxy.BindNewPipeAndPassReceiver()));
}
- SetProxy(std::move(dwrite_font_proxy));
}
- return **font_proxy_;
+ return *font_proxy;
}
DWriteFontFamilyProxy::DWriteFontFamilyProxy() = default;
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
index 576fa767650..0e14fa0c51b 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h
@@ -15,8 +15,10 @@
#include "base/files/memory_mapped_file.h"
#include "base/macros.h"
#include "base/strings/string16.h"
+#include "base/threading/sequence_local_storage_slot.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom.h"
namespace content {
@@ -28,6 +30,8 @@ class DWriteFontFamilyProxy;
// into a custom font collection.
// This is needed because the sandbox interferes with DirectWrite's
// communication with the system font service.
+// This class can be accessed from any thread, but it is expected that a lock
+// internal to DWrite prevents concurrent accesses.
class DWriteFontCollectionProxy
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
@@ -36,6 +40,12 @@ class DWriteFontCollectionProxy
IDWriteFontFileLoader> {
public:
// Factory method to avoid exporting the class and all it derives from.
+ //
+ // |proxy| is an optional DWriteFontProxy to use when the constructed
+ // DWriteFontCollectionProxy is used on the current sequence. DWriteFontProxy
+ // remotes will be bound via ChildThread when the constructed
+ // DWriteFontCollectionProxy is used from a sequence for which no
+ // DWriteFontProxy has been provided.
static CONTENT_EXPORT HRESULT
Create(DWriteFontCollectionProxy** proxy_out,
IDWriteFactory* dwrite_factory,
@@ -92,14 +102,16 @@ class DWriteFontCollectionProxy
blink::mojom::DWriteFontProxy& GetFontProxy();
private:
- void SetProxy(mojo::PendingRemote<blink::mojom::DWriteFontProxy> proxy);
-
Microsoft::WRL::ComPtr<IDWriteFactory> factory_;
std::vector<Microsoft::WRL::ComPtr<DWriteFontFamilyProxy>> families_;
std::map<base::string16, UINT32> family_names_;
UINT32 family_count_ = UINT_MAX;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
- scoped_refptr<blink::mojom::ThreadSafeDWriteFontProxyPtr> font_proxy_;
+ // Per-sequence mojo::Remote<DWriteFontProxy>. This is preferred to a
+ // mojo::SharedRemote, which would force a thread hop for each call that
+ // doesn't originate from the "bound" sequence.
+ base::SequenceLocalStorageSlot<mojo::Remote<blink::mojom::DWriteFontProxy>>
+ font_proxy_;
DISALLOW_ASSIGN(DWriteFontCollectionProxy);
};