diff options
author | lpromero <lpromero@chromium.org> | 2015-01-23 12:17:36 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-23 20:18:40 +0000 |
commit | a110f52e83cebd2b6f0ed37c34abeac8bfcb1b72 (patch) | |
tree | b0054fe1a2bbb25a9532fb7a1b9a1decb5b62a6d /components/enhanced_bookmarks | |
parent | 921392d21263c05b374d94ae3da3120094cd6a65 (diff) | |
download | chromium_src-a110f52e83cebd2b6f0ed37c34abeac8bfcb1b72.zip chromium_src-a110f52e83cebd2b6f0ed37c34abeac8bfcb1b72.tar.gz chromium_src-a110f52e83cebd2b6f0ed37c34abeac8bfcb1b72.tar.bz2 |
★ Record the image dominant color in the image database.
This CL adds a column in the bookmarks images database.
It contains the dominant color extracted from the image.
Since this computation can be lengthy, it is done in the background, when the
image is stored in the database.
For old databases, a migration path is provided and the dominant color is
computed and stored upon querying the image for the first time.
BUG=448443
Review URL: https://codereview.chromium.org/875463003
Cr-Commit-Position: refs/heads/master@{#312916}
Diffstat (limited to 'components/enhanced_bookmarks')
-rw-r--r-- | components/enhanced_bookmarks/BUILD.gn | 2 | ||||
-rw-r--r-- | components/enhanced_bookmarks/DEPS | 10 | ||||
-rw-r--r-- | components/enhanced_bookmarks/bookmark_image_service.cc | 107 | ||||
-rw-r--r-- | components/enhanced_bookmarks/bookmark_image_service.h | 47 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_record.h | 30 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store.cc | 4 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store.h | 23 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_ios_unittest.mm | 23 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_unittest.cc | 144 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_util.cc | 6 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_util.h | 4 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_util_ios.mm | 6 | ||||
-rw-r--r-- | components/enhanced_bookmarks/persistent_image_store.cc | 157 | ||||
-rw-r--r-- | components/enhanced_bookmarks/persistent_image_store.h | 7 | ||||
-rw-r--r-- | components/enhanced_bookmarks/test_image_store.cc | 24 | ||||
-rw-r--r-- | components/enhanced_bookmarks/test_image_store.h | 7 |
16 files changed, 418 insertions, 183 deletions
diff --git a/components/enhanced_bookmarks/BUILD.gn b/components/enhanced_bookmarks/BUILD.gn index 0da3276..7ce7ed5 100644 --- a/components/enhanced_bookmarks/BUILD.gn +++ b/components/enhanced_bookmarks/BUILD.gn @@ -18,6 +18,7 @@ source_set("enhanced_bookmarks") { "enhanced_bookmark_model_observer.h", "enhanced_bookmark_utils.cc", "enhanced_bookmark_utils.h", + "image_record.h", "image_store.cc", "image_store.h", "image_store_util.cc", @@ -37,6 +38,7 @@ source_set("enhanced_bookmarks") { "//base", "//components/bookmarks/browser", "//components/enhanced_bookmarks/proto", + "//skia", "//sql", "//ui/gfx", "//url", diff --git a/components/enhanced_bookmarks/DEPS b/components/enhanced_bookmarks/DEPS index 2716044..fd5c958 100644 --- a/components/enhanced_bookmarks/DEPS +++ b/components/enhanced_bookmarks/DEPS @@ -7,14 +7,6 @@ include_rules = [ "+jni", "+net", "+sql", + "+third_party/skia", "+ui", ] - -specific_include_rules = { - "image_store_unittest\.cc": [ - "+third_party/skia" - ], - "test_image_store\.cc": [ - "+third_party/skia" - ], -} diff --git a/components/enhanced_bookmarks/bookmark_image_service.cc b/components/enhanced_bookmarks/bookmark_image_service.cc index 0831e38..c2c019e 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.cc +++ b/components/enhanced_bookmarks/bookmark_image_service.cc @@ -5,12 +5,14 @@ #include "components/enhanced_bookmarks/bookmark_image_service.h" #include "base/single_thread_task_runner.h" +#include "base/task_runner_util.h" #include "base/thread_task_runner_handle.h" #include "base/threading/sequenced_worker_pool.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_model_observer.h" #include "components/enhanced_bookmarks/enhanced_bookmark_model.h" #include "components/enhanced_bookmarks/enhanced_bookmark_utils.h" +#include "components/enhanced_bookmarks/image_store_util.h" #include "components/enhanced_bookmarks/persistent_image_store.h" using bookmarks::BookmarkModel; @@ -33,11 +35,9 @@ void DeleteImageStore(ImageStore* store) { void RetrieveImageFromStoreRelay( ImageStore* store, const GURL& page_url, - enhanced_bookmarks::BookmarkImageService::Callback callback, + enhanced_bookmarks::BookmarkImageService::ImageCallback callback, scoped_refptr<base::SingleThreadTaskRunner> origin_loop) { - std::pair<gfx::Image, GURL> image_data = store->Get(page_url); - origin_loop->PostTask( - FROM_HERE, base::Bind(callback, image_data.first, image_data.second)); + origin_loop->PostTask(FROM_HERE, base::Bind(callback, store->Get(page_url))); } } // namespace @@ -99,14 +99,13 @@ void BookmarkImageService::Shutdown() { } void BookmarkImageService::SalientImageForUrl(const GURL& page_url, - Callback callback) { + ImageCallback callback) { DCHECK(CalledOnValidThread()); SalientImageForUrl(page_url, true, callback); } -void BookmarkImageService::RetrieveImageFromStore( - const GURL& page_url, - BookmarkImageService::Callback callback) { +void BookmarkImageService::RetrieveImageFromStore(const GURL& page_url, + ImageCallback callback) { DCHECK(CalledOnValidThread()); pool_->PostSequencedWorkerTaskWithShutdownBehavior( pool_->GetNamedSequenceToken(kSequenceToken), @@ -147,19 +146,18 @@ void BookmarkImageService::RetrieveSalientImageForPageUrl( } void BookmarkImageService::FetchCallback(const GURL& page_url, - Callback original_callback, - const gfx::Image& image, - const GURL& image_url) { + ImageCallback original_callback, + const ImageRecord& record) { DCHECK(CalledOnValidThread()); - if (!image.IsEmpty() || !image_url.is_empty()) { - // Either the image was in the store or there is no image in the store, but - // an URL for an image is present, indicating that a previous attempt to - // download the image failed. Just return the image. - original_callback.Run(image, image_url); + if (!record.image.IsEmpty() || !record.url.is_empty()) { + // Either the record was in the store or there is no image in the store, but + // an URL for a record is present, indicating that a previous attempt to + // download the image failed. Just return the record. + original_callback.Run(record); } else { - // There is no image in the store, and no previous attempts to retrieve + // There is no record in the store, and no previous attempts to retrieve // one. Start a request to retrieve a salient image if there is an image - // url set on a bookmark, and then enqueue the request for the image to + // url set on a bookmark, and then enqueue the request for the record to // be triggered when the retrieval is finished. RetrieveSalientImageForPageUrl(page_url); SalientImageForUrl(page_url, false, original_callback); @@ -168,7 +166,7 @@ void BookmarkImageService::FetchCallback(const GURL& page_url, void BookmarkImageService::SalientImageForUrl(const GURL& page_url, bool fetch_from_bookmark, - Callback callback) { + ImageCallback callback) { DCHECK(CalledOnValidThread()); // If the request is done while the image is currently being retrieved, just @@ -194,9 +192,7 @@ void BookmarkImageService::ProcessNewImage(const GURL& page_url, const gfx::Image& image, const GURL& image_url) { DCHECK(CalledOnValidThread()); - StoreImage(image, image_url, page_url); - in_progress_page_urls_.erase(page_url); - ProcessRequests(page_url, image, image_url); + PostTaskToStoreImage(image, image_url, page_url); if (update_bookmarks && image_url.is_valid()) { const BookmarkNode* bookmark = enhanced_bookmark_model_->bookmark_model() @@ -215,20 +211,42 @@ bool BookmarkImageService::IsPageUrlInProgress(const GURL& page_url) { return in_progress_page_urls_.find(page_url) != in_progress_page_urls_.end(); } -void BookmarkImageService::StoreImage(const gfx::Image& image, - const GURL& image_url, - const GURL& page_url) { - DCHECK(CalledOnValidThread()); +ImageRecord BookmarkImageService::StoreImage(const gfx::Image& image, + const GURL& image_url, + const GURL& page_url) { + ImageRecord image_info(image, image_url, SK_ColorBLACK); if (!image.IsEmpty()) { + image_info.dominant_color = DominantColorForImage(image); + // TODO(lpromero): this should be saved all the time, even when there is an + // empty image. http://crbug.com/451450 pool_->PostNamedSequencedWorkerTask( - kSequenceToken, - FROM_HERE, - base::Bind(&ImageStore::Insert, - base::Unretained(store_.get()), - page_url, - image_url, - image)); + kSequenceToken, FROM_HERE, + base::Bind(&ImageStore::Insert, base::Unretained(store_.get()), + page_url, image_info)); } + return image_info; +} + +void BookmarkImageService::PostTaskToStoreImage(const gfx::Image& image, + const GURL& image_url, + const GURL& page_url) { + DCHECK(CalledOnValidThread()); + + base::Callback<ImageRecord(void)> task = + base::Bind(&BookmarkImageService::StoreImage, base::Unretained(this), + image, image_url, page_url); + base::Callback<void(const ImageRecord&)> reply = + base::Bind(&BookmarkImageService::OnStoreImagePosted, + base::Unretained(this), page_url); + + base::PostTaskAndReplyWithResult(pool_.get(), FROM_HERE, task, reply); +} + +void BookmarkImageService::OnStoreImagePosted(const GURL& page_url, + const ImageRecord& image) { + DCHECK(CalledOnValidThread()); + in_progress_page_urls_.erase(page_url); + ProcessRequests(page_url, image); } void BookmarkImageService::RemoveImageForUrl(const GURL& page_url) { @@ -238,7 +256,7 @@ void BookmarkImageService::RemoveImageForUrl(const GURL& page_url) { FROM_HERE, base::Bind(&ImageStore::Erase, base::Unretained(store_.get()), page_url)); in_progress_page_urls_.erase(page_url); - ProcessRequests(page_url, gfx::Image(), GURL()); + ProcessRequests(page_url, ImageRecord()); } void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) { @@ -250,7 +268,7 @@ void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) { from, to)); in_progress_page_urls_.erase(from); - ProcessRequests(from, gfx::Image(), GURL()); + ProcessRequests(from, ImageRecord()); } void BookmarkImageService::ClearAll() { @@ -261,11 +279,10 @@ void BookmarkImageService::ClearAll() { FROM_HERE, base::Bind(&ImageStore::ClearAll, base::Unretained(store_.get()))); - for (std::map<const GURL, std::vector<Callback> >::const_iterator it = + for (std::map<const GURL, std::vector<ImageCallback>>::const_iterator it = callbacks_.begin(); - it != callbacks_.end(); - ++it) { - ProcessRequests(it->first, gfx::Image(), GURL()); + it != callbacks_.end(); ++it) { + ProcessRequests(it->first, ImageRecord()); } in_progress_page_urls_.erase(in_progress_page_urls_.begin(), @@ -273,15 +290,13 @@ void BookmarkImageService::ClearAll() { } void BookmarkImageService::ProcessRequests(const GURL& page_url, - const gfx::Image& image, - const GURL& image_url) { + const ImageRecord& record) { DCHECK(CalledOnValidThread()); - std::vector<Callback> callbacks = callbacks_[page_url]; - for (std::vector<Callback>::const_iterator it = callbacks.begin(); - it != callbacks.end(); - ++it) { - it->Run(image, image_url); + std::vector<ImageCallback> callbacks = callbacks_[page_url]; + for (std::vector<ImageCallback>::const_iterator it = callbacks.begin(); + it != callbacks.end(); ++it) { + it->Run(record); } callbacks_.erase(page_url); diff --git a/components/enhanced_bookmarks/bookmark_image_service.h b/components/enhanced_bookmarks/bookmark_image_service.h index 2ee8d61..5bf2637 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.h +++ b/components/enhanced_bookmarks/bookmark_image_service.h @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "components/bookmarks/browser/bookmark_model_observer.h" +#include "components/enhanced_bookmarks/image_record.h" #include "components/enhanced_bookmarks/image_store.h" #include "components/keyed_service/core/keyed_service.h" #include "net/url_request/url_request.h" @@ -36,7 +37,7 @@ class BookmarkImageService : public KeyedService, ~BookmarkImageService() override; - typedef base::Callback<void(const gfx::Image&, const GURL& url)> Callback; + typedef base::Callback<void(const ImageRecord&)> ImageCallback; // KeyedService: void Shutdown() override; @@ -46,7 +47,7 @@ class BookmarkImageService : public KeyedService, // a URL for this salient image available. The image (which may be empty) is // sent via the callback. The callback may be called synchronously if it is // possible. The callback is always triggered on the main thread. - void SalientImageForUrl(const GURL& page_url, Callback callback); + void SalientImageForUrl(const GURL& page_url, ImageCallback callback); // bookmarks::BookmarkModelObserver: void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, @@ -108,28 +109,37 @@ class BookmarkImageService : public KeyedService, EnhancedBookmarkModel* enhanced_bookmark_model_; private: - // Same as SalientImageForUrl(const GURL&, Callback) but can prevent the - // network request if fetch_from_bookmark is false. + // Same as SalientImageForUrl(const GURL&, ImageCallback) but can + // prevent the network request if fetch_from_bookmark is false. void SalientImageForUrl(const GURL& page_url, bool fetch_from_bookmark, - Callback stack_callback); + ImageCallback stack_callback); // Processes the requests that have been waiting on an image. - void ProcessRequests(const GURL& page_url, - const gfx::Image& image, - const GURL& image_url); + void ProcessRequests(const GURL& page_url, const ImageRecord& image); + + // Once an image is retrieved this method updates the store with it. Returns + // the newly formed ImageRecord. This is typically called on |pool_|, the + // background sequenced worker pool for this object. + ImageRecord StoreImage(const gfx::Image& image, + const GURL& image_url, + const GURL& page_url); + + // Calls |StoreImage| in the background. This should only be called from the + // main thread. + void PostTaskToStoreImage(const gfx::Image& image, + const GURL& image_url, + const GURL& page_url); - // Once an image is retrieved this method updates the store with it. - void StoreImage(const gfx::Image& image, - const GURL& image_url, - const GURL& page_url); + // Called when |StoreImage| as been posted. This should only be called from + // the main thread. + void OnStoreImagePosted(const GURL& page_url, const ImageRecord& image); // Called when retrieving an image from the image store fails, to trigger // retrieving the image from the url stored in the bookmark (if any). void FetchCallback(const GURL& page_url, - Callback original_callback, - const gfx::Image& image, - const GURL& image_url); + ImageCallback original_callback, + const ImageRecord& record); // Remove the image stored for this bookmark (if it exists). Called when a // bookmark is deleted. @@ -147,21 +157,20 @@ class BookmarkImageService : public KeyedService, // main thread and the callback will be called on the main thread as well. The // callback will always be called. The returned image is nil if the image is // not present in the store. - void RetrieveImageFromStore(const GURL& page_url, - BookmarkImageService::Callback callback); + void RetrieveImageFromStore(const GURL& page_url, ImageCallback callback); // Maps a pageUrl to an image. scoped_ptr<ImageStore> store_; // All the callbacks waiting for a particular image. - std::map<const GURL, std::vector<Callback> > callbacks_; + std::map<const GURL, std::vector<ImageCallback>> callbacks_; // When a bookmark is changed, two messages are received on the // bookmarkModelObserver, one with the old state, one with the new. The url // before the change is saved in this instance variable. GURL previous_url_; - // The worker pool to enqueue the store requests onto. + // The worker pool to enqueue the requests onto. scoped_refptr<base::SequencedWorkerPool> pool_; DISALLOW_COPY_AND_ASSIGN(BookmarkImageService); }; diff --git a/components/enhanced_bookmarks/image_record.h b/components/enhanced_bookmarks/image_record.h new file mode 100644 index 0000000..dde3251 --- /dev/null +++ b/components/enhanced_bookmarks/image_record.h @@ -0,0 +1,30 @@ +// Copyright 2015 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 COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_RECORD_H_ +#define COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_RECORD_H_ + +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/image/image.h" +#include "url/gurl.h" + +namespace enhanced_bookmarks { + +// Defines a record of a bookmark image in the ImageStore. +struct ImageRecord { + ImageRecord() : image(), url(), dominant_color(SK_ColorBLACK) {} + ImageRecord(const gfx::Image& image, const GURL& url, SkColor dominant_color) + : image(image), url(url), dominant_color(dominant_color) {} + + // The image data. + gfx::Image image; + // The URL that hosts the image. + GURL url; + // The dominant color of the image. + SkColor dominant_color; +}; + +} // namespace enhanced_bookmarks + +#endif // COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_RECORD_H_ diff --git a/components/enhanced_bookmarks/image_store.cc b/components/enhanced_bookmarks/image_store.cc index a7e32e2..a370578 100644 --- a/components/enhanced_bookmarks/image_store.cc +++ b/components/enhanced_bookmarks/image_store.cc @@ -18,7 +18,7 @@ void ImageStore::ChangeImageURL(const GURL& from, const GURL& to) { if (!HasKey(from)) return; - std::pair<gfx::Image, GURL> image_info = Get(from); + const enhanced_bookmarks::ImageRecord& record = Get(from); Erase(from); - Insert(to, image_info.second, image_info.first); + Insert(to, record); } diff --git a/components/enhanced_bookmarks/image_store.h b/components/enhanced_bookmarks/image_store.h index 9d79506..f4c63fa 100644 --- a/components/enhanced_bookmarks/image_store.h +++ b/components/enhanced_bookmarks/image_store.h @@ -5,11 +5,11 @@ #ifndef COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_STORE_H_ #define COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_STORE_H_ -#include <map> #include <set> #include "base/sequence_checker.h" -#include "ui/gfx/image/image.h" +#include "components/enhanced_bookmarks/image_record.h" +#include "ui/gfx/geometry/size.h" class GURL; @@ -23,21 +23,22 @@ class ImageStore { // Returns true if there is an image for this url. virtual bool HasKey(const GURL& page_url) = 0; - // Inserts an image and its url in the store for the the given page url. The - // image can be null indicating that the download of the image at this URL or - // encoding for insertion failed previously. On non-ios platforms, |image| + // Inserts an ImageRecord in the store for the given page url. The image can + // be null indicating that the download of the image at this URL or + // encoding for insertion failed previously. On non-iOS platforms, |image| // must have exactly one representation with a scale factor of 1. virtual void Insert(const GURL& page_url, - const GURL& image_url, - const gfx::Image& image) = 0; + const enhanced_bookmarks::ImageRecord& image_record) = 0; // Removes an image from the store. virtual void Erase(const GURL& page_url) = 0; - // Returns the image associated with this url. Returns empty image and url if - // there are no image for this url. It also returns the image_url where the - // image was downloaded from or failed to be downloaded from. - virtual std::pair<gfx::Image, GURL> Get(const GURL& page_url) = 0; + // Returns the image associated with this url. Returns an ImageRecord with an + // empty image if there is no image for this url. It also returns the + // image_url where the image was downloaded from or failed to be downloaded + // from. When the image is not empty, the dominant color of the image is also + // filled. + virtual enhanced_bookmarks::ImageRecord Get(const GURL& page_url) = 0; // Returns the size of the image stored for this URL or empty size if no // images are present. diff --git a/components/enhanced_bookmarks/image_store_ios_unittest.mm b/components/enhanced_bookmarks/image_store_ios_unittest.mm index 78c57cb..19dd5fa 100644 --- a/components/enhanced_bookmarks/image_store_ios_unittest.mm +++ b/components/enhanced_bookmarks/image_store_ios_unittest.mm @@ -8,6 +8,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/mac/scoped_cftyperef.h" +#include "components/enhanced_bookmarks/image_record.h" #include "components/enhanced_bookmarks/image_store_util.h" #include "components/enhanced_bookmarks/persistent_image_store.h" #include "components/enhanced_bookmarks/test_image_store.h" @@ -21,7 +22,7 @@ namespace { // Generates a gfx::Image with a random UIImage representation. Uses off-center // circle gradient to make all pixels slightly different in order to detect // small image alterations. -gfx::Image GenerateRandomUIImage(gfx::Size& size, float scale) { +gfx::Image GenerateRandomUIImage(const gfx::Size& size, float scale) { UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width(), size.height()), YES, // opaque. @@ -136,17 +137,19 @@ typedef testing::Types<TestImageStore, TYPED_TEST_CASE(ImageStoreUnitTestIOS, Implementations); TYPED_TEST(ImageStoreUnitTestIOS, StoringImagesPreservesScale) { - CGFloat scales[] = { 0.0, 1.0, 2.0 }; - gfx::Size image_size(42, 24); + const CGFloat scales[] = {0.0, 1.0, 2.0}; + const gfx::Size image_size(42, 24); for (unsigned long i = 0; i < arraysize(scales); i++) { - gfx::Image src_image(GenerateRandomUIImage(image_size, scales[i])); const GURL url("foo://bar"); - const GURL image_url("a.jpg"); - this->store_->Insert(url, image_url, src_image); - std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); - - EXPECT_EQ(image_url, image_info.second); - EXPECT_TRUE(CompareImages(src_image, image_info.first)); + const enhanced_bookmarks::ImageRecord image_in( + GenerateRandomUIImage(image_size, scales[i]), GURL("http://a.jpg"), + SK_ColorGREEN); + this->store_->Insert(url, image_in); + const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); + + EXPECT_EQ(image_in.url, image_out.url); + EXPECT_TRUE(CompareImages(image_in.image, image_out.image)); + EXPECT_EQ(image_in.dominant_color, image_out.dominant_color); } } diff --git a/components/enhanced_bookmarks/image_store_unittest.cc b/components/enhanced_bookmarks/image_store_unittest.cc index 3724e08..e0d5ace 100644 --- a/components/enhanced_bookmarks/image_store_unittest.cc +++ b/components/enhanced_bookmarks/image_store_unittest.cc @@ -4,13 +4,17 @@ #include "components/enhanced_bookmarks/image_store.h" +#include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/strings/string_number_conversions.h" +#include "components/enhanced_bookmarks/image_record.h" #include "components/enhanced_bookmarks/image_store_util.h" #include "components/enhanced_bookmarks/persistent_image_store.h" #include "components/enhanced_bookmarks/test_image_store.h" +#include "sql/statement.h" #include "testing/platform_test.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkColor.h" #include "url/gurl.h" namespace { @@ -62,6 +66,45 @@ bool CompareImages(const gfx::Image& image_1, const gfx::Image& image_2) { image_1_bytes->size()); } +bool CreateV1PersistentImageStoreDB(const base::FilePath& path) { + sql::Connection db; + if (!db.Open(path)) + return false; + + if (db.DoesTableExist("images_by_url")) + return false; + + const char kV1TableSql[] = + "CREATE TABLE IF NOT EXISTS images_by_url (" + "page_url LONGVARCHAR NOT NULL," + "image_url LONGVARCHAR NOT NULL," + "image_data BLOB," + "width INTEGER," + "height INTEGER" + ")"; + if (!db.Execute(kV1TableSql)) + return false; + + const char kV1IndexSql[] = + "CREATE INDEX IF NOT EXISTS images_by_url_idx ON images_by_url(page_url)"; + if (!db.Execute(kV1IndexSql)) + return false; + + sql::Statement statement(db.GetUniqueStatement( + "INSERT INTO images_by_url " + "(page_url, image_url, image_data, width, height) " + "VALUES (?, ?, ?, ?, ?)")); + statement.BindString(0, "foo://bar"); + statement.BindString(1, "http://a.jpg"); + scoped_refptr<base::RefCountedMemory> image_bytes = + enhanced_bookmarks::BytesForImage(GenerateWhiteImage()); + statement.BindBlob(2, image_bytes->front(), (int)image_bytes->size()); + statement.BindInt(3, 42); + statement.BindInt(4, 24); + + return statement.Run(); +} + // Factory functions for creating instances of the implementations. template <class T> ImageStore* CreateStore(base::ScopedTempDir& folder); @@ -127,7 +170,9 @@ TYPED_TEST(ImageStoreUnitTest, StartsEmpty) { } TYPED_TEST(ImageStoreUnitTest, StoreOne) { - this->store_->Insert(GURL("foo://bar"), GURL("a.jpg"), GenerateBlackImage()); + const enhanced_bookmarks::ImageRecord image( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + this->store_->Insert(GURL("foo://bar"), image); std::set<GURL> all_urls; this->store_->GetAllPageUrls(&all_urls); @@ -137,25 +182,26 @@ TYPED_TEST(ImageStoreUnitTest, StoreOne) { } TYPED_TEST(ImageStoreUnitTest, Retrieve) { - gfx::Image src_image = GenerateBlackImage(42, 24); const GURL url("foo://bar"); - const GURL image_url("a.jpg"); - this->store_->Insert(url, image_url, src_image); - - std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); - gfx::Size size = this->store_->GetSize(url); - - EXPECT_EQ(size.width(), 42); - EXPECT_EQ(size.height(), 24); - EXPECT_EQ(image_url, image_info.second); - EXPECT_TRUE(CompareImages(src_image, image_info.first)); + const enhanced_bookmarks::ImageRecord image_in( + CreateImage(42, 24, 1, 0, 0, 1), GURL("http://a.jpg"), SK_ColorBLUE); + this->store_->Insert(url, image_in); + + const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); + const gfx::Size size = this->store_->GetSize(url); + + EXPECT_EQ(42, size.width()); + EXPECT_EQ(24, size.height()); + EXPECT_EQ(image_in.url, image_out.url); + EXPECT_TRUE(CompareImages(image_in.image, image_out.image)); + EXPECT_EQ(SK_ColorBLUE, image_out.dominant_color); } TYPED_TEST(ImageStoreUnitTest, Erase) { - gfx::Image src_image = GenerateBlackImage(); const GURL url("foo://bar"); - const GURL image_url("a.jpg"); - this->store_->Insert(url, image_url, src_image); + const enhanced_bookmarks::ImageRecord image( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + this->store_->Insert(url, image); this->store_->Erase(url); EXPECT_FALSE(this->store_->HasKey(url)); @@ -166,9 +212,13 @@ TYPED_TEST(ImageStoreUnitTest, Erase) { TYPED_TEST(ImageStoreUnitTest, ClearAll) { const GURL url_foo("http://foo"); - this->store_->Insert(url_foo, GURL("foo.jpg"), GenerateBlackImage()); + const enhanced_bookmarks::ImageRecord black_image( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + this->store_->Insert(url_foo, black_image); const GURL url_bar("http://bar"); - this->store_->Insert(url_foo, GURL("bar.jpg"), GenerateWhiteImage()); + const enhanced_bookmarks::ImageRecord white_image( + GenerateWhiteImage(), GURL("http://a.jpg"), SK_ColorWHITE); + this->store_->Insert(url_bar, white_image); this->store_->ClearAll(); @@ -180,54 +230,70 @@ TYPED_TEST(ImageStoreUnitTest, ClearAll) { } TYPED_TEST(ImageStoreUnitTest, Update) { - gfx::Image src_image1 = GenerateWhiteImage(); - gfx::Image src_image2 = GenerateBlackImage(); const GURL url("foo://bar"); - const GURL image_url1("1.jpg"); - this->store_->Insert(url, image_url1, src_image1); + const enhanced_bookmarks::ImageRecord image1(GenerateWhiteImage(), + GURL("1.jpg"), SK_ColorWHITE); + this->store_->Insert(url, image1); - const GURL image_url2("2.jpg"); - this->store_->Insert(url, image_url2, src_image2); + const enhanced_bookmarks::ImageRecord image2(GenerateBlackImage(), + GURL("2.jpg"), SK_ColorBLACK); + this->store_->Insert(url, image2); - std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); + const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); EXPECT_TRUE(this->store_->HasKey(url)); std::set<GURL> all_urls; this->store_->GetAllPageUrls(&all_urls); EXPECT_EQ(1u, all_urls.size()); - EXPECT_EQ(image_url2, image_info.second); - EXPECT_TRUE(CompareImages(src_image2, image_info.first)); + EXPECT_EQ(image2.url, image_out.url); + EXPECT_TRUE(CompareImages(image2.image, image_out.image)); + EXPECT_EQ(SK_ColorBLACK, image_out.dominant_color); } TYPED_TEST(ImageStoreUnitTest, Persistence) { - gfx::Image src_image = GenerateBlackImage(); const GURL url("foo://bar"); - const GURL image_url("a.jpg"); - this->store_->Insert(url, image_url, src_image); + const enhanced_bookmarks::ImageRecord image_in( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + this->store_->Insert(url, image_in); this->ResetStore(); if (this->use_persistent_store()) { std::set<GURL> all_urls; this->store_->GetAllPageUrls(&all_urls); EXPECT_EQ(1u, all_urls.size()); - EXPECT_EQ(GURL("foo://bar"), *all_urls.begin()); - EXPECT_TRUE(this->store_->HasKey(GURL("foo://bar"))); - std::pair<gfx::Image, GURL> image_info = this->store_->Get(url); + EXPECT_EQ(url, *all_urls.begin()); + EXPECT_TRUE(this->store_->HasKey(url)); + const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); - EXPECT_EQ(image_url, image_info.second); - EXPECT_TRUE(CompareImages(src_image, image_info.first)); + EXPECT_EQ(image_in.url, image_out.url); + EXPECT_TRUE(CompareImages(image_in.image, image_out.image)); + EXPECT_EQ(image_in.dominant_color, image_out.dominant_color); } else { std::set<GURL> all_urls; this->store_->GetAllPageUrls(&all_urls); EXPECT_EQ(0u, all_urls.size()); - EXPECT_FALSE(this->store_->HasKey(GURL("foo://bar"))); + EXPECT_FALSE(this->store_->HasKey(url)); } } +TYPED_TEST(ImageStoreUnitTest, MigrationToV2) { + // Migration is available only with persistent stores. + if (!this->use_persistent_store()) + return; + + // Set up v1 DB. + EXPECT_TRUE(CreateV1PersistentImageStoreDB(this->tempDir_.path().Append( + base::FilePath::FromUTF8Unsafe("BookmarkImageAndUrlStore.db")))); + + const enhanced_bookmarks::ImageRecord image_out = + this->store_->Get(GURL("foo://bar")); + EXPECT_EQ(SK_ColorWHITE, image_out.dominant_color); +} + TYPED_TEST(ImageStoreUnitTest, GetSize) { - gfx::Image src_image = GenerateBlackImage(); const GURL url("foo://bar"); - const GURL image_url("a.jpg"); + const enhanced_bookmarks::ImageRecord image_in( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); int64 size = 0; if (this->use_persistent_store()) { @@ -238,8 +304,8 @@ TYPED_TEST(ImageStoreUnitTest, GetSize) { EXPECT_LE(this->store_->GetStoreSizeInBytes(), 1024); } for (int i = 0; i < 100; ++i) { - this->store_->Insert( - GURL(url.spec() + '/' + base::IntToString(i)), image_url, src_image); + this->store_->Insert(GURL(url.spec() + '/' + base::IntToString(i)), + image_in); EXPECT_GE(this->store_->GetStoreSizeInBytes(), size); size = this->store_->GetStoreSizeInBytes(); } diff --git a/components/enhanced_bookmarks/image_store_util.cc b/components/enhanced_bookmarks/image_store_util.cc index 213b595..ef3979d 100644 --- a/components/enhanced_bookmarks/image_store_util.cc +++ b/components/enhanced_bookmarks/image_store_util.cc @@ -4,6 +4,8 @@ #include "components/enhanced_bookmarks/image_store_util.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/color_analysis.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_util.h" @@ -30,4 +32,8 @@ scoped_refptr<base::RefCountedMemory> BytesForImage(const gfx::Image& image) { gfx::Image ImageForBytes(const scoped_refptr<base::RefCountedMemory>& bytes) { return gfx::ImageFrom1xJPEGEncodedData(bytes->front(), bytes->size()); } + +SkColor DominantColorForImage(const gfx::Image& image) { + return color_utils::CalculateKMeanColorOfBitmap(*image.ToSkBitmap()); +} } diff --git a/components/enhanced_bookmarks/image_store_util.h b/components/enhanced_bookmarks/image_store_util.h index 0b9ecaf..8537197 100644 --- a/components/enhanced_bookmarks/image_store_util.h +++ b/components/enhanced_bookmarks/image_store_util.h @@ -6,6 +6,7 @@ #define COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_STORE_UTIL_H_ #include "base/memory/ref_counted_memory.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image.h" @@ -22,6 +23,9 @@ scoped_refptr<base::RefCountedMemory> BytesForImage(const gfx::Image& image); // returns a gfx::Image. If decoding fails, returns an empty image. gfx::Image ImageForBytes(const scoped_refptr<base::RefCountedMemory>& data); +// Returns the dominant color for |image|. This method can be slow on very large +// images. +SkColor DominantColorForImage(const gfx::Image& image); } #endif // COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_STORE_UTIL_H_ diff --git a/components/enhanced_bookmarks/image_store_util_ios.mm b/components/enhanced_bookmarks/image_store_util_ios.mm index 5d027cb..98a08db 100644 --- a/components/enhanced_bookmarks/image_store_util_ios.mm +++ b/components/enhanced_bookmarks/image_store_util_ios.mm @@ -8,6 +8,8 @@ #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsobject.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/color_analysis.h" namespace { // An implementation of RefCountedMemory, where the bytes are stored in a @@ -45,4 +47,8 @@ gfx::Image ImageForBytes(const scoped_refptr<base::RefCountedMemory>& data) { [NSData dataWithBytes:data->front() length:data->size()]] retain]); } +SkColor DominantColorForImage(const gfx::Image& image) { + return color_utils::CalculateKMeanColorOfBitmap(*image.ToSkBitmap()); +} + } // namespace enhanced_bookmarks diff --git a/components/enhanced_bookmarks/persistent_image_store.cc b/components/enhanced_bookmarks/persistent_image_store.cc index 0108c85..1061b69 100644 --- a/components/enhanced_bookmarks/persistent_image_store.cc +++ b/components/enhanced_bookmarks/persistent_image_store.cc @@ -5,6 +5,7 @@ #include "components/enhanced_bookmarks/persistent_image_store.h" #include "base/files/file.h" +#include "base/logging.h" #include "components/enhanced_bookmarks/image_store_util.h" #include "sql/statement.h" #include "sql/transaction.h" @@ -12,6 +13,11 @@ #include "url/gurl.h" namespace { +// Current version number. Databases are written at the "current" version +// number, but any previous version that can read the "compatible" one can make +// do with our database without *too* many bad effects. +const int kCurrentVersionNumber = 2; +const int kCompatibleVersionNumber = 1; bool InitTables(sql::Connection& db) { const char kTableSql[] = @@ -20,7 +26,8 @@ bool InitTables(sql::Connection& db) { "image_url LONGVARCHAR NOT NULL," "image_data BLOB," "width INTEGER," - "height INTEGER" + "height INTEGER," + "image_dominant_color INTEGER" ")"; if (!db.Execute(kTableSql)) return false; @@ -35,7 +42,60 @@ bool InitIndices(sql::Connection& db) { return true; } +// V1 didn't store the dominant color of an image. Creates the column to store +// a dominant color in the database. The value will be filled when queried for a +// one time cost. +bool MigrateImagesWithNoDominantColor(sql::Connection& db) { + if (!db.DoesTableExist("images_by_url")) { + NOTREACHED() << "images_by_url table should exist before migration."; + return false; + } + + if (!db.DoesColumnExist("images_by_url", "image_dominant_color")) { + // The initial version doesn't have the image_dominant_color column, it is + // added to the table here. + if (!db.Execute( + "ALTER TABLE images_by_url " + "ADD COLUMN image_dominant_color INTEGER")) { + return false; + } + } + return true; +} + +sql::InitStatus EnsureCurrentVersion(sql::Connection& db, + sql::MetaTable& meta_table) { + // 1- Newer databases than designed for can't be read. + if (meta_table.GetCompatibleVersionNumber() > kCurrentVersionNumber) { + LOG(WARNING) << "Image DB is too new."; + return sql::INIT_TOO_NEW; + } + + int cur_version = meta_table.GetVersionNumber(); + + // 2- Put migration code here. + + if (cur_version == 1) { + if (!MigrateImagesWithNoDominantColor(db)) { + LOG(WARNING) << "Unable to update image DB to version 1."; + return sql::INIT_FAILURE; + } + ++cur_version; + meta_table.SetVersionNumber(cur_version); + meta_table.SetCompatibleVersionNumber( + std::min(cur_version, kCompatibleVersionNumber)); + } + + // 3- When the version is too old, just try to continue anyway, there should + // not be a released product that makes a database too old to handle. + LOG_IF(WARNING, cur_version < kCurrentVersionNumber) + << "Image DB version " << cur_version << " is too old to handle."; + + return sql::INIT_OK; +} + sql::InitStatus OpenDatabaseImpl(sql::Connection& db, + sql::MetaTable& meta_table, const base::FilePath& db_path) { DCHECK(!db.is_open()); @@ -44,22 +104,33 @@ sql::InitStatus OpenDatabaseImpl(sql::Connection& db, // TODO(noyau): Set error callback? // Run the database in exclusive mode. Nobody else should be accessing the - // database while we're running, and this will give somewhat improved perf. + // database while running, and this will give somewhat improved performance. db.set_exclusive_locking(); if (!db.Open(db_path)) return sql::INIT_FAILURE; - // Scope initialization in a transaction so we can't be partially initialized. + // Scope initialization in a transaction so it can't be partially initialized. sql::Transaction transaction(&db); if (!transaction.Begin()) return sql::INIT_FAILURE; + // Initialize the meta table. + int cur_version = meta_table.DoesTableExist(&db) + ? kCurrentVersionNumber + : 1; // Only v1 didn't have a meta table. + if (!meta_table.Init(&db, cur_version, + std::min(cur_version, kCompatibleVersionNumber))) + return sql::INIT_FAILURE; + // Create the tables. - if (!InitTables(db) || - !InitIndices(db)) { + if (!InitTables(db) || !InitIndices(db)) return sql::INIT_FAILURE; - } + + // Check the version. + sql::InitStatus version_status = EnsureCurrentVersion(db, meta_table); + if (version_status != sql::INIT_OK) + return version_status; // Initialization is complete. if (!transaction.Commit()) @@ -90,24 +161,25 @@ bool PersistentImageStore::HasKey(const GURL& page_url) { return !!count; } -void PersistentImageStore::Insert(const GURL& page_url, - const GURL& image_url, - const gfx::Image& image) { +void PersistentImageStore::Insert( + const GURL& page_url, + const enhanced_bookmarks::ImageRecord& record) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); if (OpenDatabase() != sql::INIT_OK) return; Erase(page_url); // Remove previous image for this url, if any. - sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, + sql::Statement statement(db_.GetCachedStatement( + SQL_FROM_HERE, "INSERT INTO images_by_url " - "(page_url, image_url, image_data, width, height)" - "VALUES (?, ?, ?, ?, ?)")); + "(page_url, image_url, image_data, width, height, image_dominant_color)" + "VALUES (?, ?, ?, ?, ?, ?)")); statement.BindString(0, page_url.possibly_invalid_spec()); - statement.BindString(1, image_url.possibly_invalid_spec()); + statement.BindString(1, record.url.possibly_invalid_spec()); scoped_refptr<base::RefCountedMemory> image_bytes = - enhanced_bookmarks::BytesForImage(image); + enhanced_bookmarks::BytesForImage(record.image); // Insert an empty image in case encoding fails. if (!image_bytes.get()) @@ -117,8 +189,9 @@ void PersistentImageStore::Insert(const GURL& page_url, statement.BindBlob(2, image_bytes->front(), (int)image_bytes->size()); - statement.BindInt(3, image.Size().width()); - statement.BindInt(4, image.Size().height()); + statement.BindInt(3, record.image.Size().width()); + statement.BindInt(4, record.image.Size().height()); + statement.BindInt(5, record.dominant_color); statement.Run(); } @@ -133,27 +206,59 @@ void PersistentImageStore::Erase(const GURL& page_url) { statement.Run(); } -std::pair<gfx::Image, GURL> PersistentImageStore::Get(const GURL& page_url) { +enhanced_bookmarks::ImageRecord PersistentImageStore::Get( + const GURL& page_url) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); + enhanced_bookmarks::ImageRecord image_record; if (OpenDatabase() != sql::INIT_OK) - return std::make_pair(gfx::Image(), GURL()); + return image_record; - sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, - "SELECT image_data, image_url FROM images_by_url WHERE page_url = ?")); + bool stored_image_record_needs_update = false; - statement.BindString(0, page_url.possibly_invalid_spec()); + // Scope the SELECT statement. + { + sql::Statement statement(db_.GetCachedStatement( + SQL_FROM_HERE, + "SELECT image_data, image_url, image_dominant_color FROM images_by_url " + "WHERE page_url = ?")); - while (statement.Step()) { + statement.BindString(0, page_url.possibly_invalid_spec()); + + if (!statement.Step()) + return image_record; + + // Image. if (statement.ColumnByteLength(0) > 0) { scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); statement.ColumnBlobAsVector(0, &data->data()); + image_record.image = enhanced_bookmarks::ImageForBytes(data); + } - return std::make_pair(enhanced_bookmarks::ImageForBytes(data), - GURL(statement.ColumnString(1))); + // URL. + image_record.url = GURL(statement.ColumnString(1)); + + // Dominant color. + if (statement.ColumnType(2) != sql::COLUMN_TYPE_NULL) { + image_record.dominant_color = SkColor(statement.ColumnInt(2)); + } else { + // The dominant color was not computed when the image was first + // stored. + // Compute it now. + image_record.dominant_color = + enhanced_bookmarks::DominantColorForImage(image_record.image); + stored_image_record_needs_update = true; } + + // Make sure there is only one record for page_url. + DCHECK(!statement.Step()); + } + + if (stored_image_record_needs_update) { + Erase(page_url); + Insert(page_url, image_record); } - return std::make_pair(gfx::Image(), GURL()); + return image_record; } gfx::Size PersistentImageStore::GetSize(const GURL& page_url) { @@ -217,7 +322,7 @@ sql::InitStatus PersistentImageStore::OpenDatabase() { sql::InitStatus status = sql::INIT_FAILURE; for (size_t i = 0; i < kAttempts; ++i) { - status = OpenDatabaseImpl(db_, path_); + status = OpenDatabaseImpl(db_, meta_table_, path_); if (status == sql::INIT_OK) return status; diff --git a/components/enhanced_bookmarks/persistent_image_store.h b/components/enhanced_bookmarks/persistent_image_store.h index bc715a5..5a0c41d 100644 --- a/components/enhanced_bookmarks/persistent_image_store.h +++ b/components/enhanced_bookmarks/persistent_image_store.h @@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "sql/connection.h" #include "sql/init_status.h" +#include "sql/meta_table.h" // The PersistentImageStore is an implementation of ImageStore that persists its // data on disk. @@ -19,10 +20,9 @@ class PersistentImageStore : public ImageStore { explicit PersistentImageStore(const base::FilePath& path); bool HasKey(const GURL& page_url) override; void Insert(const GURL& page_url, - const GURL& image_url, - const gfx::Image& image) override; + const enhanced_bookmarks::ImageRecord& image) override; void Erase(const GURL& page_url) override; - std::pair<gfx::Image, GURL> Get(const GURL& page_url) override; + enhanced_bookmarks::ImageRecord Get(const GURL& page_url) override; gfx::Size GetSize(const GURL& page_url) override; void GetAllPageUrls(std::set<GURL>* urls) override; void ClearAll() override; @@ -36,6 +36,7 @@ class PersistentImageStore : public ImageStore { const base::FilePath path_; sql::Connection db_; + sql::MetaTable meta_table_; DISALLOW_COPY_AND_ASSIGN(PersistentImageStore); }; diff --git a/components/enhanced_bookmarks/test_image_store.cc b/components/enhanced_bookmarks/test_image_store.cc index 19d505f..9b11cdf 100644 --- a/components/enhanced_bookmarks/test_image_store.cc +++ b/components/enhanced_bookmarks/test_image_store.cc @@ -18,15 +18,11 @@ bool TestImageStore::HasKey(const GURL& page_url) { } void TestImageStore::Insert(const GURL& page_url, - const GURL& image_url, - const gfx::Image& image) { + const enhanced_bookmarks::ImageRecord& image) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); Erase(page_url); - store_.insert(std::make_pair( - page_url, - std::make_pair(image, - image_url))); + store_.insert(std::make_pair(page_url, image)); } void TestImageStore::Erase(const GURL& page_url) { @@ -35,14 +31,13 @@ void TestImageStore::Erase(const GURL& page_url) { store_.erase(page_url); } -std::pair<gfx::Image, GURL> TestImageStore::Get(const GURL& page_url) { +enhanced_bookmarks::ImageRecord TestImageStore::Get(const GURL& page_url) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); - ImageMap::const_iterator pair_enumerator = store_.find(page_url); - if (pair_enumerator == store_.end()) - return std::make_pair(gfx::Image(), GURL()); + if (store_.find(page_url) == store_.end()) + return enhanced_bookmarks::ImageRecord(); - return std::make_pair(store_[page_url].first, store_[page_url].second); + return store_[page_url]; } gfx::Size TestImageStore::GetSize(const GURL& page_url) { @@ -52,7 +47,7 @@ gfx::Size TestImageStore::GetSize(const GURL& page_url) { if (pair_enumerator == store_.end()) return gfx::Size(); - return store_[page_url].first.Size(); + return store_[page_url].image.Size(); } void TestImageStore::GetAllPageUrls(std::set<GURL>* urls) { @@ -77,9 +72,10 @@ int64 TestImageStore::GetStoreSizeInBytes() { size += sizeof(it->first); size += it->first.spec().length(); size += sizeof(it->second); - SkBitmap bitmap = it->second.first.AsBitmap(); + SkBitmap bitmap = it->second.image.AsBitmap(); size += bitmap.getSize(); - size += it->second.second.spec().length(); + size += it->second.url.spec().length(); + size += sizeof(it->second.dominant_color); } return size; } diff --git a/components/enhanced_bookmarks/test_image_store.h b/components/enhanced_bookmarks/test_image_store.h index 5acef16..460a285 100644 --- a/components/enhanced_bookmarks/test_image_store.h +++ b/components/enhanced_bookmarks/test_image_store.h @@ -15,10 +15,9 @@ class TestImageStore : public ImageStore { TestImageStore(); bool HasKey(const GURL& page_url) override; void Insert(const GURL& page_url, - const GURL& image_url, - const gfx::Image& image) override; + const enhanced_bookmarks::ImageRecord& image) override; void Erase(const GURL& page_url) override; - std::pair<gfx::Image, GURL> Get(const GURL& page_url) override; + enhanced_bookmarks::ImageRecord Get(const GURL& page_url) override; gfx::Size GetSize(const GURL& page_url) override; void GetAllPageUrls(std::set<GURL>* urls) override; void ClearAll() override; @@ -28,7 +27,7 @@ class TestImageStore : public ImageStore { ~TestImageStore() override; private: - typedef std::map<const GURL, std::pair<gfx::Image, const GURL> > ImageMap; + typedef std::map<const GURL, enhanced_bookmarks::ImageRecord> ImageMap; ImageMap store_; DISALLOW_COPY_AND_ASSIGN(TestImageStore); |