Home | History | Annotate | Download | only in suggestions
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/search/suggestions/thumbnail_manager.h"
      6 
      7 #include "chrome/browser/profiles/profile.h"
      8 #include "chrome/browser/search/suggestions/proto/suggestions.pb.h"
      9 #include "content/public/browser/browser_thread.h"
     10 #include "net/base/load_flags.h"
     11 
     12 namespace suggestions {
     13 
     14 ThumbnailManager::ThumbnailManager(Profile* profile)
     15     : url_request_context_(profile->GetRequestContext()) {}
     16 
     17 ThumbnailManager::~ThumbnailManager() {}
     18 
     19 ThumbnailManager::ThumbnailRequest::ThumbnailRequest() : fetcher(NULL) {}
     20 
     21 ThumbnailManager::ThumbnailRequest::ThumbnailRequest(chrome::BitmapFetcher* f)
     22     : fetcher(f) {}
     23 
     24 ThumbnailManager::ThumbnailRequest::~ThumbnailRequest() {
     25   delete fetcher;
     26 }
     27 
     28 void ThumbnailManager::InitializeThumbnailMap(
     29     const SuggestionsProfile& suggestions) {
     30   thumbnail_map_.clear();
     31   for (int i = 0; i < suggestions.suggestions_size(); ++i) {
     32     const ChromeSuggestion& suggestion = suggestions.suggestions(i);
     33     if (suggestion.has_thumbnail()) {
     34       thumbnail_map_[GURL(suggestion.url())] = GURL(suggestion.thumbnail());
     35     }
     36   }
     37 }
     38 
     39 void ThumbnailManager::GetPageThumbnail(
     40     const GURL& url,
     41     base::Callback<void(const GURL&, const SkBitmap*)> callback) {
     42   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     43   // If |url| is not found in |thumbnail_map_|, then invoke |callback| with NULL
     44   // since there is no associated thumbnail.
     45   GURL thumbnail_url;
     46   if (!GetThumbnailURL(url, &thumbnail_url)) {
     47     callback.Run(url, NULL);
     48     return;
     49   }
     50 
     51   // Look for a request in progress for |thumbnail_url|.
     52   ThumbnailRequestMap::iterator it = pending_requests_.find(thumbnail_url);
     53   if (it == pending_requests_.end()) {
     54     // |thumbnail_url| is not being fetched, so create a request and initiate
     55     // the fetch.
     56     ThumbnailRequest request(new chrome::BitmapFetcher(thumbnail_url, this));
     57     request.url = url;
     58     request.callbacks.push_back(callback);
     59     request.fetcher->Start(
     60         url_request_context_, std::string(),
     61         net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
     62         net::LOAD_NORMAL);
     63     pending_requests_[thumbnail_url].swap(&request);
     64   } else {
     65     // Request in progress. Register as an interested callback.
     66     it->second.callbacks.push_back(callback);
     67   }
     68 }
     69 
     70 void ThumbnailManager::OnFetchComplete(const GURL thumbnail_url,
     71                                        const SkBitmap* bitmap) {
     72   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     73 
     74   ThumbnailRequestMap::iterator it = pending_requests_.find(thumbnail_url);
     75   DCHECK(it != pending_requests_.end());
     76 
     77   ThumbnailRequest* request = &it->second;
     78 
     79   // Here |bitmap| could be NULL or a pointer to a bitmap which is owned by the
     80   // BitmapFetcher and which ceases to exist after this function. Pass the
     81   // un-owned pointer to the registered callbacks.
     82   for (CallbackVector::iterator it = request->callbacks.begin();
     83        it != request->callbacks.end(); ++it) {
     84     it->Run(request->url, bitmap);
     85   }
     86   pending_requests_.erase(it);
     87 }
     88 
     89 bool ThumbnailManager::GetThumbnailURL(const GURL& url, GURL* thumbnail_url) {
     90   std::map<GURL, GURL>::iterator it = thumbnail_map_.find(url);
     91   if (it == thumbnail_map_.end()) return false;  // Not found.
     92   *thumbnail_url = it->second;
     93   return true;
     94 }
     95 
     96 }  // namespace suggestions
     97