1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/search/suggestions/image_manager_impl.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/ref_counted_memory.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/load_flags.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/url_request/url_request_context_getter.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/gfx/codec/jpeg_codec.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing leveldb_proto::ProtoDatabase; 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// From JPEG-encoded bytes to SkBitmap. 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SkBitmap* DecodeImage(const std::vector<unsigned char>& encoded_data) { 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return gfx::JPEGCodec::Decode(&encoded_data[0], encoded_data.size()); 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace suggestions { 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::ImageManagerImpl() : weak_ptr_factory_(this) {} 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::ImageManagerImpl( 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::URLRequestContextGetter* url_request_context, 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<ProtoDatabase<ImageData> > database, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& database_dir) 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : url_request_context_(url_request_context), 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_(database.Pass()), 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_ready_(false), 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_(this) { 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) database_->Init(database_dir, base::Bind(&ImageManagerImpl::OnDatabaseInit, 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr())); 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::~ImageManagerImpl() {} 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::ImageRequest::ImageRequest() : fetcher(NULL) {} 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::ImageRequest::ImageRequest(chrome::BitmapFetcher* f) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : fetcher(f) {} 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ImageManagerImpl::ImageRequest::~ImageRequest() { delete fetcher; } 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::Initialize(const SuggestionsProfile& suggestions) { 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) image_url_map_.clear(); 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (int i = 0; i < suggestions.suggestions_size(); ++i) { 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ChromeSuggestion& suggestion = suggestions.suggestions(i); 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (suggestion.has_thumbnail()) { 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) image_url_map_[GURL(suggestion.url())] = GURL(suggestion.thumbnail()); 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::GetImageForURL( 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& url, 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Callback<void(const GURL&, const SkBitmap*)> callback) { 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If |url| is not found in |image_url_map_|, then invoke |callback| with 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // NULL since there is no associated image for this |url|. 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GURL image_url; 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!GetImageURL(url, &image_url)) { 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(url, NULL); 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |database_| can be NULL if something went wrong in initialization. 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (database_.get() && !database_ready_) { 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Once database is initialized, it will serve pending requests from either 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // cache or network. 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) QueueCacheRequest(url, image_url, callback); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ServeFromCacheOrNetwork(url, image_url, callback); 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ImageManagerImpl::GetImageURL(const GURL& url, GURL* image_url) { 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::map<GURL, GURL>::iterator it = image_url_map_.find(url); 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (it == image_url_map_.end()) return false; // Not found. 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *image_url = it->second; 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::QueueCacheRequest( 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& url, const GURL& image_url, 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Callback<void(const GURL&, const SkBitmap*)> callback) { 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // To be served when the database has loaded. 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequestMap::iterator it = pending_cache_requests_.find(url); 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it == pending_cache_requests_.end()) { 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequest request(NULL); 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request.url = url; 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) request.image_url = image_url; 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch request.callbacks.push_back(callback); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_cache_requests_[url].swap(&request); 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Request already queued for this url. 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->second.callbacks.push_back(callback); 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::ServeFromCacheOrNetwork( 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& url, const GURL& image_url, 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Callback<void(const GURL&, const SkBitmap*)> callback) { 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If there is a image available in memory, return it. 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ServeFromCache(url, callback)) { 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) StartOrQueueNetworkRequest(url, image_url, callback); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ImageManagerImpl::ServeFromCache( 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url, 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Callback<void(const GURL&, const SkBitmap*)> callback) { 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkBitmap* bitmap = GetBitmapFromCache(url); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (bitmap) { 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.Run(url, bitmap); 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SkBitmap* ImageManagerImpl::GetBitmapFromCache(const GURL& url) { 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageMap::iterator image_iter = image_map_.find(url.spec()); 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (image_iter != image_map_.end()) { 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return &image_iter->second; 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::StartOrQueueNetworkRequest( 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& url, const GURL& image_url, 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Callback<void(const GURL&, const SkBitmap*)> callback) { 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Before starting to fetch the image. Look for a request in progress for 1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |image_url|, and queue if appropriate. 1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequestMap::iterator it = pending_net_requests_.find(image_url); 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it == pending_net_requests_.end()) { 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |image_url| is not being fetched, so create a request and initiate 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the fetch. 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequest request(new chrome::BitmapFetcher(image_url, this)); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request.url = url; 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request.callbacks.push_back(callback); 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request.fetcher->Start( 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url_request_context_, std::string(), 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::LOAD_NORMAL); 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) pending_net_requests_[image_url].swap(&request); 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Request in progress. Register as an interested callback. 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it->second.callbacks.push_back(callback); 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::OnFetchComplete(const GURL image_url, 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SkBitmap* bitmap) { 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequestMap::iterator image_iter = pending_net_requests_.find(image_url); 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(image_iter != pending_net_requests_.end()); 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageRequest* request = &image_iter->second; 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Here |bitmap| could be NULL or a pointer to a bitmap which is owned by the 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // BitmapFetcher and which ceases to exist after this function. Pass the 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // un-owned pointer to the registered callbacks. 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (CallbackVector::iterator callback_iter = request->callbacks.begin(); 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_iter != request->callbacks.end(); ++callback_iter) { 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_iter->Run(request->url, bitmap); 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Save the bitmap to the in-memory model as well as the database, because it 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // is now the freshest representation of the image. 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(mathp): Handle null (no image found), possible deletion in DB. 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (bitmap) SaveImage(request->url, *bitmap); 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Erase the completed ImageRequest. 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) pending_net_requests_.erase(image_iter); 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::SaveImage(const GURL& url, const SkBitmap& bitmap) { 1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Update the image map. 1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) image_map_.insert(std::make_pair(url.spec(), bitmap)); 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!database_ready_) return; 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Attempt to save a JPEG representation to the database. If not successful, 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the fetched bitmap will still be inserted in the cache, above. 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<unsigned char> encoded_data; 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (EncodeImage(bitmap, &encoded_data)) { 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Save the resulting bitmap to the database. 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ImageData data; 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_url(url.spec()); 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data.set_data(std::string(encoded_data.begin(), encoded_data.end())); 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<ProtoDatabase<ImageData>::KeyEntryVector> entries_to_save( 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new ProtoDatabase<ImageData>::KeyEntryVector()); 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<std::vector<std::string> > keys_to_remove( 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new std::vector<std::string>()); 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch entries_to_save->push_back(std::make_pair(data.url(), data)); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_->UpdateEntries(entries_to_save.Pass(), keys_to_remove.Pass(), 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&ImageManagerImpl::OnDatabaseSave, 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr())); 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::OnDatabaseInit(bool success) { 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!success) { 2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DVLOG(1) << "Image database init failed."; 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_.reset(); 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ServePendingCacheRequests(); 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) database_->LoadEntries(base::Bind(&ImageManagerImpl::OnDatabaseLoad, 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr())); 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::OnDatabaseLoad(bool success, 2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<ImageDataVector> entries) { 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!success) { 2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DVLOG(1) << "Image database load failed."; 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_.reset(); 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ServePendingCacheRequests(); 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_ready_ = true; 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LoadEntriesInCache(entries.Pass()); 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ServePendingCacheRequests(); 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::OnDatabaseSave(bool success) { 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!success) { 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DVLOG(1) << "Image database save failed."; 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_.reset(); 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch database_ready_ = false; 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::LoadEntriesInCache(scoped_ptr<ImageDataVector> entries) { 2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (ImageDataVector::iterator it = entries->begin(); it != entries->end(); 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++it) { 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<unsigned char> encoded_data(it->data().begin(), 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->data().end()); 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<SkBitmap> bitmap(DecodeImage(encoded_data)); 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (bitmap.get()) { 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) image_map_.insert(std::make_pair(it->url(), *bitmap)); 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ImageManagerImpl::ServePendingCacheRequests() { 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (ImageRequestMap::iterator it = pending_cache_requests_.begin(); 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != pending_cache_requests_.end(); ++it) { 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const ImageRequest& request = it->second; 258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (CallbackVector::const_iterator callback_it = request.callbacks.begin(); 259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_it != request.callbacks.end(); ++callback_it) { 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ServeFromCacheOrNetwork(request.url, request.image_url, *callback_it); 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ImageManagerImpl::EncodeImage(const SkBitmap& bitmap, 2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::vector<unsigned char>* dest) { 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkAutoLockPixels bitmap_lock(bitmap); 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!bitmap.readyToDraw() || bitmap.isNull()) { 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return gfx::JPEGCodec::Encode( 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::JPEGCodec::FORMAT_SkBitmap, bitmap.width(), bitmap.height(), 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitmap.width() * bitmap.bytesPerPixel(), 100, dest); 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace suggestions 279