15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef CHROME_BROWSER_FONT_FAMILY_CACHE_H_
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define CHROME_BROWSER_FONT_FAMILY_CACHE_H_
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/containers/hash_tables.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/gtest_prod_util.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string16.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/supports_user_data.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_observer.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/notification_registrar.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/common/web_preferences.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PrefService;
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class Profile;
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)FORWARD_DECLARE_TEST(FontFamilyCacheTest, Caching);
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Caches font family preferences associated with a PrefService. This class
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// relies on the assumption that each concatenation of map_name + '.' + script
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// is a unique string. It also relies on the assumption that the (const char*)
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// keys used in both inner and outer hash_maps are compile time constants.
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FontFamilyCache : public base::SupportsUserData::Data,
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        public content::NotificationObserver {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit FontFamilyCache(Profile* profile);
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FontFamilyCache();
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Gets or creates the relevant FontFamilyCache, and then fills |map|.
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void FillFontFamilyMap(Profile* profile,
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                const char* map_name,
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                content::ScriptFontFamilyMap* map);
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Fills |map| with font family preferences.
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void FillFontFamilyMap(const char* map_name,
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         content::ScriptFontFamilyMap* map);
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected:
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Exposed and virtual for testing.
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Fetches the font without checking the cache.
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual base::string16 FetchFont(const char* script, const char* map_name);
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(::FontFamilyCacheTest, Caching);
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Map from script to font.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Key comparison uses pointer equality.
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef base::hash_map<const char*, base::string16> ScriptFontMap;
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Map from font family to ScriptFontMap.
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Key comparison uses pointer equality.
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typedef base::hash_map<const char*, ScriptFontMap> FontFamilyMap;
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Checks the cache for the font. If not present, fetches the font and stores
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the result in the cache.
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // This method needs to be very fast, because it's called ~20,000 times on a
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // fresh launch with an empty profile. It's important to avoid unnecessary
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // object construction, hence the heavy use of const char* and the minimal use
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // of std::string.
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |script| and |map_name| must be compile time constants. Two behaviors rely
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // on this: key comparison uses pointer equality, and keys must outlive the
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // hash_maps.
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::string16 FetchAndCacheFont(const char* script, const char* map_name);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Called when font family preferences changed.
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Invalidates the cached entry, and removes the relevant observer.
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Note: It is safe to remove the observer from the pref change callback.
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnPrefsChanged(const std::string& pref_name);
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // content::NotificationObserver override.
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Called when the profile is being destructed.
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Observe(int type,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationSource& source,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Cache of font family preferences.
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontFamilyMap font_family_map_;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Weak reference.
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Note: The lifetime of this object is tied to the lifetime of the
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // PrefService, so there is no worry about an invalid pointer.
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const PrefService* prefs_;
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Reacts to profile changes.
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PrefChangeRegistrar profile_pref_registrar_;
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Listens for profile destruction.
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::NotificationRegistrar notification_registrar_;
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FontFamilyCache);
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif  // CHROME_BROWSER_FONT_FAMILY_CACHE_H_
97