• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
6 #define CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
7 #pragma once
8 
9 #include <map>
10 
11 #include "base/memory/ref_counted.h"
12 #include "content/common/notification_observer.h"
13 #include "content/common/notification_registrar.h"
14 
15 class Extension;
16 class ExtensionResource;
17 class SkBitmap;
18 
19 namespace gfx {
20   class Size;
21 }
22 
23 // The views need to load their icons asynchronously but might be deleted before
24 // the images have loaded. This class encapsulates a loader class that stays
25 // alive while the request is in progress (manages its own lifetime) and keeps
26 // track of whether the view still cares about the icon loading.
27 //
28 // To use this class, have your class derive from ImageLoadingTracker::Observer,
29 // and add a member variable ImageLoadingTracker tracker_. Then override
30 // Observer::OnImageLoaded and call:
31 //   tracker_.LoadImage(extension, resource, max_size, false);
32 // ... and wait for OnImageLoaded to be called back on you with a pointer to the
33 // SkBitmap loaded.
34 // NOTE: if the image is available already (or the resource is not valid), the
35 // Observer is notified immediately from the call to LoadImage. In other words,
36 // by the time LoadImage returns the observer has been notified.
37 //
38 class ImageLoadingTracker : public NotificationObserver {
39  public:
40   enum CacheParam {
41     CACHE,
42     DONT_CACHE
43   };
44 
45   class Observer {
46    public:
47     virtual ~Observer();
48 
49     // Will be called when the image with the given index has loaded.
50     // The |image| is owned by the tracker, so the observer should make a copy
51     // if they need to access it after this call. |image| can be null if valid
52     // image was not found or it failed to decode. |resource| is the
53     // ExtensionResource where the |image| came from and the |index| represents
54     // the index of the image just loaded (starts at 0 and increments every
55     // time LoadImage is called).
56     virtual void OnImageLoaded(SkBitmap* image,
57                                const ExtensionResource& resource,
58                                int index) = 0;
59   };
60 
61   explicit ImageLoadingTracker(Observer* observer);
62   ~ImageLoadingTracker();
63 
64   // Specify image resource to load. If the loaded image is larger than
65   // |max_size| it will be resized to those dimensions. IMPORTANT NOTE: this
66   // function may call back your observer synchronously (ie before it returns)
67   // if the image was found in the cache.
68   void LoadImage(const Extension* extension,
69                  const ExtensionResource& resource,
70                  const gfx::Size& max_size,
71                  CacheParam cache);
72 
73  private:
74   typedef std::map<int, const Extension*> LoadMap;
75 
76   class ImageLoader;
77 
78   // When an image has finished loaded and been resized on the file thread, it
79   // is posted back to this method on the original thread.  This method then
80   // calls the observer's OnImageLoaded and deletes the ImageLoadingTracker if
81   // it was the last image in the list. The |original_size| should be the size
82   // of the image before any resizing was done.
83   // |image| may be null if the file failed to decode.
84   void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource,
85                      const gfx::Size& original_size, int id);
86 
87   // NotificationObserver method. If an extension is uninstalled while we're
88   // waiting for the image we remove the entry from load_map_.
89   virtual void Observe(NotificationType type,
90                        const NotificationSource& source,
91                        const NotificationDetails& details);
92 
93   // The view that is waiting for the image to load.
94   Observer* observer_;
95 
96   // ID to use for next image requested. This is an ever increasing integer.
97   int next_id_;
98 
99   // The object responsible for loading the image on the File thread.
100   scoped_refptr<ImageLoader> loader_;
101 
102   // If LoadImage is told to cache the result an entry is added here. The
103   // integer identifies the id assigned to the request. If the extension is
104   // deleted while fetching the image the entry is removed from the map.
105   LoadMap load_map_;
106 
107   NotificationRegistrar registrar_;
108 
109   DISALLOW_COPY_AND_ASSIGN(ImageLoadingTracker);
110 };
111 
112 #endif  // CHROME_BROWSER_EXTENSIONS_IMAGE_LOADING_TRACKER_H_
113