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