summaryrefslogtreecommitdiffstats
path: root/chrome/browser/thumbnail_store.h
blob: 8b5fde885defd9567d892a61ace5b5440c0c55e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_THUMBNAIL_STORE_H_
#define CHROME_BROWSER_THUMBNAIL_STORE_H_

#include <map>
#include <string>
#include <vector>

#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/timer.h"
#include "chrome/browser/cancelable_request.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/url_database.h"  // For DBCloseScoper
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/ref_counted_util.h"
#include "chrome/common/sqlite_compiled_statement.h"
#include "chrome/common/thumbnail_score.h"
#include "testing/gtest/include/gtest/gtest_prod.h"

class DictionaryValue;
class GURL;
class HistoryService;
class Profile;
class SkBitmap;
struct sqlite3;
namespace base {
class Time;
}

// This storage interface provides storage for the thumbnails used
// by the new_tab_ui.
class ThumbnailStore : public base::RefCountedThreadSafe<ThumbnailStore>,
                       public NotificationObserver {
 public:
  ThumbnailStore();
  ~ThumbnailStore();

  // Must be called after creation but before other methods are called.
  void Init(const FilePath& db_name,      // The location of the database.
            Profile* profile);            // To get to the HistoryService.

  // Stores the given thumbnail and score with the associated url in the cache.
  bool SetPageThumbnail(const GURL& url,
                        const SkBitmap& thumbnail,
                        const ThumbnailScore& score,
                        bool fetch_redirects);  // for debugging

  // Sets *data to point to the thumbnail for the given url.
  // Returns false if no thumbnail available.
  bool GetPageThumbnail(const GURL& url, RefCountedBytes** data);

  // This is called when the browser is shutting down to write all dirty cache
  // entries to disk.
  void Shutdown();

 private:
  FRIEND_TEST(ThumbnailStoreTest, RetrieveFromCache);
  FRIEND_TEST(ThumbnailStoreTest, RetrieveFromDisk);
  FRIEND_TEST(ThumbnailStoreTest, UpdateThumbnail);
  FRIEND_TEST(ThumbnailStoreTest, FollowRedirects);
  friend class ThumbnailStoreTest;

  struct CacheEntry {
    scoped_refptr<RefCountedBytes> data_;
    ThumbnailScore score_;
    bool dirty_;

    CacheEntry() : data_(NULL), score_(ThumbnailScore()), dirty_(false) {}
    CacheEntry(RefCountedBytes* data,
               const ThumbnailScore& score,
               bool dirty)
        : data_(data),
          score_(score),
          dirty_(dirty) {}
  };

  // Data structure used to store thumbnail data in memory.
  typedef std::map<GURL, CacheEntry> Cache;

  // NotificationObserver implementation
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  // Most visited URLs and their redirect lists -------------------------------

  // Query the HistoryService for the most visited URLs and the most recent
  // redirect lists for those URLs.  This happens in the background and the
  // callback is OnURLDataAvailable.
  void UpdateURLData();

  // The callback for UpdateURLData.
  void OnURLDataAvailable(std::vector<GURL>* urls,
                          history::RedirectMap* redirects);

  // The callback for the redirects request to the HistoryService made in
  // SetPageThumbnail. If we have a redirect chain A -> B -> C, this function
  // will be called with url=C and redirects = {B -> A}.  This information gets
  // inserted into the RedirectMap as A => {B -> C}.
  void OnRedirectsForURLAvailable(HistoryService::Handle handle,
                                  GURL url,
                                  bool success,
                                  history::RedirectList* redirects);

  // Remove stale data --------------------------------------------------------

  // Remove entries from the in memory thumbnail cache cache that have been
  // blacklisted or are not in the top kMaxCacheSize visited sites.  Call
  // CommitCacheToDB on the file_thread to remove these entries from disk and
  // to also write new entries to disk.
  void CleanCacheData();

  // Disk operations ----------------------------------------------------------

  // Initialize |db_| to the database specified in |db_name|.  If |cb_loop|
  // is non-null, calls GetAllThumbnailsFromDisk.  Done on the file_thread.
  void InitializeFromDB(const FilePath& db_name, MessageLoop* cb_loop);

  // Read all thumbnail data from the specified FilePath into a Cache object.
  // Done on the file_thread and returns to OnDiskDataAvailable on the thread
  // owning the specified MessageLoop.
  void GetAllThumbnailsFromDisk(MessageLoop* cb_loop);

  // Once thumbnail data from the disk is available from the file_thread,
  // this function is invoked on the main thread.  It takes ownership of the
  // Cache* passed in and retains this Cache* for the lifetime of the object.
  void OnDiskDataAvailable(Cache* cache);

  // Delete each URL in the given vector from the DB and write all dirty
  // cache entries to the DB.
  void CommitCacheToDB(
      scoped_refptr<RefCountedVector<GURL> > urls_to_delete,
      Cache* data) const;

  // Decide whether to store data ---------------------------------------------

  bool ShouldStoreThumbnailForURL(const GURL& url) const;

  bool IsURLBlacklisted(const GURL& url) const;

  std::wstring GetDictionaryKeyForURL(const std::string& url) const;

  // Returns true if url is in most_visited_urls_.
  bool IsPopular(const GURL& url) const;



  // Member variables ---------------------------------------------------------

  // The Cache maintained by the object.
  scoped_ptr<Cache> cache_;

  // The database holding the thumbnails on disk.
  sqlite3* db_;
  SqliteStatementCache* statement_cache_;
  history::DBCloseScoper close_scoper_;

  // We hold a reference to the history service to query for most visited URLs
  // and redirect information.
  scoped_refptr<HistoryService> hs_;

  // A list of the most_visited_urls_ refreshed every 30mins from the
  // HistoryService.
  scoped_ptr<std::vector<GURL> > most_visited_urls_;

  // A pointer to the persistent URL blacklist for this profile.
  const DictionaryValue* url_blacklist_;

  // A map pairing the URL that a user typed to a list of URLs it was
  // redirected to. Ex:
  // google.com => { http://www.google.com/ }
  scoped_ptr<history::RedirectMap> redirect_urls_;

  // Timer on which UpdateURLData runs.
  base::OneShotTimer<ThumbnailStore> timer_;
  int seconds_to_next_update_;

  // Consumer for queries to the HistoryService.
  CancelableRequestConsumer consumer_;

  // Registrar to get notified when the history is cleared.
  NotificationRegistrar registrar_;

  static const unsigned int kMaxCacheSize = 24;
  static const int64 kInitialUpdateIntervalSecs = 180;
  static const int64 kMaxUpdateIntervalSecs = 3600;

  DISALLOW_COPY_AND_ASSIGN(ThumbnailStore);
};

#endif  // CHROME_BROWSER_THUMBNAIL_STORE_H_