Index: components/suggestions/image_manager.cc |
diff --git a/components/suggestions/image_manager.cc b/components/suggestions/image_manager.cc |
index 2837e632bae4cc0c2174377d885fc840755031f4..329b4d9f3f2829f5608323ac12195288102b4d1b 100644 |
--- a/components/suggestions/image_manager.cc |
+++ b/components/suggestions/image_manager.cc |
@@ -5,20 +5,35 @@ |
#include "components/suggestions/image_manager.h" |
#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/task_runner_util.h" |
#include "components/suggestions/image_encoder.h" |
#include "components/suggestions/image_fetcher.h" |
using leveldb_proto::ProtoDatabase; |
+namespace { |
+ |
+scoped_ptr<SkBitmap> DecodeImage( |
+ scoped_refptr<base::RefCountedMemory> encoded_data) { |
+ return scoped_ptr<SkBitmap>(suggestions::DecodeJPEGToSkBitmap( |
+ encoded_data->front(), encoded_data->size())); |
+} |
+ |
+} // namespace |
+ |
namespace suggestions { |
ImageManager::ImageManager() : weak_ptr_factory_(this) {} |
-ImageManager::ImageManager(scoped_ptr<ImageFetcher> image_fetcher, |
- scoped_ptr<ProtoDatabase<ImageData> > database, |
- const base::FilePath& database_dir) |
+ImageManager::ImageManager( |
+ scoped_ptr<ImageFetcher> image_fetcher, |
+ scoped_ptr<ProtoDatabase<ImageData>> database, |
+ const base::FilePath& database_dir, |
+ scoped_refptr<base::TaskRunner> background_task_runner) |
: image_fetcher_(image_fetcher.Pass()), |
database_(database.Pass()), |
+ background_task_runner_(background_task_runner), |
database_ready_(false), |
weak_ptr_factory_(this) { |
image_fetcher_->SetImageFetcherDelegate(this); |
@@ -95,57 +110,68 @@ void ImageManager::QueueCacheRequest( |
} |
} |
-void ImageManager::ServeFromCacheOrNetwork( |
- const GURL& url, const GURL& image_url, |
- base::Callback<void(const GURL&, const SkBitmap*)> callback) { |
- // If there is a image available in memory, return it. |
- if (!ServeFromCache(url, callback)) { |
+void ImageManager::OnCacheImageDecoded( |
+ const GURL& url, |
+ const GURL& image_url, |
+ base::Callback<void(const GURL&, const SkBitmap*)> callback, |
+ scoped_ptr<SkBitmap> bitmap) { |
+ if (bitmap.get()) { |
+ callback.Run(url, bitmap.get()); |
+ } else { |
image_fetcher_->StartOrQueueNetworkRequest(url, image_url, callback); |
} |
} |
-bool ImageManager::ServeFromCache( |
- const GURL& url, |
- base::Callback<void(const GURL&, const SkBitmap*)> callback) { |
- SkBitmap* bitmap = GetBitmapFromCache(url); |
- if (bitmap) { |
- callback.Run(url, bitmap); |
- return true; |
+scoped_refptr<base::RefCountedMemory> ImageManager::GetEncodedImageFromCache( |
+ const GURL& url) { |
+ ImageMap::iterator image_iter = image_map_.find(url.spec()); |
+ if (image_iter != image_map_.end()) { |
+ return image_iter->second; |
} |
- return false; |
+ return nullptr; |
} |
-SkBitmap* ImageManager::GetBitmapFromCache(const GURL& url) { |
- ImageMap::iterator image_iter = image_map_.find(url.spec()); |
- if (image_iter != image_map_.end()) { |
- return &image_iter->second; |
+void ImageManager::ServeFromCacheOrNetwork( |
+ const GURL& url, |
+ const GURL& image_url, |
+ base::Callback<void(const GURL&, const SkBitmap*)> callback) { |
+ scoped_refptr<base::RefCountedMemory> encoded_data = |
+ GetEncodedImageFromCache(url); |
+ if (encoded_data.get()) { |
+ base::PostTaskAndReplyWithResult( |
+ background_task_runner_.get(), FROM_HERE, |
+ base::Bind(&DecodeImage, encoded_data), |
+ base::Bind(&ImageManager::OnCacheImageDecoded, |
+ weak_ptr_factory_.GetWeakPtr(), url, image_url, callback)); |
+ } else { |
+ image_fetcher_->StartOrQueueNetworkRequest(url, image_url, callback); |
} |
- return NULL; |
} |
void ImageManager::SaveImage(const GURL& url, const SkBitmap& bitmap) { |
+ scoped_refptr<base::RefCountedBytes> encoded_data( |
+ new base::RefCountedBytes()); |
+ if (!EncodeSkBitmapToJPEG(bitmap, &encoded_data->data())) { |
+ return; |
+ } |
+ |
// Update the image map. |
- image_map_.insert(std::make_pair(url.spec(), bitmap)); |
+ image_map_.insert({url.spec(), encoded_data}); |
if (!database_ready_) return; |
- // Attempt to save a JPEG representation to the database. If not successful, |
- // the fetched bitmap will still be inserted in the cache, above. |
- std::vector<unsigned char> encoded_data; |
- if (EncodeSkBitmapToJPEG(bitmap, &encoded_data)) { |
- // Save the resulting bitmap to the database. |
- ImageData data; |
- data.set_url(url.spec()); |
- data.set_data(std::string(encoded_data.begin(), encoded_data.end())); |
- scoped_ptr<ProtoDatabase<ImageData>::KeyEntryVector> entries_to_save( |
- new ProtoDatabase<ImageData>::KeyEntryVector()); |
- scoped_ptr<std::vector<std::string> > keys_to_remove( |
- new std::vector<std::string>()); |
- entries_to_save->push_back(std::make_pair(data.url(), data)); |
- database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), |
- base::Bind(&ImageManager::OnDatabaseSave, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
+ // Save the resulting bitmap to the database. |
+ ImageData data; |
+ data.set_url(url.spec()); |
+ data.set_data(encoded_data->front(), encoded_data->size()); |
+ scoped_ptr<ProtoDatabase<ImageData>::KeyEntryVector> entries_to_save( |
+ new ProtoDatabase<ImageData>::KeyEntryVector()); |
+ scoped_ptr<std::vector<std::string>> keys_to_remove( |
+ new std::vector<std::string>()); |
+ entries_to_save->push_back(std::make_pair(data.url(), data)); |
+ database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), |
+ base::Bind(&ImageManager::OnDatabaseSave, |
+ weak_ptr_factory_.GetWeakPtr())); |
} |
void ImageManager::OnDatabaseInit(bool success) { |
@@ -187,10 +213,8 @@ void ImageManager::LoadEntriesInCache(scoped_ptr<ImageDataVector> entries) { |
std::vector<unsigned char> encoded_data(it->data().begin(), |
it->data().end()); |
- scoped_ptr<SkBitmap> bitmap(DecodeJPEGToSkBitmap(encoded_data)); |
- if (bitmap.get()) { |
- image_map_.insert(std::make_pair(it->url(), *bitmap)); |
- } |
+ image_map_.insert( |
+ {it->url(), base::RefCountedBytes::TakeVector(&encoded_data)}); |
} |
} |