blob: 72354133823410cbe70687c5676d7326fdbd09ea [file] [log] [blame]
[email protected]354de9e2014-08-07 03:27:191// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_FONT_FAMILY_CACHE_H_
6#define CHROME_BROWSER_FONT_FAMILY_CACHE_H_
7
Jan Wilken Dörriead587c32021-03-11 14:09:278#include <string>
brettw84cff3f2017-06-29 18:26:509#include <unordered_map>
10
[email protected]354de9e2014-08-07 03:27:1911#include "base/gtest_prod_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5212#include "base/memory/raw_ptr.h"
[email protected]354de9e2014-08-07 03:27:1913#include "base/supports_user_data.h"
Brett Wilson21cf626a2017-09-07 00:30:2014#include "chrome/browser/font_pref_change_notifier.h"
Gyuyoung Kim1ac4ca782020-09-11 03:32:5115#include "third_party/blink/public/common/web_preferences/web_preferences.h"
[email protected]354de9e2014-08-07 03:27:1916
17class PrefService;
18class Profile;
19
20FORWARD_DECLARE_TEST(FontFamilyCacheTest, Caching);
21
22// Caches font family preferences associated with a PrefService. This class
23// relies on the assumption that each concatenation of map_name + '.' + script
24// is a unique string. It also relies on the assumption that the (const char*)
brettw84cff3f2017-06-29 18:26:5025// keys used in both inner and outer maps are compile time constants.
Erik Chen8be820612017-08-29 23:38:1826// This class caches the strings necessary to update
Gyuyoung Kim1ac4ca782020-09-11 03:32:5127// "blink::web_pref::ScriptFontFamilyMap". This is necessary since Chrome
28// attempts to update blink::web_pref::ScriptFontFamilyMap 20000 times at
29// startup. See https://crbug.com/308095.
Evan Stadecf0da232019-10-03 15:25:2130class FontFamilyCache : public base::SupportsUserData::Data {
[email protected]354de9e2014-08-07 03:27:1931 public:
32 explicit FontFamilyCache(Profile* profile);
Peter Boström53c6c5952021-09-17 09:41:2633
34 FontFamilyCache(const FontFamilyCache&) = delete;
35 FontFamilyCache& operator=(const FontFamilyCache&) = delete;
36
Daniel Chenga542fca2014-10-21 09:51:2937 ~FontFamilyCache() override;
[email protected]354de9e2014-08-07 03:27:1938
39 // Gets or creates the relevant FontFamilyCache, and then fills |map|.
40 static void FillFontFamilyMap(Profile* profile,
41 const char* map_name,
Gyuyoung Kim1ac4ca782020-09-11 03:32:5142 blink::web_pref::ScriptFontFamilyMap* map);
[email protected]354de9e2014-08-07 03:27:1943
44 // Fills |map| with font family preferences.
45 void FillFontFamilyMap(const char* map_name,
Gyuyoung Kim1ac4ca782020-09-11 03:32:5146 blink::web_pref::ScriptFontFamilyMap* map);
[email protected]354de9e2014-08-07 03:27:1947
48 protected:
49 // Exposed and virtual for testing.
50 // Fetches the font without checking the cache.
Jan Wilken Dörrief27844b2021-03-11 23:18:4851 virtual std::u16string FetchFont(const char* script, const char* map_name);
[email protected]354de9e2014-08-07 03:27:1952
53 private:
54 FRIEND_TEST_ALL_PREFIXES(::FontFamilyCacheTest, Caching);
55
56 // Map from script to font.
57 // Key comparison uses pointer equality.
Jan Wilken Dörrief27844b2021-03-11 23:18:4858 using ScriptFontMap = std::unordered_map<const char*, std::u16string>;
[email protected]354de9e2014-08-07 03:27:1959
60 // Map from font family to ScriptFontMap.
61 // Key comparison uses pointer equality.
brettw84cff3f2017-06-29 18:26:5062 using FontFamilyMap = std::unordered_map<const char*, ScriptFontMap>;
[email protected]354de9e2014-08-07 03:27:1963
64 // Checks the cache for the font. If not present, fetches the font and stores
65 // the result in the cache.
66 // This method needs to be very fast, because it's called ~20,000 times on a
67 // fresh launch with an empty profile. It's important to avoid unnecessary
68 // object construction, hence the heavy use of const char* and the minimal use
69 // of std::string.
70 // |script| and |map_name| must be compile time constants. Two behaviors rely
71 // on this: key comparison uses pointer equality, and keys must outlive the
brettw84cff3f2017-06-29 18:26:5072 // maps.
Jan Wilken Dörrief27844b2021-03-11 23:18:4873 std::u16string FetchAndCacheFont(const char* script, const char* map_name);
[email protected]354de9e2014-08-07 03:27:1974
75 // Called when font family preferences changed.
76 // Invalidates the cached entry, and removes the relevant observer.
77 // Note: It is safe to remove the observer from the pref change callback.
78 void OnPrefsChanged(const std::string& pref_name);
79
[email protected]354de9e2014-08-07 03:27:1980 // Cache of font family preferences.
81 FontFamilyMap font_family_map_;
82
83 // Weak reference.
84 // Note: The lifetime of this object is tied to the lifetime of the
85 // PrefService, so there is no worry about an invalid pointer.
Keishi Hattori0e45c022021-11-27 09:25:5286 raw_ptr<const PrefService> prefs_;
[email protected]354de9e2014-08-07 03:27:1987
Evan Stadecf0da232019-10-03 15:25:2188 // Reacts to profile font changes. |font_change_registrar_| will be
89 // automatically unregistered when the FontPrefChangeNotifier is destroyed as
90 // part of Profile destruction, thus ensuring safe unregistration even though
91 // |this| is destroyed after the Profile destructor completes as part of
92 // Profile's super class destructor ~base::SupportsUserData.
Brett Wilson21cf626a2017-09-07 00:30:2093 FontPrefChangeNotifier::Registrar font_change_registrar_;
[email protected]354de9e2014-08-07 03:27:1994};
95
96#endif // CHROME_BROWSER_FONT_FAMILY_CACHE_H_