[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / font_family_cache.h
1 // Copyright 2014 The Chromium Authors
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
8 #include <string>
9 #include <unordered_map>
10
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/supports_user_data.h"
14 #include "chrome/browser/font_pref_change_notifier.h"
15 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
16
17 class PrefService;
18 class Profile;
19
20 FORWARD_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*)
25 // keys used in both inner and outer maps are compile time constants.
26 // This class caches the strings necessary to update
27 // "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.
30 class FontFamilyCache : public base::SupportsUserData::Data {
31  public:
32   explicit FontFamilyCache(Profile* profile);
33
34   FontFamilyCache(const FontFamilyCache&) = delete;
35   FontFamilyCache& operator=(const FontFamilyCache&) = delete;
36
37   ~FontFamilyCache() override;
38
39   // Gets or creates the relevant FontFamilyCache, and then fills |map|.
40   static void FillFontFamilyMap(Profile* profile,
41                                 const char* map_name,
42                                 blink::web_pref::ScriptFontFamilyMap* map);
43
44   // Fills |map| with font family preferences.
45   void FillFontFamilyMap(const char* map_name,
46                          blink::web_pref::ScriptFontFamilyMap* map);
47
48  protected:
49   // Exposed and virtual for testing.
50   // Fetches the font without checking the cache.
51   virtual std::u16string FetchFont(const char* script, const char* map_name);
52
53  private:
54   FRIEND_TEST_ALL_PREFIXES(::FontFamilyCacheTest, Caching);
55
56   // Map from script to font.
57   // Key comparison uses pointer equality.
58   using ScriptFontMap = std::unordered_map<const char*, std::u16string>;
59
60   // Map from font family to ScriptFontMap.
61   // Key comparison uses pointer equality.
62   using FontFamilyMap = std::unordered_map<const char*, ScriptFontMap>;
63
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
72   // maps.
73   std::u16string FetchAndCacheFont(const char* script, const char* map_name);
74
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
80   // 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.
86   raw_ptr<const PrefService, AcrossTasksDanglingUntriaged> prefs_;
87
88   // 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.
93   FontPrefChangeNotifier::Registrar font_change_registrar_;
94 };
95
96 #endif  // CHROME_BROWSER_FONT_FAMILY_CACHE_H_