From 449478308895f2f09eacfb4971b9917627aa3152 Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Tue, 9 Jun 2009 20:04:28 +0000 Subject: Modified ThumbnailStore to cache/store JPEGs instead of SkBitmaps. Add command line flag "--thumbnail-store" to enable using the ThumbnailStore facility instead of the current ThumbnailDatabase. Original review: http://codereview.chromium.org/118409 Patch by Meelap Shah git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17971 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser.vcproj | 8 ++ chrome/browser/dom_ui/dom_ui_thumbnail_source.cc | 22 ++++ chrome/browser/profile.cc | 13 +++ chrome/browser/profile.h | 7 +- chrome/browser/tab_contents/tab_contents.cc | 14 ++- chrome/browser/thumbnail_store.cc | 134 ++++++++++++----------- chrome/browser/thumbnail_store.h | 18 +-- chrome/browser/thumbnail_store_unittest.cc | 75 ++++++------- chrome/chrome.gyp | 3 + chrome/common/chrome_switches.cc | 4 + chrome/common/chrome_switches.h | 2 + chrome/test/testing_profile.h | 5 + chrome/test/unit/unittests.vcproj | 4 + 13 files changed, 185 insertions(+), 124 deletions(-) diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index b20ce97..c6bbe8b 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -2805,6 +2805,14 @@ > + + + + diff --git a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc index df9c675..9f3d175 100644 --- a/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc +++ b/chrome/browser/dom_ui/dom_ui_thumbnail_source.cc @@ -5,10 +5,15 @@ #include "chrome/browser/dom_ui/dom_ui_thumbnail_source.h" #include "app/resource_bundle.h" +#include "base/command_line.h" +#include "base/gfx/jpeg_codec.h" #include "chrome/browser/profile.h" +#include "chrome/browser/thumbnail_store.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" #include "grit/theme_resources.h" +#include "third_party/skia/include/core/SkBitmap.h" DOMUIThumbnailSource::DOMUIThumbnailSource(Profile* profile) : DataSource(chrome::kChromeUIThumbnailPath, MessageLoop::current()), @@ -17,6 +22,23 @@ DOMUIThumbnailSource::DOMUIThumbnailSource(Profile* profile) void DOMUIThumbnailSource::StartDataRequest(const std::string& path, int request_id) { + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kThumbnailStore)) { + ThumbnailStore* store = profile_->GetThumbnailStore(); + RefCountedBytes* data = NULL; + + if (!store->GetPageThumbnail(GURL(path), &data)) { + if (!default_thumbnail_.get()) { + default_thumbnail_ = new RefCountedBytes; + ResourceBundle::GetSharedInstance().LoadImageResourceBytes( + IDR_DEFAULT_THUMBNAIL, &default_thumbnail_->data); + } + SendResponse(request_id, default_thumbnail_); + return; + } + SendResponse(request_id, data); + return; + } + HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); if (hs) { HistoryService::Handle handle = hs->GetPageThumbnail( diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index f493a42..b7bd98d 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -28,6 +28,7 @@ #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/spellchecker.h" #include "chrome/browser/ssl/ssl_host_state.h" +#include "chrome/browser/thumbnail_store.h" #include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/visitedlink_master.h" #include "chrome/browser/webdata/web_data_service.h" @@ -343,6 +344,10 @@ class OffTheRecordProfileImpl : public Profile, return profile_->GetSpellChecker(); } + virtual ThumbnailStore* GetThumbnailStore() { + return NULL; + } + virtual void MarkAsCleanShutdown() { } @@ -926,6 +931,14 @@ TabRestoreService* ProfileImpl::GetTabRestoreService() { return tab_restore_service_.get(); } +ThumbnailStore* ProfileImpl::GetThumbnailStore() { + if (!thumbnail_store_.get()) { + thumbnail_store_ = new ThumbnailStore; + thumbnail_store_->Init(GetPath().AppendASCII("thumbnailstore\\")); + } + return thumbnail_store_.get(); +} + void ProfileImpl::ResetTabRestoreService() { tab_restore_service_ = NULL; } diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h index d5e800f..0c6179e 100644 --- a/chrome/browser/profile.h +++ b/chrome/browser/profile.h @@ -24,6 +24,7 @@ namespace net { class ForceTLSState; } class BookmarkModel; +class BrowserThemeProvider; class ChromeURLRequestContext; class DownloadManager; class Extension; @@ -40,7 +41,7 @@ class SQLitePersistentCookieStore; class TabRestoreService; class TemplateURLFetcher; class TemplateURLModel; -class BrowserThemeProvider; +class ThumbnailStore; class URLRequestContext; class UserScriptMaster; class VisitedLinkMaster; @@ -190,6 +191,8 @@ class Profile { // Returns or creates the ThemeProvider associated with this profile virtual ThemeProvider* GetThemeProvider() = 0; + virtual ThumbnailStore* GetThumbnailStore() = 0; + // Returns the request context information associated with this profile. Call // this only on the UI thread, since it can send notifications that should // happen on the UI thread. @@ -327,6 +330,7 @@ class ProfileImpl : public Profile, virtual void SetTheme(Extension* extension); virtual void ClearTheme(); virtual ThemeProvider* GetThemeProvider(); + virtual ThumbnailStore* GetThumbnailStore(); virtual bool HasCreatedDownloadManager() const; virtual URLRequestContext* GetRequestContext(); virtual URLRequestContext* GetRequestContextForMedia(); @@ -391,6 +395,7 @@ class ProfileImpl : public Profile, scoped_ptr ssl_host_state_; scoped_ptr force_tls_state_; scoped_ptr prefs_; + scoped_refptr thumbnail_store_; scoped_ptr template_url_fetcher_; scoped_ptr template_url_model_; scoped_ptr bookmark_bar_model_; diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index db21d93..a39f7eb 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -37,6 +37,7 @@ #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/thumbnail_store.h" #include "chrome/browser/search_engines/template_url_fetcher.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/chrome_switches.h" @@ -1633,10 +1634,15 @@ void TabContents::UpdateThumbnail(const GURL& url, const SkBitmap& bitmap, const ThumbnailScore& score) { // Tell History about this thumbnail - HistoryService* hs; - if (!profile()->IsOffTheRecord() && - (hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS))) { - hs->SetPageThumbnail(url, bitmap, score); + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kThumbnailStore)) { + profile()->GetThumbnailStore()-> + SetPageThumbnail(url, bitmap, score, !profile()->IsOffTheRecord()); + } else { + HistoryService* hs; + if (!profile()->IsOffTheRecord() && + (hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS))) { + hs->SetPageThumbnail(url, bitmap, score); + } } } diff --git a/chrome/browser/thumbnail_store.cc b/chrome/browser/thumbnail_store.cc index 1745431..c599c20 100644 --- a/chrome/browser/thumbnail_store.cc +++ b/chrome/browser/thumbnail_store.cc @@ -23,62 +23,57 @@ ThumbnailStore::~ThumbnailStore() { } void ThumbnailStore::Init(const FilePath& file_path) { - file_path_ = file_path.DirName(); + file_path_ = file_path; g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &ThumbnailStore::GetAllThumbnailsFromDisk, file_path_, MessageLoop::current())); } -void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) { - if (cache) { - cache_.reset(cache); - cache_initialized_ = true; - } -} - void ThumbnailStore::GetAllThumbnailsFromDisk(FilePath filepath, MessageLoop* cb_loop) { - // Create the specified directory if it does not exist. - if (!file_util::DirectoryExists(filepath) && - !file_util::CreateDirectory(filepath)) - return; - - // Walk the directory and read the thumbnail data from disk. - FilePath path; - GURL url; - SkBitmap image; - ThumbnailScore score; ThumbnailStore::Cache* cache = new ThumbnailStore::Cache; - file_util::FileEnumerator fenum(filepath, false, - file_util::FileEnumerator::FILES); - while (!(path = fenum.Next()).empty()) { - if (GetPageThumbnailFromDisk(path, &url, &image, &score)) - (*cache)[url] = std::make_pair(image, score); + // Create the specified directory if it does not exist. + if (!file_util::DirectoryExists(filepath)) { + file_util::CreateDirectory(filepath); + } else { + // Walk the directory and read the thumbnail data from disk. + FilePath path; + GURL url; + RefCountedBytes* data = new RefCountedBytes; + ThumbnailScore score; + file_util::FileEnumerator fenum(filepath, false, + file_util::FileEnumerator::FILES); + + while (!(path = fenum.Next()).empty()) { + if (GetPageThumbnailFromDisk(path, &url, data, &score)) + (*cache)[url] = std::make_pair(data, score); + } } - cb_loop->PostTask(FROM_HERE, NewRunnableMethod(this, &ThumbnailStore::OnDiskDataAvailable, cache)); } bool ThumbnailStore::GetPageThumbnailFromDisk(const FilePath& file, - GURL* url, SkBitmap* thumbnail, + GURL* url, + RefCountedBytes* data, ThumbnailScore* score) const { int64 file_size; if (!file_util::GetFileSize(file, &file_size)) return false; // Read the file into a buffer. - std::vector data; - data.resize(static_cast(file_size)); - if (file_util::ReadFile(file, &data[0], static_cast(file_size)) == -1) + std::vector file_data; + file_data.resize(static_cast(file_size)); + if (file_util::ReadFile(file, &file_data[0], + static_cast(file_size)) == -1) return false; // Unpack the url, ThumbnailScore and JPEG size from the buffer. std::string url_string; unsigned int jpeg_len; void* iter = NULL; - Pickle packed(&data[0], static_cast(file_size)); + Pickle packed(&file_data[0], static_cast(file_size)); if (!packed.ReadString(&iter, &url_string) || !UnpackScore(score, packed, iter) || @@ -90,25 +85,28 @@ bool ThumbnailStore::GetPageThumbnailFromDisk(const FilePath& file, url->Swap(&temp_url); // Unpack the JPEG data from the buffer. - if (thumbnail) { - const char* jpeg_data = NULL; - int out_len; - - if (!packed.ReadData(&iter, &jpeg_data, &out_len) || - out_len != jpeg_len) - return false; - - // Convert the jpeg_data to an SkBitmap. - SkBitmap* thumbnail_ = JPEGCodec::Decode( - reinterpret_cast(jpeg_data), jpeg_len); - *thumbnail = *thumbnail_; - delete thumbnail_; - } + const char* jpeg_data = NULL; + int out_len; + + if (!packed.ReadData(&iter, &jpeg_data, &out_len) || + out_len != jpeg_len) + return false; + + // Copy jpeg data to the out parameter. + data->data.resize(jpeg_len); + memcpy(&data->data[0], jpeg_data, jpeg_len); return true; } +void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) { + if (cache) { + cache_.reset(cache); + cache_initialized_ = true; + } +} + bool ThumbnailStore::SetPageThumbnail(const GURL& url, - SkBitmap& thumbnail, + const SkBitmap& thumbnail, const ThumbnailScore& score, bool write_to_disk) { if (!cache_initialized_) @@ -119,8 +117,26 @@ bool ThumbnailStore::SetPageThumbnail(const GURL& url, !ShouldReplaceThumbnailWith((*cache_)[url].second, score)) return true; + base::TimeTicks encode_start = base::TimeTicks::Now(); + + // Encode the SkBitmap to jpeg and add to cache. + RefCountedBytes* jpeg_data = new RefCountedBytes; + SkAutoLockPixels thumbnail_lock(thumbnail); + bool encoded = JPEGCodec::Encode( + reinterpret_cast(thumbnail.getAddr32(0, 0)), + JPEGCodec::FORMAT_BGRA, thumbnail.width(), + thumbnail.height(), + static_cast(thumbnail.rowBytes()), 90, + &jpeg_data->data); + + base::TimeDelta delta = base::TimeTicks::Now() - encode_start; + HISTOGRAM_TIMES("Thumbnail.Encode", delta); + + if (!encoded) + return false; + // Update the cache_ with the new thumbnail. - (*cache_)[url] = std::make_pair(thumbnail, score); + (*cache_)[url] = std::make_pair(jpeg_data, score); // Write the new thumbnail data to disk in the background on file_thread. if (write_to_disk) { @@ -134,27 +150,14 @@ bool ThumbnailStore::WriteThumbnailToDisk(const GURL& url) const { // Thumbnail data will be stored in a file named url.host(). FilePath file = file_path_.AppendASCII(url.host()); Pickle packed; - SkBitmap thumbnail = (*cache_)[url].first; + scoped_refptr data((*cache_)[url].first); ThumbnailScore score = (*cache_)[url].second; - // Convert the SkBitmap to a JPEG. - std::vector jpeg_data; - SkAutoLockPixels thumbnail_lock(thumbnail); - bool encoded = JPEGCodec::Encode( - reinterpret_cast(thumbnail.getAddr32(0, 0)), - JPEGCodec::FORMAT_BGRA, thumbnail.width(), - thumbnail.height(), - static_cast(thumbnail.rowBytes()), 90, - &jpeg_data); - - if (!encoded) - return false; - // Pack the url, ThumbnailScore, and the JPEG data. packed.WriteString(url.spec()); PackScore(score, &packed); - packed.WriteUInt32(jpeg_data.size()); - packed.WriteData(reinterpret_cast(&jpeg_data[0]), jpeg_data.size()); + packed.WriteUInt32(data->data.size()); + packed.WriteData(reinterpret_cast(&data->data[0]), data->data.size()); // Write the packed data to a file. file_util::Delete(file, false); @@ -163,14 +166,13 @@ bool ThumbnailStore::WriteThumbnailToDisk(const GURL& url) const { packed.size()) != -1; } -bool ThumbnailStore::GetPageThumbnail(const GURL& url, SkBitmap* thumbnail, - ThumbnailScore* score) { +bool ThumbnailStore::GetPageThumbnail(const GURL& url, RefCountedBytes** data) { if (!cache_initialized_ || cache_->find(url) == cache_->end()) return false; - *thumbnail = (*cache_)[url].first; - *score = (*cache_)[url].second; + *data = (*cache_)[url].first; + (*data)->AddRef(); return true; } @@ -178,7 +180,7 @@ void ThumbnailStore::PackScore(const ThumbnailScore& score, Pickle* packed) const { // Pack the contents of the given ThumbnailScore into the given Pickle. packed->WriteData(reinterpret_cast(&score.boring_score), - sizeof(score.boring_score)); + sizeof(score.boring_score)); packed->WriteBool(score.at_top); packed->WriteBool(score.good_clipping); packed->WriteInt64(score.time_at_snapshot.ToInternalValue()); diff --git a/chrome/browser/thumbnail_store.h b/chrome/browser/thumbnail_store.h index 46b6ae0..486f99c 100644 --- a/chrome/browser/thumbnail_store.h +++ b/chrome/browser/thumbnail_store.h @@ -11,6 +11,7 @@ #include "base/file_path.h" #include "base/message_loop.h" #include "base/ref_counted.h" +#include "chrome/common/ref_counted_util.h" #include "testing/gtest/include/gtest/gtest_prod.h" class GURL; @@ -37,23 +38,22 @@ class ThumbnailStore : public base::RefCountedThreadSafe { // If write_to_disk is true, the thumbnail data is written to disk on the // file_thread. bool SetPageThumbnail(const GURL& url, - SkBitmap& thumbnail, + const SkBitmap& thumbnail, const ThumbnailScore& score, bool write_to_disk); - // Retrieves the thumbnail and score for the given url. + // Sets *data to point to the thumbnail for the given url. // Returns false if there is not data for the given url or some other // error occurred. - bool GetPageThumbnail(const GURL& url, - SkBitmap* thumbnail, - ThumbnailScore* score); + bool GetPageThumbnail(const GURL& url, RefCountedBytes** data); private: FRIEND_TEST(ThumbnailStoreTest, RetrieveFromCache); FRIEND_TEST(ThumbnailStoreTest, RetrieveFromDisk); // Data structure used to store thumbnail data in memory. - typedef std::map > Cache; + typedef std::map, + ThumbnailScore> > Cache; // The location of the thumbnail store. FilePath file_path_; @@ -67,7 +67,7 @@ class ThumbnailStore : public base::RefCountedThreadSafe { // out parameters GURL, SkBitmap, and ThumbnailScore. bool GetPageThumbnailFromDisk(const FilePath& file, GURL* url, - SkBitmap* thumbnail, + RefCountedBytes* data, ThumbnailScore* score) const; // Once thumbnail data from the disk is available from the file_thread, @@ -86,11 +86,11 @@ class ThumbnailStore : public base::RefCountedThreadSafe { bool UnpackScore(ThumbnailScore* score, const Pickle& packed, void*& iter) const; - DISALLOW_COPY_AND_ASSIGN(ThumbnailStore); - // The Cache maintained by the object. scoped_ptr cache_; bool cache_initialized_; + + DISALLOW_COPY_AND_ASSIGN(ThumbnailStore); }; #endif // CHROME_BROWSER_THUMBNAIL_STORE_H_ diff --git a/chrome/browser/thumbnail_store_unittest.cc b/chrome/browser/thumbnail_store_unittest.cc index 53ec322..eb00993 100644 --- a/chrome/browser/thumbnail_store_unittest.cc +++ b/chrome/browser/thumbnail_store_unittest.cc @@ -12,7 +12,9 @@ #include "base/file_util.h" #include "base/gfx/jpeg_codec.h" #include "base/path_service.h" +#include "base/ref_counted.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/ref_counted_util.h" #include "chrome/common/thumbnail_score.h" #include "chrome/tools/profiles/thumbnail-inl.h" #include "googleurl/src/gurl.h" @@ -46,7 +48,8 @@ class ThumbnailStoreTest : public testing::Test { // The directory where ThumbnailStore will store data. FilePath file_path_; - SkBitmap read_image_, image_enc_dec_, image_; + SkBitmap image_; + scoped_refptr jpeg_image_; ThumbnailScore score1_, score2_; GURL url1_, url2_; base::Time time_; @@ -63,21 +66,14 @@ void ThumbnailStoreTest::SetUp() { // image is the original SkBitmap representing the thumbnail image_ = *(JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail))); - // The ThumbnailStore will encode the thumbnail to jpeg at 90% quality, so - // we do this to image. When image is stored, image_enc_dec_ is what - // ThumbnailStore should return. - std::vector jpeg_data; SkAutoLockPixels thumbnail_lock(image_); + jpeg_image_ = new RefCountedBytes; bool encoded = JPEGCodec::Encode( reinterpret_cast(image_.getAddr32(0, 0)), JPEGCodec::FORMAT_BGRA, image_.width(), image_.height(), static_cast(image_.rowBytes()), 90, - &jpeg_data); - - image_enc_dec_ = *(JPEGCodec::Decode( - reinterpret_cast(&jpeg_data[0]), - jpeg_data.size())); + &(jpeg_image_->data)); } void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) { @@ -86,15 +82,20 @@ void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) { // differences should be small since encoding was done at 90% before // writing to disk. + if (image_a->height() != image_b->height() || + image_b->width() != image_b->width() || + image_a->rowBytes() != image_b->rowBytes()) + return; + SkAutoLockPixels lock_a(*image_a); SkAutoLockPixels lock_b(*image_b); - int ppr = read_image_.rowBytesAsPixels(); + int ppr = image_a->rowBytesAsPixels(); unsigned int *a, *b; unsigned int maxv[4]; memset(maxv, 0, sizeof(maxv)); - for (int nrows = read_image_.height()-1; nrows >= 0; nrows--) { + for (int nrows = image_a->height()-1; nrows >= 0; nrows--) { a = image_a->getAddr32(0, nrows); b = image_b->getAddr32(0, nrows); for (int i = 0; i < ppr; i += 4) { @@ -114,61 +115,47 @@ void ThumbnailStoreTest::PrintPixelDiff(SkBitmap* image_a, SkBitmap* image_b) { } TEST_F(ThumbnailStoreTest, RetrieveFromCache) { - ThumbnailStore* store = new ThumbnailStore; - store->AddRef(); + RefCountedBytes* read_image = NULL; + scoped_refptr store = new ThumbnailStore; + store->file_path_ = file_path_; store->cache_.reset(new ThumbnailStore::Cache); store->cache_initialized_ = true; - read_image_.reset(); - // Retrieve a thumbnail/score for a nonexistent page. - EXPECT_FALSE(store->GetPageThumbnail(url2_, &read_image_, &score2_)); + EXPECT_FALSE(store->GetPageThumbnail(url2_, &read_image)); // Store a thumbnail into the cache and retrieve it. EXPECT_TRUE(store->SetPageThumbnail(url1_, image_, score1_, false)); - EXPECT_TRUE(store->GetPageThumbnail(url1_, &read_image_, &score2_)); - EXPECT_TRUE(score1_.Equals(score2_)); - EXPECT_TRUE(read_image_.getSize() == image_.getSize()); - EXPECT_TRUE(read_image_.pixelRef() == image_.pixelRef()); - EXPECT_FALSE(read_image_.isNull()); + EXPECT_TRUE(store->GetPageThumbnail(url1_, &read_image)); + EXPECT_TRUE(score1_.Equals((*store->cache_)[url1_].second)); + EXPECT_TRUE(read_image->data.size() == jpeg_image_->data.size()); + EXPECT_EQ(0, memcmp(&read_image->data[0], &jpeg_image_->data[0], + jpeg_image_->data.size())); - store->Release(); + read_image->Release(); } TEST_F(ThumbnailStoreTest, RetrieveFromDisk) { - ThumbnailStore* store = new ThumbnailStore; - store->AddRef(); + scoped_refptr read_image = new RefCountedBytes; + scoped_refptr store = new ThumbnailStore; + store->file_path_ = file_path_; store->cache_.reset(new ThumbnailStore::Cache); store->cache_initialized_ = true; - read_image_.reset(); - // Store a thumbnail onto the disk and retrieve it. EXPECT_TRUE(store->SetPageThumbnail(url1_, image_, score1_, false)); EXPECT_TRUE(store->WriteThumbnailToDisk(url1_)); EXPECT_TRUE(store->GetPageThumbnailFromDisk( - file_path_.AppendASCII(url1_.host()), &url2_, &read_image_, &score2_)); + file_path_.AppendASCII(url1_.host()), &url2_, read_image, &score2_)); + read_image->AddRef(); EXPECT_TRUE(url1_ == url2_); EXPECT_TRUE(score1_.Equals(score2_)); - EXPECT_TRUE(read_image_.getSize() == image_enc_dec_.getSize()); - EXPECT_FALSE(read_image_.isNull()); - - // The retrieved SkBitmap should be the same as the original image - // encoded at 90% quality to jpeg, then decoded. - - { - SkAutoLockPixels lock_a(read_image_); - SkAutoLockPixels lock_b(image_enc_dec_); - EXPECT_TRUE(0 == memcmp(read_image_.getPixels(), - image_enc_dec_.getPixels(), - read_image_.getSize())); - } - PrintPixelDiff(&read_image_, &image_); - - store->Release(); + EXPECT_TRUE(read_image->data.size() == jpeg_image_->data.size()); + EXPECT_EQ(0, memcmp(&read_image->data[0], &jpeg_image_->data[0], + jpeg_image_->data.size())); } diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 219004d..3b65c85 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1379,6 +1379,8 @@ 'browser/task_manager_resource_providers.h', 'browser/theme_resources_util.cc', 'browser/theme_resources_util.h', + 'browser/thumbnail_store.cc', + 'browser/thumbnail_store.h', 'browser/toolbar_model.cc', 'browser/toolbar_model.h', 'browser/user_data_manager.cc', @@ -3215,6 +3217,7 @@ 'browser/history/text_database_manager_unittest.cc', 'browser/history/text_database_unittest.cc', 'browser/history/thumbnail_database_unittest.cc', + 'browser/thumbnail_store_unittest.cc', 'browser/history/url_database_unittest.cc', 'browser/history/visit_database_unittest.cc', 'browser/history/visit_tracker_unittest.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index a9335ed..48511d3 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -490,4 +490,8 @@ const wchar_t kNoDefaultBrowserCheck[] = L"no-default-browser-check"; // Enables the benchmarking extensions. const wchar_t kEnableBenchmarking[] = L"enable-benchmarking"; +// Enables using ThumbnailStore instead of ThumbnailDatabase for setting and +// getting thumbnails for the new tab page. +const wchar_t kThumbnailStore[] = L"thumbnail-store"; + } // namespace switches diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 50666c8..8259d72 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -185,6 +185,8 @@ extern const wchar_t kEnableBenchmarking[]; extern const wchar_t kNoDefaultBrowserCheck[]; +extern const wchar_t kThumbnailStore[]; + } // namespace switches #endif // CHROME_COMMON_CHROME_SWITCHES_H_ diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index 40b88dd..56bfc38 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -121,6 +121,11 @@ class TestingProfile : public Profile { virtual TemplateURLFetcher* GetTemplateURLFetcher() { return NULL; } + + virtual ThumbnailStore* GetThumbnailStore() { + return NULL; + } + virtual DownloadManager* GetDownloadManager() { return NULL; } diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj index 7c91621..f80b539 100644 --- a/chrome/test/unit/unittests.vcproj +++ b/chrome/test/unit/unittests.vcproj @@ -814,6 +814,10 @@ > + + -- cgit v1.1