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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/thumbnail_cache.h
diff --git a/chrome/browser/android/thumbnail_cache.h b/chrome/browser/android/thumbnail_cache.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1b45b134bdb1e776596108a8194035d88d2c968
--- /dev/null
+++ b/chrome/browser/android/thumbnail_cache.h
@@ -0,0 +1,371 @@
+// Copyright 2014 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_ANDROID_THUMBNAIL_CACHE_H_
+#define CHROME_BROWSER_ANDROID_THUMBNAIL_CACHE_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+#include "base/bind.h"
+#include "base/containers/hash_tables.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "content/public/browser/android/ui_resource_listener.h"
+#include "content/public/browser/android/ui_resource_provider.h"
+#include "net/base/linked_hash_map.h"
+#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/size_f.h"
+#include "url/gurl.h"
+
+class SkBitmap;
+class TabThumbnailProvider;
+
+namespace base {
+class File;
+class Time;
+}
+
+namespace content {
+class ContentViewCore;
+class UIResourceProvider;
+}
+
+typedef int TabId;
+typedef std::list<TabId> TabIdList;
+
+class ThumbnailChangeListener {
+ public:
+ virtual void OnThumbnailChanged(TabId tab_id, bool upgrade) = 0;
+ virtual void OnUIResourceUpdated(TabId tab_id,
+ cc::UIResourceId ui_resource_id,
+ gfx::Size content_size,
+ gfx::SizeF scaled_thumbnail_size) = 0;
+};
+
+class ThumbnailCache : public content::UIResourceListener {
+ private:
+ class Thumbnail : public base::RefCountedThreadSafe<Thumbnail> {
+ public:
+ enum ThumbnailFormat { DECOMPRESSED, COMPRESSED };
+
+ // This constructs a placeholder for the thumbnail. The content is filled
+ // by calling ReadThumbnailFromFile.
+ Thumbnail(TabId tab_id, content::UIResourceProvider* ui_resource_provider);
+
+ Thumbnail(TabId tab_id,
+ SkBitmap bitmap,
+ float scale,
+ content::UIResourceProvider* ui_resource_provider);
+ Thumbnail(const Thumbnail& thumbnail);
+ void CleanupThumbnail();
+ bool AttemptToScheduleRebuildFromData();
+ void CleanupCPUData(bool force);
+ bool RebuildThumbnail();
+ bool CompressionRequired() const;
+ bool DataWriteRequired() const;
+ bool HasCompressedRawData() const;
+ bool IsValid() const;
+
+ // Returns the size of the content represented by this thumbnail.
+ gfx::Size GetContentSize() const;
+
+ TabId tab_id() const { return tab_id_; }
+ cc::UIResourceId ui_resource_id() const { return ui_resource_id_; }
+
+ // The ratio of the size of the thumbnail to the content size.
+ float scale() const { return scale_; }
+
+ // Returns the size of the data (pixels) held by this thumbnail. Can be the
+ // size of the uncompressed or compressed data.
+ gfx::Size data_size() const { return data_size_; }
+
+ virtual bool is_approximation() const { return false; }
+
+ // Called on the compression thread.
+ void Compress();
+ // Called on the disk thread. Returns true if writing was successful.
+ bool WriteThumbnailToFile(base::File& file);
+ // Called on the disk thread. Returns true if reading was successful.
+ bool ReadThumbnailFromFile(base::File& file);
+
+ // We invalidate the thumbnail content if a read/write/compress has failed.
+ void Invalidate();
+
+ SkBitmap raw_data() { return raw_data_; }
+
+ protected:
+ friend class base::RefCountedThreadSafe<Thumbnail>;
+ ~Thumbnail();
+
+ private:
+ void SetRawThumbnailData(SkBitmap bitmap);
+ void SetCompressedThumbnailData(skia::RefPtr<SkPixelRef> compressed_data,
+ gfx::Size scaled_content_size);
+ bool CleanupRequired();
+
+ TabId tab_id_;
+ SkBitmap raw_data_;
+ float scale_;
+ content::UIResourceProvider* ui_resource_provider_;
+ cc::UIResourceId ui_resource_id_;
+ skia::RefPtr<SkPixelRef> compressed_data_;
+ gfx::Size data_size_;
+ gfx::Size scaled_content_size_;
+ ThumbnailFormat format_;
+ bool rebuild_pending_;
+ bool data_write_pending_;
+ bool from_stream_;
+ };
+
+ class ApproxThumbnail : public Thumbnail {
+ public:
+ ApproxThumbnail(TabId tab_id,
+ SkBitmap bitmap,
+ float scale,
+ content::UIResourceProvider* ui_resource_provider);
+
+ virtual bool is_approximation() const OVERRIDE { return true; }
+ };
+
+ class ThumbnailBitmap {
+ public:
+ ThumbnailBitmap();
+ ThumbnailBitmap(SkBitmap bitmap, float scale);
+ bool IsValid() const;
+ SkBitmap bitmap() const { return bitmap_; }
+ float scale() const { return scale_; }
+ ThumbnailBitmap CreateApproximation() const;
+
+ private:
+ SkBitmap bitmap_;
+ float scale_;
+ };
+
+ class ThumbnailMetaData {
+ public:
+ ThumbnailMetaData();
+ ThumbnailMetaData(const base::Time& current_time, const GURL& url);
+ const GURL& url() const { return url_; }
+ base::Time capture_time() const { return capture_time_; }
+
+ private:
+ base::Time capture_time_;
+ GURL url_;
+ };
+
+ class TabReadbackRequest : public base::RefCounted<TabReadbackRequest> {
+ public:
+ TabReadbackRequest(
+ TabId tab_id,
+ content::ContentViewCore* content_view_core,
+ float thumbnail_scale,
+ base::Callback<void(int, const ThumbnailBitmap&)> end_callback);
+
+ bool drop_after_readback() const { return drop_after_readback_; }
+
+ void Run();
+ void OnFinishGetTabThumbnailBitmap(bool success, const SkBitmap& bitmap);
+ void SetDropAfterReadback(bool flag) { drop_after_readback_ = flag; }
+
+ private:
+ TabId tab_id_;
+ content::ContentViewCore* content_view_core_;
+ const float thumbnail_scale_;
+ base::Callback<void(int, const ThumbnailBitmap&)> end_callback_;
+ bool drop_after_readback_;
+
+ base::WeakPtrFactory<TabReadbackRequest> weak_factory_;
+ };
+
+ template <class Key, class Value>
+ class LRUExpiringCache {
+ private:
+ typedef linked_hash_map<Key, Value> LinkedHashMap;
+
+ public:
+ typedef typename LinkedHashMap::iterator iterator;
+ typedef typename LinkedHashMap::const_iterator const_iterator;
+
+ explicit LRUExpiringCache(size_t max_cache_size)
+ : max_cache_size_(max_cache_size) {}
+
+ void Put(const Key& key, const Value& value) {
+ map_[key] = value;
+ EvictIfFull();
+ }
+
+ Value Get(const Key& key) {
+ iterator iter = map_.find(key);
+ if (iter != map_.end())
+ return iter->second;
+ return Value();
+ }
+
+ bool Contains(const Key& key) const {
+ const_iterator iter = map_.find(key);
+ return iter != map_.end();
+ }
+
+ Value Remove(const Key& key) {
+ Value val = Get(key);
+ map_.erase(key);
+ return val;
+ }
+
+ iterator begin() { return map_.begin(); }
+ iterator end() { return map_.end(); }
+ size_t MaximumCacheSize() const { return max_cache_size_; }
+ size_t size() const { return map_.size(); }
+
+ private:
+ void EvictIfFull() {
+ while (map_.size() > max_cache_size_) {
+ iterator it = map_.begin();
+ map_.erase(it);
+ }
+ }
+
+ size_t max_cache_size_;
+ LinkedHashMap map_;
+ };
+
+ typedef LRUExpiringCache<TabId, scoped_refptr<Thumbnail> >
+ ExpiringThumbnailCache;
+ typedef std::set<ThumbnailChangeListener*> ThumbnailChangeListenerSet;
+ typedef base::hash_map<TabId, scoped_refptr<TabReadbackRequest> >
+ TabReadbackRequestMap;
+ typedef base::hash_map<TabId, ThumbnailMetaData> ThumbnailMetaDataMap;
+ typedef std::list<scoped_refptr<Thumbnail> > ThumbnailQueue;
+
+ public:
+ ThumbnailCache(const std::string& disk_cache_path_str,
+ size_t default_cache_size,
+ size_t approximation_cache_size,
+ size_t compression_queue_max_size,
+ size_t write_queue_max_size,
+ bool use_approximation_thumbnails,
+ float thumbnail_scale);
+
+ ~ThumbnailCache();
+
+ void AddThumbnailChangeListener(ThumbnailChangeListener* listener);
+ void RemoveThumbnailChangeListener(ThumbnailChangeListener* listener);
+ void CacheTabThumbnail(const TabThumbnailProvider* tab);
+ void CacheTabThumbnailWithBitmap(const TabThumbnailProvider* tab,
+ const SkBitmap& bitmap,
+ float thumbnail_scale);
+ void HandleLowMemory(bool consider_gpu_memory);
+ void InvalidateIfChanged(const TabThumbnailProvider* tab);
+ void RemoveThumbnailsAndScheduleReload();
+ void CacheInTab(TabId tab_id);
+ void Remove(TabId tab_id);
+ void RemoveFromDiskAtAndAboveId(TabId min_id);
+ void RemoveFromDisk(TabId tab_id);
+ void UpdateVisibleIds(const TabIdList& last_visible_ids);
+ void ThumbnailRequested(TabId tab_id);
+ void SetUIResourceProvider(content::UIResourceProvider* ui_resource_provider);
+
+ // Implements content::UIResourceListener.
+ virtual void OnUIResourcesAreInvalid() OVERRIDE;
+ virtual void OnRecreateUIResources() OVERRIDE;
+
+ private:
+ // The task to run
+ static void CompressionTask(scoped_refptr<Thumbnail> thumbnail);
+
+ void PostCompressionTask(scoped_refptr<Thumbnail> thumbnail);
+
+ static void WriteTask(const base::FilePath& file_path,
+ scoped_refptr<Thumbnail> thumbnail);
+
+ void PostWriteTask(scoped_refptr<Thumbnail> thumbnail);
+
+ static void ReadTask(const base::FilePath& file_path,
+ scoped_refptr<Thumbnail> thumbnail);
+
+ void PostReadTask(scoped_refptr<Thumbnail> thumbnail);
+
+ static void RemoveFromDiskTask(const base::FilePath& file_path);
+ static void RemoveFromDiskAtAndAboveIdTask(const base::FilePath& dir_path,
+ TabId min_id);
+ scoped_refptr<Thumbnail> GetThumbnail(TabId tab_id);
+ scoped_refptr<Thumbnail> GetThumbnail(TabId tab_id, bool cache_in_if_missing);
+ void EndCacheTabThumbnail(TabId tab_id, const ThumbnailBitmap& bitmap);
+ bool CanReadTabContent(const TabThumbnailProvider* tab);
+ void PutThumbnail(TabId tab_id, const ThumbnailBitmap& thumbnail_bitmap);
+ void PutThumbnail(TabId tab_id,
+ const ThumbnailBitmap& thumbnail_bitmap,
+ scoped_refptr<Thumbnail> thumbnail);
+ bool CheckAndUpdateThumbnailMetaData(const TabThumbnailProvider* tab,
+ bool is_native_page);
+ void RemoveFromCache(ExpiringThumbnailCache& cache,
+ const std::list<TabId>& tab_ids);
+ size_t HandleLowMemoryOnQueue(ThumbnailQueue& queue,
+ bool consider_gpu_memory);
+ void RemoveFromQueues(TabId tab_id);
+ bool WriteThumbnailIfNecessary(scoped_refptr<Thumbnail> thumbnail);
+ bool CompressThumbnailIfNecessary(scoped_refptr<Thumbnail> thumbnail);
+ void WriteNextThumbnail();
+ bool RemoveDuplicateIdsFromQueueHelper(ThumbnailQueue& queue,
+ scoped_refptr<Thumbnail> thumbnail);
+ void ReadNextThumbnail(TabId id);
+ void ReadNextThumbnail();
+ void CompressNextThumbnail();
+ void RebuildThumbnail(scoped_refptr<Thumbnail> thumbnail,
+ bool force_cleanup_cpu_data);
+ bool ShouldCleanupThumbnail(scoped_refptr<Thumbnail> thumbnail,
+ const ExpiringThumbnailCache* forced_source);
+ void CleanupThumbnail(scoped_refptr<Thumbnail> thumbnail);
+ void CleanupThumbnail(scoped_refptr<Thumbnail> thumbnail,
+ const ExpiringThumbnailCache* forced_source);
+ void NotifyListenersOfThumbnailChange(TabId tab_id, bool upgrade);
+ void NotifyListenersOfUIResourceUpdate(TabId tab_id);
+ base::FilePath GetFilePath(TabId tab_id) const;
+ bool ThumbnailInputFileExists(TabId tab_id) const;
+ void RemoveCorruptThumbnailSource(TabId tab_id);
+ void MakeSpaceForNewItemIfNecessary(TabId tab_id);
+ void RemoveThumbnailFromCache();
+ void AddIdToVisibleIds(TabId tab_id);
+ void CleanupPersistentData();
+
+ base::Time CurrentTime();
+
+ content::UIResourceProvider* ui_resource_provider_;
+ const base::FilePath disk_cache_path_;
+ const size_t compression_queue_max_size_;
+ const size_t write_queue_max_size_;
+
+ ExpiringThumbnailCache cache_;
+ ExpiringThumbnailCache approximation_cache_;
+ const bool use_approximation_thumbnails_;
+
+ // All thumbnails are scaled by this value. This accounts for device's DPI
+ // (dots per inch).
+ const float thumbnail_scale_;
+
+ ThumbnailChangeListenerSet thumbnail_change_listeners_;
+
+ TabReadbackRequestMap pending_thumbnail_readbacks_;
+ ThumbnailMetaDataMap thumbnail_meta_data_;
+
+ ThumbnailQueue compression_queue_;
+ ThumbnailQueue write_queue_;
+ TabIdList read_queue_;
+
+ TabIdList last_visible_ids_;
+ TabIdList visible_ids_;
+
+ base::Thread compression_thread_;
+
+ base::WeakPtrFactory<ThumbnailCache> weak_factory_;
+};
+
+#endif // CHROME_BROWSER_ANDROID_THUMBNAIL_CACHE_H_

Powered by Google App Engine
This is Rietveld 408576698