• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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