This source file includes following definitions.
- GetExtensionIconResource
 
- Draw
 
- blank_image_
 
- ResetHost
 
- GetImageForScale
 
- weak_ptr_factory_
 
- LoadImageForScaleFactor
 
- OnImageLoaded
 
- Observe
 
#include "chrome/browser/extensions/extension_icon_image.h"
#include <vector>
#include "base/bind.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/image_loader.h"
#include "content/public/browser/notification_service.h"
#include "extensions/common/extension.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/size.h"
#include "ui/gfx/size_conversions.h"
namespace {
const int kMatchBiggerTreshold = 32;
extensions::ExtensionResource GetExtensionIconResource(
    const extensions::Extension* extension,
    const ExtensionIconSet& icons,
    int size,
    ExtensionIconSet::MatchType match_type) {
  std::string path = icons.Get(size, match_type);
  if (path.empty())
    return extensions::ExtensionResource();
  return extension->GetResource(path);
}
class BlankImageSource : public gfx::CanvasImageSource {
 public:
  explicit BlankImageSource(const gfx::Size& size_in_dip)
      : CanvasImageSource(size_in_dip,  false) {
  }
  virtual ~BlankImageSource() {}
 private:
  
  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
    canvas->DrawColor(SkColorSetARGB(0, 0, 0, 0));
  }
  DISALLOW_COPY_AND_ASSIGN(BlankImageSource);
};
}  
namespace extensions {
class IconImage::Source : public gfx::ImageSkiaSource {
 public:
  Source(IconImage* host, const gfx::Size& size_in_dip);
  virtual ~Source();
  void ResetHost();
 private:
  
  virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE;
  
  
  IconImage* host_;
  
  
  gfx::ImageSkia blank_image_;
  DISALLOW_COPY_AND_ASSIGN(Source);
};
IconImage::Source::Source(IconImage* host, const gfx::Size& size_in_dip)
    : host_(host),
      blank_image_(new BlankImageSource(size_in_dip), size_in_dip) {
}
IconImage::Source::~Source() {
}
void IconImage::Source::ResetHost() {
  host_ = NULL;
}
gfx::ImageSkiaRep IconImage::Source::GetImageForScale(float scale) {
  gfx::ImageSkiaRep representation;
  if (host_) {
    representation =
        host_->LoadImageForScaleFactor(ui::GetSupportedScaleFactor(scale));
  }
  if (!representation.is_null())
    return representation;
  return blank_image_.GetRepresentation(scale);
}
IconImage::IconImage(
    content::BrowserContext* context,
    const Extension* extension,
    const ExtensionIconSet& icon_set,
    int resource_size_in_dip,
    const gfx::ImageSkia& default_icon,
    Observer* observer)
    : browser_context_(context),
      extension_(extension),
      icon_set_(icon_set),
      resource_size_in_dip_(resource_size_in_dip),
      observer_(observer),
      source_(NULL),
      default_icon_(gfx::ImageSkiaOperations::CreateResizedImage(
          default_icon,
          skia::ImageOperations::RESIZE_BEST,
          gfx::Size(resource_size_in_dip, resource_size_in_dip))),
      weak_ptr_factory_(this) {
  gfx::Size resource_size(resource_size_in_dip, resource_size_in_dip);
  source_ = new Source(this, resource_size);
  image_skia_ = gfx::ImageSkia(source_, resource_size);
  registrar_.Add(this,
                 chrome::NOTIFICATION_EXTENSION_REMOVED,
                 content::NotificationService::AllSources());
}
IconImage::~IconImage() {
  source_->ResetHost();
}
gfx::ImageSkiaRep IconImage::LoadImageForScaleFactor(
    ui::ScaleFactor scale_factor) {
  
  if (!extension_)
    return gfx::ImageSkiaRep();
  const float scale = ui::GetImageScale(scale_factor);
  const int resource_size_in_pixel =
      static_cast<int>(resource_size_in_dip_ * scale);
  extensions::ExtensionResource resource;
  
  
  if (resource_size_in_pixel >= kMatchBiggerTreshold) {
    resource = GetExtensionIconResource(extension_, icon_set_,
        resource_size_in_pixel, ExtensionIconSet::MATCH_BIGGER);
  }
  
  if (resource.empty()) {
    resource = GetExtensionIconResource(extension_, icon_set_,
        resource_size_in_pixel, ExtensionIconSet::MATCH_SMALLER);
  }
  
  if (resource.empty())
    return default_icon_.GetRepresentation(scale);
  std::vector<ImageLoader::ImageRepresentation> info_list;
  info_list.push_back(ImageLoader::ImageRepresentation(
      resource,
      ImageLoader::ImageRepresentation::ALWAYS_RESIZE,
      gfx::ToFlooredSize(gfx::ScaleSize(
          gfx::Size(resource_size_in_dip_, resource_size_in_dip_), scale)),
      scale_factor));
  extensions::ImageLoader* loader =
      extensions::ImageLoader::Get(browser_context_);
  loader->LoadImagesAsync(extension_, info_list,
                          base::Bind(&IconImage::OnImageLoaded,
                                     weak_ptr_factory_.GetWeakPtr(),
                                     scale));
  return gfx::ImageSkiaRep();
}
void IconImage::OnImageLoaded(float scale, const gfx::Image& image_in) {
  const gfx::ImageSkia* image =
      image_in.IsEmpty() ? &default_icon_ : image_in.ToImageSkia();
  
  if (image->isNull())
    return;
  gfx::ImageSkiaRep rep = image->GetRepresentation(scale);
  DCHECK(!rep.is_null());
  DCHECK_EQ(scale, rep.scale());
  
  image_skia_.RemoveRepresentation(scale);
  image_skia_.AddRepresentation(rep);
  if (observer_)
    observer_->OnExtensionIconImageChanged(this);
}
void IconImage::Observe(int type,
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) {
  DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_REMOVED);
  const Extension* extension = content::Details<const Extension>(details).ptr();
  if (extension_ == extension)
    extension_ = NULL;
}
}