• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 COMPONENTS_SEARCH_PROVIDER_LOGOS_LOGO_CACHE_H_
6 #define COMPONENTS_SEARCH_PROVIDER_LOGOS_LOGO_CACHE_H_
7 
8 #include <string>
9 
10 #include "base/callback.h"
11 #include "base/files/file_path.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/threading/thread_checker.h"
17 #include "components/search_provider_logos/logo_common.h"
18 
19 namespace search_provider_logos {
20 
21 // A file-based cache for the search provider's logo. This allows clients to
22 // store and retrieve a logo (of type EncodedLogo) and its associated metadata
23 // (of type LogoMetadata). Metadata can be updated independently from the logo
24 // to handle cases where, e.g. the expiration date changes, but the logo stays
25 // the same. If corruption is detected in the metadata or logo, the cache will
26 // be cleared.
27 //
28 // Note: this class must only be used on a single thread. All methods are
29 // are blocking, so this should not be used on the UI thread.
30 //
31 // The logo and its metadata are stored in files, so they persist even when
32 // Chrome is closed. Once loaded from disk, the metadata is kept in memory to
33 // enable quick retrieval. The logo is not kept around in memory because of its
34 // size.
35 class LogoCache {
36  public:
37   // Constructs a logo cache that stores data in |cache_directory|.
38   // |cache_directory| will be created if it does not already exist.
39   explicit LogoCache(const base::FilePath& cache_directory);
40   virtual ~LogoCache();
41 
42   // Updates the metadata for the cached logo.
43   virtual void UpdateCachedLogoMetadata(const LogoMetadata& metadata);
44 
45   // Returns metadata for the cached logo, or NULL if logo is cached.
46   virtual const LogoMetadata* GetCachedLogoMetadata();
47 
48   // Sets the cached logo and metadata. |logo| may be NULL, in which case the
49   // cached logo and metadata will be cleared.
50   virtual void SetCachedLogo(const EncodedLogo* logo);
51 
52   // Returns the cached logo, or NULL if no logo is cached or the cached logo is
53   // corrupt.
54   virtual scoped_ptr<EncodedLogo> GetCachedLogo();
55 
56  private:
57   FRIEND_TEST_ALL_PREFIXES(LogoCacheSerializationTest, SerializeMetadata);
58   FRIEND_TEST_ALL_PREFIXES(LogoCacheSerializationTest,
59                            DeserializeCorruptMetadata);
60   FRIEND_TEST_ALL_PREFIXES(LogoCacheTest, StoreAndRetrieveMetadata);
61   FRIEND_TEST_ALL_PREFIXES(LogoCacheTest, RetrieveCorruptMetadata);
62   FRIEND_TEST_ALL_PREFIXES(LogoCacheTest, RetrieveCorruptLogo);
63 
64   // Converts string |str| to a LogoMetadata object and returns it. Returns NULL
65   // if |str| cannot be converted.
66   static scoped_ptr<LogoMetadata> LogoMetadataFromString(
67       const std::string& str, int* logo_num_bytes);
68 
69   // Converts |metadata| to a string and stores it in |str|.
70   static void LogoMetadataToString(const LogoMetadata& metadata,
71                                    int logo_num_bytes,
72                                    std::string* str);
73 
74   // Returns the path where the cached logo will be saved.
75   base::FilePath GetLogoPath();
76 
77   // Returns the path where the metadata for the cached logo will be saved.
78   base::FilePath GetMetadataPath();
79 
80   // Updates the in-memory metadata.
81   void UpdateMetadata(scoped_ptr<LogoMetadata> metadata);
82 
83   // If the cached logo's metadata isn't available in memory (i.e.
84   // |metadata_is_valid_| is false), reads it from disk and stores it in
85   // |metadata_|. If no logo is cached, |metadata_| will be updated to NULL.
86   void ReadMetadataIfNeeded();
87 
88   // Writes the metadata for the cached logo to disk.
89   void WriteMetadata();
90 
91   // Writes |metadata_| to the cached metadata file and |encoded_image| to the
92   // cached logo file.
93   void WriteLogo(scoped_refptr<base::RefCountedMemory> encoded_image);
94 
95   // Deletes all the cache files.
96   void DeleteLogoAndMetadata();
97 
98   // Tries to create the cache directory if it does not already exist. Returns
99   // whether the cache directory exists.
100   bool EnsureCacheDirectoryExists();
101 
102   // The directory in which the cached logo and metadata will be saved.
103   base::FilePath cache_directory_;
104 
105   // The metadata describing the cached logo, or NULL if no logo is cached. This
106   // value is meaningful iff |metadata_is_valid_| is true; otherwise, the
107   // metadata must be read from file and |metadata_| will be NULL.
108   // Note: Once read from file, metadata will be stored in memory indefinitely.
109   scoped_ptr<LogoMetadata> metadata_;
110   bool metadata_is_valid_;
111 
112   // The number of bytes in the logo file, as recorded in the metadata file.
113   // Valid iff |metadata_is_valid_|. This is used to verify that the logo file
114   // is complete and corresponds to the current metadata file.
115   int logo_num_bytes_;
116 
117   // Ensure LogoCache is only used on a single thread.
118   base::ThreadChecker thread_checker_;
119 
120   DISALLOW_COPY_AND_ASSIGN(LogoCache);
121 };
122 
123 }  // namespace search_provider_logos
124 
125 #endif  // COMPONENTS_SEARCH_PROVIDER_LOGOS_LOGO_CACHE_H_
126