diff options
author | kkimlabs <kkimlabs@chromium.org> | 2015-04-03 03:08:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-03 10:08:37 +0000 |
commit | 16a0d2a22d17e3932432dab4559e63c5134aaccc (patch) | |
tree | cb3602e115c8dc531195283d2c417825005f00ad /components/enhanced_bookmarks | |
parent | a4c00a7ec01b3308c98cfad88b4bf3af1b4fde2b (diff) | |
download | chromium_src-16a0d2a22d17e3932432dab4559e63c5134aaccc.zip chromium_src-16a0d2a22d17e3932432dab4559e63c5134aaccc.tar.gz chromium_src-16a0d2a22d17e3932432dab4559e63c5134aaccc.tar.bz2 |
Fix crashes due to gfx::Image unsafe thread passing
gfx::Image has |storage_| member which is base::RefCounted, not thread
safe. Thus passing around gfx::Image to other threads by copying is
incorrect.
Workaround by using scoped_ptr and making ImageRecord class
RefCountedThreadSafe.
Related discussion:
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/8LqVoXQ_2bo
BUG=471800
Review URL: https://codereview.chromium.org/1031293002
Cr-Commit-Position: refs/heads/master@{#323720}
Diffstat (limited to 'components/enhanced_bookmarks')
-rw-r--r-- | components/enhanced_bookmarks/BUILD.gn | 1 | ||||
-rw-r--r-- | components/enhanced_bookmarks/bookmark_image_service.cc | 58 | ||||
-rw-r--r-- | components/enhanced_bookmarks/bookmark_image_service.h | 21 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_record.cc | 28 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_record.h | 19 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store.cc | 2 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store.h | 8 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_ios_unittest.mm | 22 | ||||
-rw-r--r-- | components/enhanced_bookmarks/image_store_unittest.cc | 93 | ||||
-rw-r--r-- | components/enhanced_bookmarks/persistent_image_store.cc | 27 | ||||
-rw-r--r-- | components/enhanced_bookmarks/persistent_image_store.h | 5 | ||||
-rw-r--r-- | components/enhanced_bookmarks/test_image_store.cc | 24 | ||||
-rw-r--r-- | components/enhanced_bookmarks/test_image_store.h | 11 |
13 files changed, 199 insertions, 120 deletions
diff --git a/components/enhanced_bookmarks/BUILD.gn b/components/enhanced_bookmarks/BUILD.gn index 924b570..be2322b 100644 --- a/components/enhanced_bookmarks/BUILD.gn +++ b/components/enhanced_bookmarks/BUILD.gn @@ -23,6 +23,7 @@ source_set("enhanced_bookmarks") { "enhanced_bookmark_model_observer.h", "enhanced_bookmark_utils.cc", "enhanced_bookmark_utils.h", + "image_record.cc", "image_record.h", "image_store.cc", "image_store.h", diff --git a/components/enhanced_bookmarks/bookmark_image_service.cc b/components/enhanced_bookmarks/bookmark_image_service.cc index fb3d688..4037733 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.cc +++ b/components/enhanced_bookmarks/bookmark_image_service.cc @@ -148,9 +148,9 @@ void BookmarkImageService::RetrieveSalientImageForPageUrl( void BookmarkImageService::FetchCallback(const GURL& page_url, ImageCallback original_callback, - const ImageRecord& record) { + scoped_refptr<ImageRecord> record) { DCHECK(CalledOnValidThread()); - if (!record.image.IsEmpty() || !record.url.is_empty()) { + 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. @@ -191,15 +191,18 @@ void BookmarkImageService::SalientImageForUrl(const GURL& page_url, void BookmarkImageService::ProcessNewImage(const GURL& page_url, bool update_bookmarks, const GURL& image_url, - const gfx::Image& image) { + scoped_ptr<gfx::Image> image) { DCHECK(CalledOnValidThread()); - PostTaskToStoreImage(image, image_url, page_url); + + gfx::Size size = image->Size(); + PostTaskToStoreImage(image.Pass(), image_url, page_url); + if (update_bookmarks && image_url.is_valid()) { const BookmarkNode* bookmark = enhanced_bookmark_model_->bookmark_model() ->GetMostRecentlyAddedUserNodeForURL(page_url); if (bookmark) { - const gfx::Size& size = image.Size(); + bool result = enhanced_bookmark_model_->SetOriginalImage( bookmark, image_url, size.width(), size.height()); DCHECK(result); @@ -212,13 +215,13 @@ bool BookmarkImageService::IsPageUrlInProgress(const GURL& page_url) { return in_progress_page_urls_.find(page_url) != in_progress_page_urls_.end(); } -ImageRecord BookmarkImageService::ResizeAndStoreImage(const gfx::Image& image, - const GURL& image_url, - const GURL& page_url) { - gfx::Image resized_image = ResizeImage(image); - ImageRecord image_info(resized_image, image_url, SK_ColorBLACK); - if (!resized_image.IsEmpty()) { - image_info.dominant_color = DominantColorForImage(resized_image); +scoped_refptr<ImageRecord> BookmarkImageService::ResizeAndStoreImage( + scoped_refptr<ImageRecord> image_info, + const GURL& page_url) { + + if (!image_info->image->IsEmpty()) { + image_info->image = ResizeImage(*image_info->image); + image_info->dominant_color = DominantColorForImage(*image_info->image); // TODO(lpromero): this should be saved all the time, even when there is an // empty image. http://crbug.com/451450 pool_->PostNamedSequencedWorkerTask( @@ -226,26 +229,33 @@ ImageRecord BookmarkImageService::ResizeAndStoreImage(const gfx::Image& image, 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) { +void BookmarkImageService::PostTaskToStoreImage( + scoped_ptr<gfx::Image> image, + const GURL& image_url, + const GURL& page_url) { DCHECK(CalledOnValidThread()); - base::Callback<ImageRecord(void)> task = + scoped_refptr<ImageRecord> image_info( + new ImageRecord(image.Pass(), image_url)); + + // TODO ensure image thread safety. + base::Callback<scoped_refptr<ImageRecord>(void)> task = base::Bind(&BookmarkImageService::ResizeAndStoreImage, - base::Unretained(this), image, image_url, page_url); - base::Callback<void(const ImageRecord&)> reply = + base::Unretained(this), image_info, page_url); + base::Callback<void(scoped_refptr<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) { +void BookmarkImageService::OnStoreImagePosted( + const GURL& page_url, + scoped_refptr<ImageRecord> image) { DCHECK(CalledOnValidThread()); in_progress_page_urls_.erase(page_url); ProcessRequests(page_url, image); @@ -258,7 +268,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, ImageRecord()); + ProcessRequests(page_url, scoped_refptr<ImageRecord>(new ImageRecord())); } void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) { @@ -270,7 +280,7 @@ void BookmarkImageService::ChangeImageURL(const GURL& from, const GURL& to) { from, to)); in_progress_page_urls_.erase(from); - ProcessRequests(from, ImageRecord()); + ProcessRequests(from, scoped_refptr<ImageRecord>(new ImageRecord())); } void BookmarkImageService::ClearAll() { @@ -284,7 +294,7 @@ void BookmarkImageService::ClearAll() { for (std::map<const GURL, std::vector<ImageCallback>>::const_iterator it = callbacks_.begin(); it != callbacks_.end(); ++it) { - ProcessRequests(it->first, ImageRecord()); + ProcessRequests(it->first, scoped_refptr<ImageRecord>(new ImageRecord())); } in_progress_page_urls_.erase(in_progress_page_urls_.begin(), @@ -292,7 +302,7 @@ void BookmarkImageService::ClearAll() { } void BookmarkImageService::ProcessRequests(const GURL& page_url, - const ImageRecord& record) { + scoped_refptr<ImageRecord> record) { DCHECK(CalledOnValidThread()); std::vector<ImageCallback> callbacks = callbacks_[page_url]; diff --git a/components/enhanced_bookmarks/bookmark_image_service.h b/components/enhanced_bookmarks/bookmark_image_service.h index 87b14e4..9cc0b73 100644 --- a/components/enhanced_bookmarks/bookmark_image_service.h +++ b/components/enhanced_bookmarks/bookmark_image_service.h @@ -40,7 +40,7 @@ class BookmarkImageService : public KeyedService, ~BookmarkImageService() override; - typedef base::Callback<void(const ImageRecord&)> ImageCallback; + typedef base::Callback<void(scoped_refptr<ImageRecord>)> ImageCallback; // KeyedService: void Shutdown() override; @@ -89,11 +89,11 @@ class BookmarkImageService : public KeyedService, void ProcessNewImage(const GURL& page_url, bool update_bookmarks, const GURL& image_url, - const gfx::Image& image); + scoped_ptr<gfx::Image> image); // Resizes large images to proper size that fits device display. This method // should _not_ run on the UI thread. - virtual gfx::Image ResizeImage(gfx::Image image) = 0; + virtual scoped_ptr<gfx::Image> ResizeImage(const gfx::Image& image) = 0; // Sets a new image for a bookmark. If the given page_url is bookmarked and // the image is retrieved from the image_url, then the image is locally @@ -123,31 +123,32 @@ class BookmarkImageService : public KeyedService, ImageCallback stack_callback); // Processes the requests that have been waiting on an image. - void ProcessRequests(const GURL& page_url, const ImageRecord& image); + void ProcessRequests(const GURL& page_url, scoped_refptr<ImageRecord> image); // Once an image is retrieved this method calls ResizeImage() and updates the // store with the smaller image, then returns the newly formed ImageRecord. // This is typically called on |pool_|, the background sequenced worker pool // for this object. - ImageRecord ResizeAndStoreImage(const gfx::Image& image, - const GURL& image_url, - const GURL& page_url); + scoped_refptr<ImageRecord> ResizeAndStoreImage( + scoped_refptr<ImageRecord> image_info, + const GURL& page_url); // Calls |StoreImage| in the background. This should only be called from the // main thread. - void PostTaskToStoreImage(const gfx::Image& image, + void PostTaskToStoreImage(scoped_ptr<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); + void OnStoreImagePosted(const GURL& page_url, + scoped_refptr<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, ImageCallback original_callback, - const ImageRecord& record); + scoped_refptr<ImageRecord> record); // Remove the image stored for this bookmark (if it exists). Called when a // bookmark is deleted. diff --git a/components/enhanced_bookmarks/image_record.cc b/components/enhanced_bookmarks/image_record.cc new file mode 100644 index 0000000..2e380f0 --- /dev/null +++ b/components/enhanced_bookmarks/image_record.cc @@ -0,0 +1,28 @@ +// 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. + +#include "components/enhanced_bookmarks/image_record.h" + +namespace enhanced_bookmarks { + +ImageRecord::ImageRecord(scoped_ptr<gfx::Image> image, + const GURL& url, + SkColor dominant_color) + : image(image.Pass()), + url(url), + dominant_color(dominant_color) { +} + +ImageRecord::ImageRecord(scoped_ptr<gfx::Image> image, const GURL& url) + : ImageRecord(image.Pass(), url, SK_ColorBLACK) { +} + +ImageRecord::ImageRecord() + : ImageRecord(scoped_ptr<gfx::Image>(new gfx::Image()), GURL()) { +} + +ImageRecord::~ImageRecord() { +} + +} // namespace enhanced_bookmarks diff --git a/components/enhanced_bookmarks/image_record.h b/components/enhanced_bookmarks/image_record.h index dde3251..e93f3b8 100644 --- a/components/enhanced_bookmarks/image_record.h +++ b/components/enhanced_bookmarks/image_record.h @@ -5,6 +5,7 @@ #ifndef COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_RECORD_H_ #define COMPONENTS_ENHANCED_BOOKMARKS_IMAGE_RECORD_H_ +#include "base/memory/ref_counted.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/image/image.h" #include "url/gurl.h" @@ -12,17 +13,25 @@ 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) {} +class ImageRecord : public base::RefCountedThreadSafe<ImageRecord> { + public: + ImageRecord(scoped_ptr<gfx::Image> image, + const GURL& url, + SkColor dominant_color); + ImageRecord(scoped_ptr<gfx::Image> image, const GURL& url); + ImageRecord(); // The image data. - gfx::Image image; + scoped_ptr<gfx::Image> image; // The URL that hosts the image. GURL url; // The dominant color of the image. SkColor dominant_color; + + private: + friend class base::RefCountedThreadSafe<ImageRecord>; + + ~ImageRecord(); }; } // namespace enhanced_bookmarks diff --git a/components/enhanced_bookmarks/image_store.cc b/components/enhanced_bookmarks/image_store.cc index a370578..c0759c1 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; - const enhanced_bookmarks::ImageRecord& record = Get(from); + scoped_refptr<enhanced_bookmarks::ImageRecord> record = Get(from); Erase(from); Insert(to, record); } diff --git a/components/enhanced_bookmarks/image_store.h b/components/enhanced_bookmarks/image_store.h index f4c63fa..e92ba5a 100644 --- a/components/enhanced_bookmarks/image_store.h +++ b/components/enhanced_bookmarks/image_store.h @@ -27,8 +27,9 @@ class ImageStore { // 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 enhanced_bookmarks::ImageRecord& image_record) = 0; + virtual void Insert( + const GURL& page_url, + scoped_refptr<enhanced_bookmarks::ImageRecord> image_record) = 0; // Removes an image from the store. virtual void Erase(const GURL& page_url) = 0; @@ -38,7 +39,8 @@ class ImageStore { // 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; + virtual scoped_refptr<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 19dd5fa..a22a366 100644 --- a/components/enhanced_bookmarks/image_store_ios_unittest.mm +++ b/components/enhanced_bookmarks/image_store_ios_unittest.mm @@ -22,7 +22,8 @@ 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(const gfx::Size& size, float scale) { +scoped_ptr<gfx::Image> GenerateRandomUIImage(const gfx::Size& size, + float scale) { UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width(), size.height()), YES, // opaque. @@ -56,7 +57,7 @@ gfx::Image GenerateRandomUIImage(const gfx::Size& size, float scale) { kCGGradientDrawsAfterEndLocation); UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); - return gfx::Image([image retain]); + return scoped_ptr<gfx::Image>(new gfx::Image([image retain])); } // Returns true if the two images are identical. @@ -141,15 +142,18 @@ TYPED_TEST(ImageStoreUnitTestIOS, StoringImagesPreservesScale) { const gfx::Size image_size(42, 24); for (unsigned long i = 0; i < arraysize(scales); i++) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image_in( - GenerateRandomUIImage(image_size, scales[i]), GURL("http://a.jpg"), - SK_ColorGREEN); + scoped_refptr<enhanced_bookmarks::ImageRecord> image_in( + new enhanced_bookmarks::ImageRecord( + 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); + scoped_refptr<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); + 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 e0d5ace..043c5f2 100644 --- a/components/enhanced_bookmarks/image_store_unittest.cc +++ b/components/enhanced_bookmarks/image_store_unittest.cc @@ -19,29 +19,31 @@ namespace { -gfx::Image CreateImage(int width, int height, int a, int r, int g, int b) { +scoped_ptr<gfx::Image> CreateImage( + int width, int height, int a, int r, int g, int b) { SkBitmap bitmap; bitmap.allocN32Pixels(width, height); bitmap.eraseARGB(a, r, g, b); - gfx::Image image(gfx::Image::CreateFrom1xBitmap(bitmap)); + scoped_ptr<gfx::Image> image( + new gfx::Image(gfx::Image::CreateFrom1xBitmap(bitmap))); #if defined(OS_IOS) // Make sure the image has a kImageRepCocoaTouch. - image.ToUIImage(); + image->ToUIImage(); #endif // defined(OS_IOS) return image; } -gfx::Image GenerateWhiteImage() { +scoped_ptr<gfx::Image> GenerateWhiteImage() { return CreateImage(42, 24, 255, 255, 255, 255); } -gfx::Image GenerateBlackImage(int width, int height) { +scoped_ptr<gfx::Image> GenerateBlackImage(int width, int height) { return CreateImage(width, height, 255, 0, 0, 0); } -gfx::Image GenerateBlackImage() { +scoped_ptr<gfx::Image> GenerateBlackImage() { return GenerateBlackImage(42, 24); } @@ -97,7 +99,7 @@ bool CreateV1PersistentImageStoreDB(const base::FilePath& path) { statement.BindString(0, "foo://bar"); statement.BindString(1, "http://a.jpg"); scoped_refptr<base::RefCountedMemory> image_bytes = - enhanced_bookmarks::BytesForImage(GenerateWhiteImage()); + enhanced_bookmarks::BytesForImage(*GenerateWhiteImage()); statement.BindBlob(2, image_bytes->front(), (int)image_bytes->size()); statement.BindInt(3, 42); statement.BindInt(4, 24); @@ -170,8 +172,9 @@ TYPED_TEST(ImageStoreUnitTest, StartsEmpty) { } TYPED_TEST(ImageStoreUnitTest, StoreOne) { - const enhanced_bookmarks::ImageRecord image( - GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> image( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK)); this->store_->Insert(GURL("foo://bar"), image); std::set<GURL> all_urls; @@ -183,24 +186,27 @@ TYPED_TEST(ImageStoreUnitTest, StoreOne) { TYPED_TEST(ImageStoreUnitTest, Retrieve) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image_in( - CreateImage(42, 24, 1, 0, 0, 1), GURL("http://a.jpg"), SK_ColorBLUE); + scoped_refptr<enhanced_bookmarks::ImageRecord> image_in( + new enhanced_bookmarks::ImageRecord( + 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); + scoped_refptr<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); + 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) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image( - GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> image( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK)); this->store_->Insert(url, image); this->store_->Erase(url); @@ -212,12 +218,14 @@ TYPED_TEST(ImageStoreUnitTest, Erase) { TYPED_TEST(ImageStoreUnitTest, ClearAll) { const GURL url_foo("http://foo"); - const enhanced_bookmarks::ImageRecord black_image( - GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> black_image( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK)); this->store_->Insert(url_foo, black_image); const GURL url_bar("http://bar"); - const enhanced_bookmarks::ImageRecord white_image( - GenerateWhiteImage(), GURL("http://a.jpg"), SK_ColorWHITE); + scoped_refptr<enhanced_bookmarks::ImageRecord> white_image( + new enhanced_bookmarks::ImageRecord( + GenerateWhiteImage(), GURL("http://a.jpg"), SK_ColorWHITE)); this->store_->Insert(url_bar, white_image); this->store_->ClearAll(); @@ -231,29 +239,34 @@ TYPED_TEST(ImageStoreUnitTest, ClearAll) { TYPED_TEST(ImageStoreUnitTest, Update) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image1(GenerateWhiteImage(), - GURL("1.jpg"), SK_ColorWHITE); + + scoped_refptr<enhanced_bookmarks::ImageRecord> image1( + new enhanced_bookmarks::ImageRecord( + GenerateWhiteImage(), GURL("1.jpg"), SK_ColorWHITE)); this->store_->Insert(url, image1); - const enhanced_bookmarks::ImageRecord image2(GenerateBlackImage(), - GURL("2.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> image2( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("2.jpg"), SK_ColorBLACK)); this->store_->Insert(url, image2); - const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); + scoped_refptr<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(image2.url, image_out.url); - EXPECT_TRUE(CompareImages(image2.image, image_out.image)); - EXPECT_EQ(SK_ColorBLACK, image_out.dominant_color); + 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) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image_in( - GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> image_in( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK)); this->store_->Insert(url, image_in); this->ResetStore(); @@ -263,11 +276,12 @@ TYPED_TEST(ImageStoreUnitTest, Persistence) { EXPECT_EQ(1u, all_urls.size()); EXPECT_EQ(url, *all_urls.begin()); EXPECT_TRUE(this->store_->HasKey(url)); - const enhanced_bookmarks::ImageRecord image_out = this->store_->Get(url); + scoped_refptr<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); + 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); @@ -285,15 +299,16 @@ TYPED_TEST(ImageStoreUnitTest, MigrationToV2) { EXPECT_TRUE(CreateV1PersistentImageStoreDB(this->tempDir_.path().Append( base::FilePath::FromUTF8Unsafe("BookmarkImageAndUrlStore.db")))); - const enhanced_bookmarks::ImageRecord image_out = + scoped_refptr<enhanced_bookmarks::ImageRecord> image_out = this->store_->Get(GURL("foo://bar")); - EXPECT_EQ(SK_ColorWHITE, image_out.dominant_color); + EXPECT_EQ(SK_ColorWHITE, image_out->dominant_color); } TYPED_TEST(ImageStoreUnitTest, GetSize) { const GURL url("foo://bar"); - const enhanced_bookmarks::ImageRecord image_in( - GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK); + scoped_refptr<enhanced_bookmarks::ImageRecord> image_in( + new enhanced_bookmarks::ImageRecord( + GenerateBlackImage(), GURL("http://a.jpg"), SK_ColorBLACK)); int64 size = 0; if (this->use_persistent_store()) { diff --git a/components/enhanced_bookmarks/persistent_image_store.cc b/components/enhanced_bookmarks/persistent_image_store.cc index 1061b69..69365ab 100644 --- a/components/enhanced_bookmarks/persistent_image_store.cc +++ b/components/enhanced_bookmarks/persistent_image_store.cc @@ -163,7 +163,7 @@ bool PersistentImageStore::HasKey(const GURL& page_url) { void PersistentImageStore::Insert( const GURL& page_url, - const enhanced_bookmarks::ImageRecord& record) { + scoped_refptr<enhanced_bookmarks::ImageRecord> record) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); if (OpenDatabase() != sql::INIT_OK) return; @@ -176,10 +176,10 @@ void PersistentImageStore::Insert( "VALUES (?, ?, ?, ?, ?, ?)")); statement.BindString(0, page_url.possibly_invalid_spec()); - statement.BindString(1, record.url.possibly_invalid_spec()); + statement.BindString(1, record->url.possibly_invalid_spec()); scoped_refptr<base::RefCountedMemory> image_bytes = - enhanced_bookmarks::BytesForImage(record.image); + enhanced_bookmarks::BytesForImage(*record->image); // Insert an empty image in case encoding fails. if (!image_bytes.get()) @@ -189,9 +189,9 @@ void PersistentImageStore::Insert( statement.BindBlob(2, image_bytes->front(), (int)image_bytes->size()); - statement.BindInt(3, record.image.Size().width()); - statement.BindInt(4, record.image.Size().height()); - statement.BindInt(5, record.dominant_color); + statement.BindInt(3, record->image->Size().width()); + statement.BindInt(4, record->image->Size().height()); + statement.BindInt(5, record->dominant_color); statement.Run(); } @@ -206,10 +206,11 @@ void PersistentImageStore::Erase(const GURL& page_url) { statement.Run(); } -enhanced_bookmarks::ImageRecord PersistentImageStore::Get( +scoped_refptr<enhanced_bookmarks::ImageRecord> PersistentImageStore::Get( const GURL& page_url) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); - enhanced_bookmarks::ImageRecord image_record; + scoped_refptr<enhanced_bookmarks::ImageRecord> image_record( + new enhanced_bookmarks::ImageRecord()); if (OpenDatabase() != sql::INIT_OK) return image_record; @@ -231,21 +232,21 @@ enhanced_bookmarks::ImageRecord PersistentImageStore::Get( 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); + *image_record->image = enhanced_bookmarks::ImageForBytes(data); } // URL. - image_record.url = GURL(statement.ColumnString(1)); + 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)); + 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); + image_record->dominant_color = + enhanced_bookmarks::DominantColorForImage(*image_record->image); stored_image_record_needs_update = true; } diff --git a/components/enhanced_bookmarks/persistent_image_store.h b/components/enhanced_bookmarks/persistent_image_store.h index 5a0c41d..d6f12f35 100644 --- a/components/enhanced_bookmarks/persistent_image_store.h +++ b/components/enhanced_bookmarks/persistent_image_store.h @@ -20,9 +20,10 @@ class PersistentImageStore : public ImageStore { explicit PersistentImageStore(const base::FilePath& path); bool HasKey(const GURL& page_url) override; void Insert(const GURL& page_url, - const enhanced_bookmarks::ImageRecord& image) override; + scoped_refptr<enhanced_bookmarks::ImageRecord> image) override; void Erase(const GURL& page_url) override; - enhanced_bookmarks::ImageRecord Get(const GURL& page_url) override; + scoped_refptr<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; diff --git a/components/enhanced_bookmarks/test_image_store.cc b/components/enhanced_bookmarks/test_image_store.cc index 9b11cdf..28c8de0 100644 --- a/components/enhanced_bookmarks/test_image_store.cc +++ b/components/enhanced_bookmarks/test_image_store.cc @@ -17,12 +17,13 @@ bool TestImageStore::HasKey(const GURL& page_url) { return store_.find(page_url) != store_.end(); } -void TestImageStore::Insert(const GURL& page_url, - const enhanced_bookmarks::ImageRecord& image) { +void TestImageStore::Insert( + const GURL& page_url, + scoped_refptr<enhanced_bookmarks::ImageRecord> image_record) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); Erase(page_url); - store_.insert(std::make_pair(page_url, image)); + store_.insert(std::make_pair(page_url, image_record)); } void TestImageStore::Erase(const GURL& page_url) { @@ -31,11 +32,14 @@ void TestImageStore::Erase(const GURL& page_url) { store_.erase(page_url); } -enhanced_bookmarks::ImageRecord TestImageStore::Get(const GURL& page_url) { +scoped_refptr<enhanced_bookmarks::ImageRecord> TestImageStore::Get( + const GURL& page_url) { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); - if (store_.find(page_url) == store_.end()) - return enhanced_bookmarks::ImageRecord(); + if (store_.find(page_url) == store_.end()) { + return scoped_refptr<enhanced_bookmarks::ImageRecord>( + new enhanced_bookmarks::ImageRecord()); + } return store_[page_url]; } @@ -47,7 +51,7 @@ gfx::Size TestImageStore::GetSize(const GURL& page_url) { if (pair_enumerator == store_.end()) return gfx::Size(); - return store_[page_url].image.Size(); + return store_[page_url]->image->Size(); } void TestImageStore::GetAllPageUrls(std::set<GURL>* urls) { @@ -72,10 +76,10 @@ int64 TestImageStore::GetStoreSizeInBytes() { size += sizeof(it->first); size += it->first.spec().length(); size += sizeof(it->second); - SkBitmap bitmap = it->second.image.AsBitmap(); + SkBitmap bitmap = it->second->image->AsBitmap(); size += bitmap.getSize(); - size += it->second.url.spec().length(); - size += sizeof(it->second.dominant_color); + 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 460a285..e74d25b 100644 --- a/components/enhanced_bookmarks/test_image_store.h +++ b/components/enhanced_bookmarks/test_image_store.h @@ -14,10 +14,12 @@ class TestImageStore : public ImageStore { public: TestImageStore(); bool HasKey(const GURL& page_url) override; - void Insert(const GURL& page_url, - const enhanced_bookmarks::ImageRecord& image) override; + void Insert( + const GURL& page_url, + scoped_refptr<enhanced_bookmarks::ImageRecord> image_record) override; void Erase(const GURL& page_url) override; - enhanced_bookmarks::ImageRecord Get(const GURL& page_url) override; + scoped_refptr<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; @@ -27,7 +29,8 @@ class TestImageStore : public ImageStore { ~TestImageStore() override; private: - typedef std::map<const GURL, enhanced_bookmarks::ImageRecord> ImageMap; + typedef std::map<const GURL, scoped_refptr<enhanced_bookmarks::ImageRecord>> + ImageMap; ImageMap store_; DISALLOW_COPY_AND_ASSIGN(TestImageStore); |