Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Side by Side Diff: chrome/browser/android/thumbnail_cache.h

Issue 262543002: android: add ThumbnailCache (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@codec
Patch Set: renamed ThumbnailCacheCore to ThumbnailCache Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 CHROME_BROWSER_ANDROID_THUMBNAIL_CACHE_H_
6 #define CHROME_BROWSER_ANDROID_THUMBNAIL_CACHE_H_
7
8 #include <list>
9 #include <set>
10 #include <string>
11
12 #include "base/bind.h"
13 #include "base/containers/hash_tables.h"
14 #include "base/files/file_path.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/threading/thread.h"
17 #include "base/time/time.h"
18 #include "content/public/browser/android/ui_resource_listener.h"
19 #include "content/public/browser/android/ui_resource_provider.h"
20 #include "net/base/linked_hash_map.h"
21 #include "skia/ext/refptr.h"
22 #include "third_party/skia/include/core/SkBitmap.h"
23 #include "ui/gfx/geometry/point.h"
24 #include "ui/gfx/geometry/size.h"
25 #include "ui/gfx/geometry/size_f.h"
26 #include "url/gurl.h"
27
28 class SkBitmap;
29 class TabThumbnailProvider;
30
31 namespace base {
32 class File;
33 class Time;
34 }
35
36 namespace content {
37 class ContentViewCore;
38 class UIResourceProvider;
39 }
40
41 typedef int TabId;
42 typedef std::list<TabId> TabIdList;
43
44 class ThumbnailChangeListener {
45 public:
46 virtual void OnThumbnailChanged(TabId tab_id, bool upgrade) = 0;
47 virtual void OnUIResourceUpdated(TabId tab_id,
48 cc::UIResourceId ui_resource_id,
49 gfx::Size content_size,
50 gfx::SizeF scaled_thumbnail_size) = 0;
51 };
52
53 class ThumbnailCache : public content::UIResourceListener {
54 private:
55 class Thumbnail : public base::RefCountedThreadSafe<Thumbnail> {
56 public:
57 enum ThumbnailFormat { DECOMPRESSED, COMPRESSED };
58
59 // This constructs a placeholder for the thumbnail. The content is filled
60 // by calling ReadThumbnailFromFile.
61 Thumbnail(TabId tab_id, content::UIResourceProvider* ui_resource_provider);
62
63 Thumbnail(TabId tab_id,
64 SkBitmap bitmap,
65 float scale,
66 content::UIResourceProvider* ui_resource_provider);
67 Thumbnail(const Thumbnail& thumbnail);
68 void CleanupThumbnail();
69 bool AttemptToScheduleRebuildFromData();
70 void CleanupCPUData(bool force);
71 bool RebuildThumbnail();
72 bool CompressionRequired() const;
73 bool DataWriteRequired() const;
74 bool HasCompressedRawData() const;
75 bool IsValid() const;
76
77 // Returns the size of the content represented by this thumbnail.
78 gfx::Size GetContentSize() const;
79
80 TabId tab_id() const { return tab_id_; }
81 cc::UIResourceId ui_resource_id() const { return ui_resource_id_; }
82
83 // The ratio of the size of the thumbnail to the content size.
84 float scale() const { return scale_; }
85
86 // Returns the size of the data (pixels) held by this thumbnail. Can be the
87 // size of the uncompressed or compressed data.
88 gfx::Size data_size() const { return data_size_; }
89
90 virtual bool is_approximation() const { return false; }
91
92 // Called on the compression thread.
93 void Compress();
94 // Called on the disk thread. Returns true if writing was successful.
95 bool WriteThumbnailToFile(base::File& file);
96 // Called on the disk thread. Returns true if reading was successful.
97 bool ReadThumbnailFromFile(base::File& file);
98
99 // We invalidate the thumbnail content if a read/write/compress has failed.
100 void Invalidate();
101
102 SkBitmap raw_data() { return raw_data_; }
103
104 protected:
105 friend class base::RefCountedThreadSafe<Thumbnail>;
106 ~Thumbnail();
107
108 private:
109 void SetRawThumbnailData(SkBitmap bitmap);
110 void SetCompressedThumbnailData(skia::RefPtr<SkPixelRef> compressed_data,
111 gfx::Size scaled_content_size);
112 bool CleanupRequired();
113
114 TabId tab_id_;
115 SkBitmap raw_data_;
116 float scale_;
117 content::UIResourceProvider* ui_resource_provider_;
118 cc::UIResourceId ui_resource_id_;
119 skia::RefPtr<SkPixelRef> compressed_data_;
120 gfx::Size data_size_;
121 gfx::Size scaled_content_size_;
122 ThumbnailFormat format_;
123 bool rebuild_pending_;
124 bool data_write_pending_;
125 bool from_stream_;
126 };
127
128 class ApproxThumbnail : public Thumbnail {
129 public:
130 ApproxThumbnail(TabId tab_id,
131 SkBitmap bitmap,
132 float scale,
133 content::UIResourceProvider* ui_resource_provider);
134
135 virtual bool is_approximation() const OVERRIDE { return true; }
136 };
137
138 class ThumbnailBitmap {
139 public:
140 ThumbnailBitmap();
141 ThumbnailBitmap(SkBitmap bitmap, float scale);
142 bool IsValid() const;
143 SkBitmap bitmap() const { return bitmap_; }
144 float scale() const { return scale_; }
145 ThumbnailBitmap CreateApproximation() const;
146
147 private:
148 SkBitmap bitmap_;
149 float scale_;
150 };
151
152 class ThumbnailMetaData {
153 public:
154 ThumbnailMetaData();
155 ThumbnailMetaData(const base::Time& current_time, const GURL& url);
156 const GURL& url() const { return url_; }
157 base::Time capture_time() const { return capture_time_; }
158
159 private:
160 base::Time capture_time_;
161 GURL url_;
162 };
163
164 class TabReadbackRequest : public base::RefCounted<TabReadbackRequest> {
165 public:
166 TabReadbackRequest(
167 TabId tab_id,
168 content::ContentViewCore* content_view_core,
169 float thumbnail_scale,
170 base::Callback<void(int, const ThumbnailBitmap&)> end_callback);
171
172 bool drop_after_readback() const { return drop_after_readback_; }
173
174 void Run();
175 void OnFinishGetTabThumbnailBitmap(bool success, const SkBitmap& bitmap);
176 void SetDropAfterReadback(bool flag) { drop_after_readback_ = flag; }
177
178 private:
179 TabId tab_id_;
180 content::ContentViewCore* content_view_core_;
181 const float thumbnail_scale_;
182 base::Callback<void(int, const ThumbnailBitmap&)> end_callback_;
183 bool drop_after_readback_;
184
185 base::WeakPtrFactory<TabReadbackRequest> weak_factory_;
186 };
187
188 template <class Key, class Value>
189 class LRUExpiringCache {
190 private:
191 typedef linked_hash_map<Key, Value> LinkedHashMap;
192
193 public:
194 typedef typename LinkedHashMap::iterator iterator;
195 typedef typename LinkedHashMap::const_iterator const_iterator;
196
197 explicit LRUExpiringCache(size_t max_cache_size)
198 : max_cache_size_(max_cache_size) {}
199
200 void Put(const Key& key, const Value& value) {
201 map_[key] = value;
202 EvictIfFull();
203 }
204
205 Value Get(const Key& key) {
206 iterator iter = map_.find(key);
207 if (iter != map_.end())
208 return iter->second;
209 return Value();
210 }
211
212 bool Contains(const Key& key) const {
213 const_iterator iter = map_.find(key);
214 return iter != map_.end();
215 }
216
217 Value Remove(const Key& key) {
218 Value val = Get(key);
219 map_.erase(key);
220 return val;
221 }
222
223 iterator begin() { return map_.begin(); }
224 iterator end() { return map_.end(); }
225 size_t MaximumCacheSize() const { return max_cache_size_; }
226 size_t size() const { return map_.size(); }
227
228 private:
229 void EvictIfFull() {
230 while (map_.size() > max_cache_size_) {
231 iterator it = map_.begin();
232 map_.erase(it);
233 }
234 }
235
236 size_t max_cache_size_;
237 LinkedHashMap map_;
238 };
239
240 typedef LRUExpiringCache<TabId, scoped_refptr<Thumbnail> >
241 ExpiringThumbnailCache;
242 typedef std::set<ThumbnailChangeListener*> ThumbnailChangeListenerSet;
243 typedef base::hash_map<TabId, scoped_refptr<TabReadbackRequest> >
244 TabReadbackRequestMap;
245 typedef base::hash_map<TabId, ThumbnailMetaData> ThumbnailMetaDataMap;
246 typedef std::list<scoped_refptr<Thumbnail> > ThumbnailQueue;
247
248 public:
249 ThumbnailCache(const std::string& disk_cache_path_str,
250 size_t default_cache_size,
251 size_t approximation_cache_size,
252 size_t compression_queue_max_size,
253 size_t write_queue_max_size,
254 bool use_approximation_thumbnails,
255 float thumbnail_scale);
256
257 ~ThumbnailCache();
258
259 void AddThumbnailChangeListener(ThumbnailChangeListener* listener);
260 void RemoveThumbnailChangeListener(ThumbnailChangeListener* listener);
261 void CacheTabThumbnail(const TabThumbnailProvider* tab);
262 void CacheTabThumbnailWithBitmap(const TabThumbnailProvider* tab,
263 const SkBitmap& bitmap,
264 float thumbnail_scale);
265 void HandleLowMemory(bool consider_gpu_memory);
266 void InvalidateIfChanged(const TabThumbnailProvider* tab);
267 void RemoveThumbnailsAndScheduleReload();
268 void CacheInTab(TabId tab_id);
269 void Remove(TabId tab_id);
270 void RemoveFromDiskAtAndAboveId(TabId min_id);
271 void RemoveFromDisk(TabId tab_id);
272 void UpdateVisibleIds(const TabIdList& last_visible_ids);
273 void ThumbnailRequested(TabId tab_id);
274 void SetUIResourceProvider(content::UIResourceProvider* ui_resource_provider);
275
276 // Implements content::UIResourceListener.
277 virtual void OnUIResourcesAreInvalid() OVERRIDE;
278 virtual void OnRecreateUIResources() OVERRIDE;
279
280 private:
281 // The task to run
282 static void CompressionTask(scoped_refptr<Thumbnail> thumbnail);
283
284 void PostCompressionTask(scoped_refptr<Thumbnail> thumbnail);
285
286 static void WriteTask(const base::FilePath& file_path,
287 scoped_refptr<Thumbnail> thumbnail);
288
289 void PostWriteTask(scoped_refptr<Thumbnail> thumbnail);
290
291 static void ReadTask(const base::FilePath& file_path,
292 scoped_refptr<Thumbnail> thumbnail);
293
294 void PostReadTask(scoped_refptr<Thumbnail> thumbnail);
295
296 static void RemoveFromDiskTask(const base::FilePath& file_path);
297 static void RemoveFromDiskAtAndAboveIdTask(const base::FilePath& dir_path,
298 TabId min_id);
299 scoped_refptr<Thumbnail> GetThumbnail(TabId tab_id);
300 scoped_refptr<Thumbnail> GetThumbnail(TabId tab_id, bool cache_in_if_missing);
301 void EndCacheTabThumbnail(TabId tab_id, const ThumbnailBitmap& bitmap);
302 bool CanReadTabContent(const TabThumbnailProvider* tab);
303 void PutThumbnail(TabId tab_id, const ThumbnailBitmap& thumbnail_bitmap);
304 void PutThumbnail(TabId tab_id,
305 const ThumbnailBitmap& thumbnail_bitmap,
306 scoped_refptr<Thumbnail> thumbnail);
307 bool CheckAndUpdateThumbnailMetaData(const TabThumbnailProvider* tab,
308 bool is_native_page);
309 void RemoveFromCache(ExpiringThumbnailCache& cache,
310 const std::list<TabId>& tab_ids);
311 size_t HandleLowMemoryOnQueue(ThumbnailQueue& queue,
312 bool consider_gpu_memory);
313 void RemoveFromQueues(TabId tab_id);
314 bool WriteThumbnailIfNecessary(scoped_refptr<Thumbnail> thumbnail);
315 bool CompressThumbnailIfNecessary(scoped_refptr<Thumbnail> thumbnail);
316 void WriteNextThumbnail();
317 bool RemoveDuplicateIdsFromQueueHelper(ThumbnailQueue& queue,
318 scoped_refptr<Thumbnail> thumbnail);
319 void ReadNextThumbnail(TabId id);
320 void ReadNextThumbnail();
321 void CompressNextThumbnail();
322 void RebuildThumbnail(scoped_refptr<Thumbnail> thumbnail,
323 bool force_cleanup_cpu_data);
324 bool ShouldCleanupThumbnail(scoped_refptr<Thumbnail> thumbnail,
325 const ExpiringThumbnailCache* forced_source);
326 void CleanupThumbnail(scoped_refptr<Thumbnail> thumbnail);
327 void CleanupThumbnail(scoped_refptr<Thumbnail> thumbnail,
328 const ExpiringThumbnailCache* forced_source);
329 void NotifyListenersOfThumbnailChange(TabId tab_id, bool upgrade);
330 void NotifyListenersOfUIResourceUpdate(TabId tab_id);
331 base::FilePath GetFilePath(TabId tab_id) const;
332 bool ThumbnailInputFileExists(TabId tab_id) const;
333 void RemoveCorruptThumbnailSource(TabId tab_id);
334 void MakeSpaceForNewItemIfNecessary(TabId tab_id);
335 void RemoveThumbnailFromCache();
336 void AddIdToVisibleIds(TabId tab_id);
337 void CleanupPersistentData();
338
339 base::Time CurrentTime();
340
341 content::UIResourceProvider* ui_resource_provider_;
342 const base::FilePath disk_cache_path_;
343 const size_t compression_queue_max_size_;
344 const size_t write_queue_max_size_;
345
346 ExpiringThumbnailCache cache_;
347 ExpiringThumbnailCache approximation_cache_;
348 const bool use_approximation_thumbnails_;
349
350 // All thumbnails are scaled by this value. This accounts for device's DPI
351 // (dots per inch).
352 const float thumbnail_scale_;
353
354 ThumbnailChangeListenerSet thumbnail_change_listeners_;
355
356 TabReadbackRequestMap pending_thumbnail_readbacks_;
357 ThumbnailMetaDataMap thumbnail_meta_data_;
358
359 ThumbnailQueue compression_queue_;
360 ThumbnailQueue write_queue_;
361 TabIdList read_queue_;
362
363 TabIdList last_visible_ids_;
364 TabIdList visible_ids_;
365
366 base::Thread compression_thread_;
367
368 base::WeakPtrFactory<ThumbnailCache> weak_factory_;
369 };
370
371 #endif // CHROME_BROWSER_ANDROID_THUMBNAIL_CACHE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698