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 #ifndef CHROME_BROWSER_BITMAP_FETCHER_BITMAP_FETCHER_SERVICE_H_ 5 #define CHROME_BROWSER_BITMAP_FETCHER_BITMAP_FETCHER_SERVICE_H_ 6 7 #include "base/compiler_specific.h" 8 #include "base/containers/mru_cache.h" 9 #include "base/containers/scoped_ptr_hash_map.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_vector.h" 12 #include "chrome/browser/bitmap_fetcher_delegate.h" 13 #include "components/keyed_service/core/keyed_service.h" 14 15 namespace content { 16 class BrowserContext; 17 } // namespace content 18 19 namespace chrome { 20 class BitmapFetcher; 21 } // namespace chrome 22 23 class BitmapFetcherRequest; 24 class GURL; 25 class SkBitmap; 26 27 // Service to retrieve images for Answers in Suggest. 28 class BitmapFetcherService : public KeyedService, 29 public chrome::BitmapFetcherDelegate { 30 public: 31 typedef int RequestId; 32 static const RequestId REQUEST_ID_INVALID = 0; 33 34 class Observer { 35 public: ~Observer()36 virtual ~Observer() {} 37 38 // Called whenever the image changes. Called with an empty image if the 39 // fetch failed or the request ended for any reason. 40 virtual void OnImageChanged(RequestId request_id, 41 const SkBitmap& answers_image) = 0; 42 }; 43 44 explicit BitmapFetcherService(content::BrowserContext* context); 45 virtual ~BitmapFetcherService(); 46 47 // Cancels a request, if it is still in-flight. 48 void CancelRequest(RequestId requestId); 49 50 // Requests a new image. Will either trigger download or satisfy from cache. 51 // Takes ownership of |observer|. If there are too many outstanding requests, 52 // the request will fail and |observer| will be called to signal failure. 53 // Otherwise, |observer| will be called with either the cached image or the 54 // downloaded one. 55 // NOTE: The observer might be called back synchronously from RequestImage if 56 // the image is already in the cache. 57 RequestId RequestImage(const GURL& url, Observer* observer); 58 59 // Start fetching the image at the given |url|. 60 void Prefetch(const GURL& url); 61 62 protected: 63 // Create a bitmap fetcher for the given |url| and start it. Virtual method 64 // so tests can override this for different behavior. 65 virtual chrome::BitmapFetcher* CreateFetcher(const GURL& url); 66 67 private: 68 friend class BitmapFetcherServiceTest; 69 70 typedef ScopedVector<chrome::BitmapFetcher> BitmapFetchers; 71 72 // Gets the existing fetcher for |url| or constructs a new one if it doesn't 73 // exist. 74 const chrome::BitmapFetcher* EnsureFetcherForUrl(const GURL& url); 75 76 // Find a fetcher with a given |url|. Return NULL if none is found. 77 const chrome::BitmapFetcher* FindFetcherForUrl(const GURL& url); 78 79 // Remove |fetcher| from list of active fetchers. |fetcher| MUST be part of 80 // the list. 81 void RemoveFetcher(const chrome::BitmapFetcher* fetcher); 82 83 // BitmapFetcherDelegate implementation. 84 virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) OVERRIDE; 85 86 // Currently active image fetchers. 87 BitmapFetchers active_fetchers_; 88 89 // Currently active requests. 90 ScopedVector<BitmapFetcherRequest> requests_; 91 92 // Cache of retrieved images. 93 struct CacheEntry { 94 CacheEntry(); 95 ~CacheEntry(); 96 97 scoped_ptr<const SkBitmap> bitmap; 98 }; 99 base::OwningMRUCache<GURL, CacheEntry*> cache_; 100 101 // Current request ID to be used. 102 int current_request_id_; 103 104 // Browser context this service is active for. 105 content::BrowserContext* context_; 106 107 DISALLOW_COPY_AND_ASSIGN(BitmapFetcherService); 108 }; 109 110 #endif // CHROME_BROWSER_BITMAP_FETCHER_BITMAP_FETCHER_SERVICE_H_ 111