Commit fffc6331 authored by Alex Turner's avatar Alex Turner Committed by Commit Bot

Instrument PostScript name to typeface mapping for identifiability study

Currently, local font lookups are instrumented with a digest of the
lookup value and a digest of the resulting typeface being recorded. We
expand this recording for successful local font lookups: we now also
record a digest of the resulting typeface's PostScript name with the
typeface digest. This will allow the identifiability study to measure
the diversity of installed typeface files with the same PostScript name
(for example, differing versions of the same typeface) and thus
evaluate the privacy impact of that variation.

Bug: 1136210
Change-Id: Id7ac6229db287af776474f43abd200c51319992e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453439Reviewed-by: default avatarDominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarAsanka Herath <asanka@chromium.org>
Commit-Queue: Alex Turner <alexmt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815773}
parent 53e08203
...@@ -171,7 +171,7 @@ class IdentifiableSurface { ...@@ -171,7 +171,7 @@ class IdentifiableSurface {
// FontSelectionRequest (i.e. weight, width and slope). // FontSelectionRequest (i.e. weight, width and slope).
kLocalFontLookupByFallbackCharacter = 13, kLocalFontLookupByFallbackCharacter = 13,
// Represents loading a font locally as a last resort. Input is the // Represents looking up a font locally as a last resort. Input is the
// FontSelectionRequest (i.e. weight, width and slope). // FontSelectionRequest (i.e. weight, width and slope).
kLocalFontLookupAsLastResort = 14, kLocalFontLookupAsLastResort = 14,
...@@ -201,6 +201,9 @@ class IdentifiableSurface { ...@@ -201,6 +201,9 @@ class IdentifiableSurface {
// the hint parameter. // the hint parameter.
kNavigatorUAData_GetHighEntropyValues = 24, kNavigatorUAData_GetHighEntropyValues = 24,
// Represents loading a font locally. Input is the PostScript name.
kLocalFontLoadPostScriptName = 29,
// We can use values up to and including |kMax|. // We can use values up to and including |kMax|.
kMax = (1 << kTypeBits) - 1 kMax = (1 << kTypeBits) - 1
}; };
......
...@@ -7,12 +7,13 @@ ...@@ -7,12 +7,13 @@
#include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h" #include "third_party/blink/renderer/platform/fonts/font_unique_name_lookup.h"
#include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h" #include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_font_cache.h"
#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h" #include "third_party/blink/renderer/platform/wtf/thread_specific.h"
// While the size of this cache should usually be small (up to tens), we protect // While the size of these caches should usually be small (up to tens), we
// against the possibility of it growing quickly to thousands when animating // protect against the possibility of it growing quickly to thousands when
// variable font parameters. // animating variable font parameters.
static constexpr size_t kTypefaceDigestCacheMaxSize = 250; static constexpr size_t kCachesMaxSize = 250;
namespace blink { namespace blink {
...@@ -28,7 +29,8 @@ FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) { ...@@ -28,7 +29,8 @@ FontGlobalContext* FontGlobalContext::Get(CreateIfNeeded create_if_needed) {
FontGlobalContext::FontGlobalContext() FontGlobalContext::FontGlobalContext()
: harfbuzz_font_funcs_skia_advances_(nullptr), : harfbuzz_font_funcs_skia_advances_(nullptr),
harfbuzz_font_funcs_harfbuzz_advances_(nullptr), harfbuzz_font_funcs_harfbuzz_advances_(nullptr),
typeface_digest_cache_(kTypefaceDigestCacheMaxSize) {} typeface_digest_cache_(kCachesMaxSize),
postscript_name_digest_cache_(kCachesMaxSize) {}
FontGlobalContext::~FontGlobalContext() = default; FontGlobalContext::~FontGlobalContext() = default;
...@@ -67,12 +69,33 @@ IdentifiableToken FontGlobalContext::GetOrComputeTypefaceDigest( ...@@ -67,12 +69,33 @@ IdentifiableToken FontGlobalContext::GetOrComputeTypefaceDigest(
return *cached_value; return *cached_value;
} }
IdentifiableToken FontGlobalContext::GetOrComputePostScriptNameDigest(
const FontPlatformData& source) {
SkTypeface* typeface = source.Typeface();
if (!typeface)
return IdentifiableToken();
SkFontID font_id = typeface->uniqueID();
IdentifiableToken* cached_value = postscript_name_digest_cache_.Get(font_id);
if (!cached_value) {
postscript_name_digest_cache_.Put(
font_id, IdentifiabilityBenignStringToken(source.GetPostScriptName()));
cached_value = postscript_name_digest_cache_.Get(font_id);
} else {
DCHECK(*cached_value ==
IdentifiabilityBenignStringToken(source.GetPostScriptName()));
}
return *cached_value;
}
void FontGlobalContext::ClearMemory() { void FontGlobalContext::ClearMemory() {
if (!Get(kDoNotCreate)) if (!Get(kDoNotCreate))
return; return;
GetFontCache().Invalidate(); GetFontCache().Invalidate();
Get()->typeface_digest_cache_.Clear(); Get()->typeface_digest_cache_.Clear();
Get()->postscript_name_digest_cache_.Clear();
} }
} // namespace blink } // namespace blink
...@@ -59,6 +59,8 @@ class PLATFORM_EXPORT FontGlobalContext { ...@@ -59,6 +59,8 @@ class PLATFORM_EXPORT FontGlobalContext {
static FontUniqueNameLookup* GetFontUniqueNameLookup(); static FontUniqueNameLookup* GetFontUniqueNameLookup();
IdentifiableToken GetOrComputeTypefaceDigest(const FontPlatformData& source); IdentifiableToken GetOrComputeTypefaceDigest(const FontPlatformData& source);
IdentifiableToken GetOrComputePostScriptNameDigest(
const FontPlatformData& source);
// Called by MemoryPressureListenerRegistry to clear memory. // Called by MemoryPressureListenerRegistry to clear memory.
static void ClearMemory(); static void ClearMemory();
...@@ -75,6 +77,7 @@ class PLATFORM_EXPORT FontGlobalContext { ...@@ -75,6 +77,7 @@ class PLATFORM_EXPORT FontGlobalContext {
hb_font_funcs_t* harfbuzz_font_funcs_harfbuzz_advances_; hb_font_funcs_t* harfbuzz_font_funcs_harfbuzz_advances_;
std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_; std::unique_ptr<FontUniqueNameLookup> font_unique_name_lookup_;
WTF::LruCache<SkFontID, IdentifiableToken> typeface_digest_cache_; WTF::LruCache<SkFontID, IdentifiableToken> typeface_digest_cache_;
WTF::LruCache<SkFontID, IdentifiableToken> postscript_name_digest_cache_;
DISALLOW_COPY_AND_ASSIGN(FontGlobalContext); DISALLOW_COPY_AND_ASSIGN(FontGlobalContext);
}; };
......
...@@ -109,6 +109,12 @@ void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key, ...@@ -109,6 +109,12 @@ void FontMatchingMetrics::InsertFontHashIntoMap(IdentifiableTokenKey input_key,
return; return;
IdentifiableToken output_token(GetHashForFontData(font_data)); IdentifiableToken output_token(GetHashForFontData(font_data));
hash_map.insert(input_key, output_token); hash_map.insert(input_key, output_token);
if (!font_data)
return;
IdentifiableTokenKey postscript_name_key(
GetPostScriptNameTokenForFontData(font_data));
font_load_postscript_name_.insert(postscript_name_key, output_token);
} }
IdentifiableTokenBuilder IdentifiableTokenBuilder
...@@ -245,6 +251,8 @@ void FontMatchingMetrics::PublishIdentifiabilityMetrics() { ...@@ -245,6 +251,8 @@ void FontMatchingMetrics::PublishIdentifiabilityMetrics() {
IdentifiableSurface::Type::kLocalFontLookupAsLastResort}, IdentifiableSurface::Type::kLocalFontLookupAsLastResort},
{&generic_font_lookups_, {&generic_font_lookups_,
IdentifiableSurface::Type::kGenericFontLookup}, IdentifiableSurface::Type::kGenericFontLookup},
{&font_load_postscript_name_,
IdentifiableSurface::Type::kLocalFontLoadPostScriptName},
}; };
for (const auto& surface_entry : hash_maps_with_corresponding_surface_types) { for (const auto& surface_entry : hash_maps_with_corresponding_surface_types) {
...@@ -310,4 +318,11 @@ int64_t FontMatchingMetrics::GetHashForFontData(SimpleFontData* font_data) { ...@@ -310,4 +318,11 @@ int64_t FontMatchingMetrics::GetHashForFontData(SimpleFontData* font_data) {
: 0; : 0;
} }
IdentifiableToken FontMatchingMetrics::GetPostScriptNameTokenForFontData(
SimpleFontData* font_data) {
DCHECK(font_data);
return FontGlobalContext::Get()->GetOrComputePostScriptNameDigest(
font_data->PlatformData());
}
} // namespace blink } // namespace blink
...@@ -193,7 +193,9 @@ class PLATFORM_EXPORT FontMatchingMetrics { ...@@ -193,7 +193,9 @@ class PLATFORM_EXPORT FontMatchingMetrics {
IdentifiableTokenKeyHashTraits>; IdentifiableTokenKeyHashTraits>;
// Adds a digest of the |font_data|'s typeface to |hash_map| using the key // Adds a digest of the |font_data|'s typeface to |hash_map| using the key
// |input_key|, unless that key is already present. // |input_key|, unless that key is already present. If |font_data| is not
// nullptr, then the typeface digest will also be saved with its PostScript
// name in |font_load_postscript_name_|.
void InsertFontHashIntoMap(IdentifiableTokenKey input_key, void InsertFontHashIntoMap(IdentifiableTokenKey input_key,
SimpleFontData* font_data, SimpleFontData* font_data,
TokenToTokenHashMap hash_map); TokenToTokenHashMap hash_map);
...@@ -208,6 +210,11 @@ class PLATFORM_EXPORT FontMatchingMetrics { ...@@ -208,6 +210,11 @@ class PLATFORM_EXPORT FontMatchingMetrics {
void Initialize(); void Initialize();
// Get a token that uniquely represents the typeface's PostScript name. May
// represent the empty string if no PostScript name was found.
IdentifiableToken GetPostScriptNameTokenForFontData(
SimpleFontData* font_data);
// Font family names successfully matched. // Font family names successfully matched.
HashSet<AtomicString> successful_font_families_; HashSet<AtomicString> successful_font_families_;
...@@ -235,6 +242,7 @@ class PLATFORM_EXPORT FontMatchingMetrics { ...@@ -235,6 +242,7 @@ class PLATFORM_EXPORT FontMatchingMetrics {
TokenToTokenHashMap font_lookups_by_fallback_character_; TokenToTokenHashMap font_lookups_by_fallback_character_;
TokenToTokenHashMap font_lookups_as_last_resort_; TokenToTokenHashMap font_lookups_as_last_resort_;
TokenToTokenHashMap generic_font_lookups_; TokenToTokenHashMap generic_font_lookups_;
TokenToTokenHashMap font_load_postscript_name_;
ukm::UkmRecorder* const ukm_recorder_; ukm::UkmRecorder* const ukm_recorder_;
const ukm::SourceId source_id_; const ukm::SourceId source_id_;
......
...@@ -338,4 +338,13 @@ IdentifiableToken FontPlatformData::ComputeTypefaceDigest() const { ...@@ -338,4 +338,13 @@ IdentifiableToken FontPlatformData::ComputeTypefaceDigest() const {
return builder.GetToken(); // hasher.GetHash(); return builder.GetToken(); // hasher.GetHash();
} }
String FontPlatformData::GetPostScriptName() const {
if (!typeface_)
return String();
SkString postscript_name;
bool success = typeface_->getPostScriptName(&postscript_name);
return success ? postscript_name.c_str() : String();
}
} // namespace blink } // namespace blink
...@@ -145,6 +145,9 @@ class PLATFORM_EXPORT FontPlatformData { ...@@ -145,6 +145,9 @@ class PLATFORM_EXPORT FontPlatformData {
// the fingerprinting algorithm. // the fingerprinting algorithm.
IdentifiableToken ComputeTypefaceDigest() const; IdentifiableToken ComputeTypefaceDigest() const;
// Gets the postscript name from the typeface.
String GetPostScriptName() const;
private: private:
#if !defined(OS_WIN) && !defined(OS_MAC) #if !defined(OS_WIN) && !defined(OS_MAC)
WebFontRenderStyle QuerySystemRenderStyle(const std::string& family, WebFontRenderStyle QuerySystemRenderStyle(const std::string& family,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment