OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/suggestions/image_manager.h" | 5 #include "components/suggestions/image_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "components/suggestions/image_encoder.h" | 8 #include "components/suggestions/image_encoder.h" |
9 #include "components/suggestions/image_fetcher.h" | 9 #include "components/suggestions/image_fetcher.h" |
10 #include "content/public/browser/browser_thread.h" | |
10 | 11 |
11 using leveldb_proto::ProtoDatabase; | 12 using leveldb_proto::ProtoDatabase; |
12 | 13 |
14 namespace { | |
15 | |
16 scoped_ptr<SkBitmap> DecodeImage( | |
17 scoped_refptr<base::RefCountedMemory> encoded_data) { | |
18 return scoped_ptr<SkBitmap>(suggestions::DecodeJPEGToSkBitmap( | |
19 encoded_data->front(), encoded_data->size())); | |
20 } | |
21 | |
22 } // namespace | |
23 | |
13 namespace suggestions { | 24 namespace suggestions { |
14 | 25 |
15 ImageManager::ImageManager() : weak_ptr_factory_(this) {} | 26 ImageManager::ImageManager() : weak_ptr_factory_(this) {} |
16 | 27 |
17 ImageManager::ImageManager(scoped_ptr<ImageFetcher> image_fetcher, | 28 ImageManager::ImageManager(scoped_ptr<ImageFetcher> image_fetcher, |
18 scoped_ptr<ProtoDatabase<ImageData> > database, | 29 scoped_ptr<ProtoDatabase<ImageData> > database, |
19 const base::FilePath& database_dir) | 30 const base::FilePath& database_dir) |
20 : image_fetcher_(image_fetcher.Pass()), | 31 : image_fetcher_(image_fetcher.Pass()), |
21 database_(database.Pass()), | 32 database_(database.Pass()), |
22 database_ready_(false), | 33 database_ready_(false), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 request.url = url; | 99 request.url = url; |
89 request.image_url = image_url; | 100 request.image_url = image_url; |
90 request.callbacks.push_back(callback); | 101 request.callbacks.push_back(callback); |
91 pending_cache_requests_[url] = request; | 102 pending_cache_requests_[url] = request; |
92 } else { | 103 } else { |
93 // Request already queued for this url. | 104 // Request already queued for this url. |
94 it->second.callbacks.push_back(callback); | 105 it->second.callbacks.push_back(callback); |
95 } | 106 } |
96 } | 107 } |
97 | 108 |
109 void ImageManager::OnCacheImageDecoded( | |
110 const GURL& url, | |
111 const GURL& image_url, | |
112 base::Callback<void(const GURL&, const SkBitmap*)> callback, | |
113 scoped_ptr<SkBitmap> bitmap) { | |
114 if (bitmap.get()) { | |
115 callback.Run(url, bitmap.get()); | |
116 } else { | |
117 image_fetcher_->StartOrQueueNetworkRequest(url, image_url, callback); | |
118 } | |
119 } | |
120 | |
121 scoped_refptr<base::RefCountedMemory> ImageManager::GetEncodedImageFromCache( | |
122 const GURL& url) { | |
123 ImageMap::iterator image_iter = image_map_.find(url.spec()); | |
124 if (image_iter != image_map_.end()) { | |
125 return image_iter->second; | |
126 } | |
127 return nullptr; | |
128 } | |
129 | |
98 void ImageManager::ServeFromCacheOrNetwork( | 130 void ImageManager::ServeFromCacheOrNetwork( |
99 const GURL& url, const GURL& image_url, | 131 const GURL& url, const GURL& image_url, |
100 base::Callback<void(const GURL&, const SkBitmap*)> callback) { | 132 base::Callback<void(const GURL&, const SkBitmap*)> callback) { |
101 // If there is a image available in memory, return it. | 133 scoped_refptr<base::RefCountedMemory> encoded_data = |
102 if (!ServeFromCache(url, callback)) { | 134 GetEncodedImageFromCache(url); |
135 if (encoded_data.get()) { | |
136 content::BrowserThread::PostTaskAndReplyWithResult( | |
jam
2015/06/04 16:04:30
instead of adding a dependency on content just for
| |
137 content::BrowserThread::DB, FROM_HERE, | |
138 base::Bind(&DecodeImage, encoded_data), | |
139 base::Bind(&ImageManager::OnCacheImageDecoded, | |
140 weak_ptr_factory_.GetWeakPtr(), url, image_url, callback)); | |
141 } else { | |
103 image_fetcher_->StartOrQueueNetworkRequest(url, image_url, callback); | 142 image_fetcher_->StartOrQueueNetworkRequest(url, image_url, callback); |
104 } | 143 } |
105 } | 144 } |
106 | 145 |
107 bool ImageManager::ServeFromCache( | 146 void ImageManager::SaveImage(const GURL& url, const SkBitmap& bitmap) { |
108 const GURL& url, | 147 scoped_refptr<base::RefCountedBytes> encoded_data( |
109 base::Callback<void(const GURL&, const SkBitmap*)> callback) { | 148 new base::RefCountedBytes()); |
110 SkBitmap* bitmap = GetBitmapFromCache(url); | 149 if (!EncodeSkBitmapToJPEG(bitmap, &encoded_data->data())) { |
111 if (bitmap) { | 150 return; |
112 callback.Run(url, bitmap); | |
113 return true; | |
114 } | 151 } |
115 return false; | |
116 } | |
117 | 152 |
118 SkBitmap* ImageManager::GetBitmapFromCache(const GURL& url) { | |
119 ImageMap::iterator image_iter = image_map_.find(url.spec()); | |
120 if (image_iter != image_map_.end()) { | |
121 return &image_iter->second; | |
122 } | |
123 return NULL; | |
124 } | |
125 | |
126 void ImageManager::SaveImage(const GURL& url, const SkBitmap& bitmap) { | |
127 // Update the image map. | 153 // Update the image map. |
128 image_map_.insert(std::make_pair(url.spec(), bitmap)); | 154 image_map_.insert({url.spec(), encoded_data}); |
129 | 155 |
130 if (!database_ready_) return; | 156 if (!database_ready_) return; |
131 | 157 |
132 // Attempt to save a JPEG representation to the database. If not successful, | 158 // Save the resulting bitmap to the database. |
133 // the fetched bitmap will still be inserted in the cache, above. | 159 ImageData data; |
134 std::vector<unsigned char> encoded_data; | 160 data.set_url(url.spec()); |
135 if (EncodeSkBitmapToJPEG(bitmap, &encoded_data)) { | 161 data.set_data(encoded_data->front(), encoded_data->size()); |
136 // Save the resulting bitmap to the database. | 162 scoped_ptr<ProtoDatabase<ImageData>::KeyEntryVector> entries_to_save( |
137 ImageData data; | 163 new ProtoDatabase<ImageData>::KeyEntryVector()); |
138 data.set_url(url.spec()); | 164 scoped_ptr<std::vector<std::string> > keys_to_remove( |
139 data.set_data(std::string(encoded_data.begin(), encoded_data.end())); | 165 new std::vector<std::string>()); |
140 scoped_ptr<ProtoDatabase<ImageData>::KeyEntryVector> entries_to_save( | 166 entries_to_save->push_back(std::make_pair(data.url(), data)); |
141 new ProtoDatabase<ImageData>::KeyEntryVector()); | 167 database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), |
142 scoped_ptr<std::vector<std::string> > keys_to_remove( | 168 base::Bind(&ImageManager::OnDatabaseSave, |
143 new std::vector<std::string>()); | 169 weak_ptr_factory_.GetWeakPtr())); |
144 entries_to_save->push_back(std::make_pair(data.url(), data)); | |
145 database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), | |
146 base::Bind(&ImageManager::OnDatabaseSave, | |
147 weak_ptr_factory_.GetWeakPtr())); | |
148 } | |
149 } | 170 } |
150 | 171 |
151 void ImageManager::OnDatabaseInit(bool success) { | 172 void ImageManager::OnDatabaseInit(bool success) { |
152 if (!success) { | 173 if (!success) { |
153 DVLOG(1) << "Image database init failed."; | 174 DVLOG(1) << "Image database init failed."; |
154 database_.reset(); | 175 database_.reset(); |
155 ServePendingCacheRequests(); | 176 ServePendingCacheRequests(); |
156 return; | 177 return; |
157 } | 178 } |
158 database_->LoadEntries(base::Bind(&ImageManager::OnDatabaseLoad, | 179 database_->LoadEntries(base::Bind(&ImageManager::OnDatabaseLoad, |
(...skipping 21 matching lines...) Expand all Loading... | |
180 database_ready_ = false; | 201 database_ready_ = false; |
181 } | 202 } |
182 } | 203 } |
183 | 204 |
184 void ImageManager::LoadEntriesInCache(scoped_ptr<ImageDataVector> entries) { | 205 void ImageManager::LoadEntriesInCache(scoped_ptr<ImageDataVector> entries) { |
185 for (ImageDataVector::iterator it = entries->begin(); it != entries->end(); | 206 for (ImageDataVector::iterator it = entries->begin(); it != entries->end(); |
186 ++it) { | 207 ++it) { |
187 std::vector<unsigned char> encoded_data(it->data().begin(), | 208 std::vector<unsigned char> encoded_data(it->data().begin(), |
188 it->data().end()); | 209 it->data().end()); |
189 | 210 |
190 scoped_ptr<SkBitmap> bitmap(DecodeJPEGToSkBitmap(encoded_data)); | 211 image_map_.insert({ |
191 if (bitmap.get()) { | 212 it->url(), |
192 image_map_.insert(std::make_pair(it->url(), *bitmap)); | 213 base::RefCountedBytes::TakeVector(&encoded_data)}); |
193 } | |
194 } | 214 } |
195 } | 215 } |
196 | 216 |
197 void ImageManager::ServePendingCacheRequests() { | 217 void ImageManager::ServePendingCacheRequests() { |
198 for (ImageCacheRequestMap::iterator it = pending_cache_requests_.begin(); | 218 for (ImageCacheRequestMap::iterator it = pending_cache_requests_.begin(); |
199 it != pending_cache_requests_.end(); ++it) { | 219 it != pending_cache_requests_.end(); ++it) { |
200 const ImageCacheRequest& request = it->second; | 220 const ImageCacheRequest& request = it->second; |
201 for (CallbackVector::const_iterator callback_it = request.callbacks.begin(); | 221 for (CallbackVector::const_iterator callback_it = request.callbacks.begin(); |
202 callback_it != request.callbacks.end(); ++callback_it) { | 222 callback_it != request.callbacks.end(); ++callback_it) { |
203 ServeFromCacheOrNetwork(request.url, request.image_url, *callback_it); | 223 ServeFromCacheOrNetwork(request.url, request.image_url, *callback_it); |
204 } | 224 } |
205 } | 225 } |
206 } | 226 } |
207 | 227 |
208 } // namespace suggestions | 228 } // namespace suggestions |
OLD | NEW |