blob: 36577f32fba3d6eeb2c038e6173cc1675c1b7586 [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
brettw84cff3f2017-06-29 18:26:508#include <unordered_map>
9
[email protected]354de9e2014-08-07 03:27:1910#include "base/gtest_prod_util.h"
avi6846aef2015-12-26 01:09:3811#include "base/macros.h"
[email protected]354de9e2014-08-07 03:27:1912#include "base/strings/string16.h"
13#include "base/supports_user_data.h"
Brett Wilson21cf626a2017-09-07 00:30:2014#include "chrome/browser/font_pref_change_notifier.h"
[email protected]354de9e2014-08-07 03:27:1915#include "content/public/browser/notification_observer.h"
16#include "content/public/browser/notification_registrar.h"
17#include "content/public/common/web_preferences.h"
18
19class PrefService;
20class Profile;
21
22FORWARD_DECLARE_TEST(FontFamilyCacheTest, Caching);
23
24// Caches font family preferences associated with a PrefService. This class
25// relies on the assumption that each concatenation of map_name + '.' + script
26// is a unique string. It also relies on the assumption that the (const char*)
brettw84cff3f2017-06-29 18:26:5027// keys used in both inner and outer maps are compile time constants.
Erik Chen8be820612017-08-29 23:38:1828// This class caches the strings necessary to update
29// "content::ScriptFontFamilyMap". This is necessary since Chrome attempts to
30// update content::ScriptFontFamilyMap 20000 times at startup. See
31// https://crbug.com/308095.
[email protected]354de9e2014-08-07 03:27:1932class FontFamilyCache : public base::SupportsUserData::Data,
33 public content::NotificationObserver {
34 public:
35 explicit FontFamilyCache(Profile* profile);
Daniel Chenga542fca2014-10-21 09:51:2936 ~FontFamilyCache() override;
[email protected]354de9e2014-08-07 03:27:1937
38 // Gets or creates the relevant FontFamilyCache, and then fills |map|.
39 static void FillFontFamilyMap(Profile* profile,
40 const char* map_name,
41 content::ScriptFontFamilyMap* map);
42
43 // Fills |map| with font family preferences.
44 void FillFontFamilyMap(const char* map_name,
45 content::ScriptFontFamilyMap* map);
46
47 protected:
48 // Exposed and virtual for testing.
49 // Fetches the font without checking the cache.
50 virtual base::string16 FetchFont(const char* script, const char* map_name);
51
52 private:
53 FRIEND_TEST_ALL_PREFIXES(::FontFamilyCacheTest, Caching);
54
55 // Map from script to font.
56 // Key comparison uses pointer equality.
brettw84cff3f2017-06-29 18:26:5057 using ScriptFontMap = std::unordered_map<const char*, base::string16>;
[email protected]354de9e2014-08-07 03:27:1958
59 // Map from font family to ScriptFontMap.
60 // Key comparison uses pointer equality.
brettw84cff3f2017-06-29 18:26:5061 using FontFamilyMap = std::unordered_map<const char*, ScriptFontMap>;
[email protected]354de9e2014-08-07 03:27:1962
63 // Checks the cache for the font. If not present, fetches the font and stores
64 // the result in the cache.
65 // This method needs to be very fast, because it's called ~20,000 times on a
66 // fresh launch with an empty profile. It's important to avoid unnecessary
67 // object construction, hence the heavy use of const char* and the minimal use
68 // of std::string.
69 // |script| and |map_name| must be compile time constants. Two behaviors rely
70 // on this: key comparison uses pointer equality, and keys must outlive the
brettw84cff3f2017-06-29 18:26:5071 // maps.
[email protected]354de9e2014-08-07 03:27:1972 base::string16 FetchAndCacheFont(const char* script, const char* map_name);
73
74 // Called when font family preferences changed.
75 // Invalidates the cached entry, and removes the relevant observer.
76 // Note: It is safe to remove the observer from the pref change callback.
77 void OnPrefsChanged(const std::string& pref_name);
78
79 // content::NotificationObserver override.
80 // Called when the profile is being destructed.
Daniel Chenga542fca2014-10-21 09:51:2981 void Observe(int type,
82 const content::NotificationSource& source,
83 const content::NotificationDetails& details) override;
[email protected]354de9e2014-08-07 03:27:1984
85 // Cache of font family preferences.
86 FontFamilyMap font_family_map_;
87
88 // Weak reference.
89 // Note: The lifetime of this object is tied to the lifetime of the
90 // PrefService, so there is no worry about an invalid pointer.
91 const PrefService* prefs_;
92
Brett Wilson21cf626a2017-09-07 00:30:2093 // Reacts to profile font changes.
94 FontPrefChangeNotifier::Registrar font_change_registrar_;
[email protected]354de9e2014-08-07 03:27:1995
96 // Listens for profile destruction.
97 content::NotificationRegistrar notification_registrar_;
98
99 DISALLOW_COPY_AND_ASSIGN(FontFamilyCache);
100};
101
102#endif // CHROME_BROWSER_FONT_FAMILY_CACHE_H_