Home | History | Annotate | Download | only in extensions
      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