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
5#ifndef EXTENSIONS_BROWSER_EXTENSION_ICON_IMAGE_H_
6#define EXTENSIONS_BROWSER_EXTENSION_ICON_IMAGE_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/weak_ptr.h"
13#include "content/public/browser/notification_observer.h"
14#include "content/public/browser/notification_registrar.h"
15#include "extensions/common/extension_icon_set.h"
16#include "ui/base/layout.h"
17#include "ui/gfx/image/image_skia.h"
18
19namespace content {
20class BrowserContext;
21}
22
23namespace extensions {
24class Extension;
25}
26
27namespace gfx {
28class Size;
29class Image;
30}
31
32namespace extensions {
33
34// A class that provides an ImageSkia for UI code to use. It handles extension
35// icon resource loading, screen scale factor change etc. UI code that uses
36// extension icon should host this class and be its observer. ExtensionIconImage
37// should be outlived by the observer. In painting code, UI code paints with the
38// ImageSkia provided by this class. If required extension icon resource is not
39// already present, this class tries to load it and calls its observer interface
40// when the image get updated. Until the resource is loaded, the UI code will be
41// provided with blank, transparent image.
42// If the requested resource doesn't exist or can't be loaded and a default
43// icon was supplied in the constructor, icon image will be updated with the
44// default icon's resource.
45// The default icon doesn't need to be supplied, but in that case, icon image
46// representation will be left blank if the resource loading fails.
47// If default icon is supplied, it is assumed that it contains or can
48// synchronously create (when |GetRepresentation| is called on it)
49// representations for all the scale factors supported by the current platform.
50// Note that |IconImage| is not thread safe.
51class IconImage : public content::NotificationObserver {
52 public:
53  class Observer {
54   public:
55    // Invoked when a new image rep for an additional scale factor
56    // is loaded and added to |image|.
57    virtual void OnExtensionIconImageChanged(IconImage* image) = 0;
58
59   protected:
60    virtual ~Observer() {}
61  };
62
63  // |context| is required by the underlying implementation to retrieve the
64  // |ImageLoader| instance associated with the given context. |ImageLoader| is
65  // used to perform the asynchronous image load work.
66  IconImage(content::BrowserContext* context,
67            const Extension* extension,
68            const ExtensionIconSet& icon_set,
69            int resource_size_in_dip,
70            const gfx::ImageSkia& default_icon,
71            Observer* observer);
72  virtual ~IconImage();
73
74  const gfx::ImageSkia& image_skia() const { return image_skia_; }
75
76 private:
77  class Source;
78
79  // Loads an image representation for the scale factor.
80  // If the representation gets loaded synchronously, it is returned by this
81  // method.
82  // If representation loading is asynchronous, an empty image
83  // representation is returned. When the representation gets loaded the
84  // observer's |OnExtensionIconImageLoaded| will be called.
85  gfx::ImageSkiaRep LoadImageForScaleFactor(ui::ScaleFactor scale_factor);
86
87  void OnImageLoaded(float scale_factor, const gfx::Image& image);
88
89  // content::NotificationObserver overrides:
90  virtual void Observe(int type,
91                       const content::NotificationSource& source,
92                       const content::NotificationDetails& details) OVERRIDE;
93
94  content::BrowserContext* browser_context_;
95  const Extension* extension_;
96  const ExtensionIconSet& icon_set_;
97  const int resource_size_in_dip_;
98
99  Observer* observer_;
100
101  Source* source_;  // Owned by ImageSkia storage.
102  gfx::ImageSkia image_skia_;
103  // The icon with whose representation |image_skia_| should be updated if
104  // its own representation load fails.
105  gfx::ImageSkia default_icon_;
106
107  content::NotificationRegistrar registrar_;
108
109  base::WeakPtrFactory<IconImage> weak_ptr_factory_;
110
111  DISALLOW_COPY_AND_ASSIGN(IconImage);
112};
113
114}  // namespace extensions
115
116#endif  // EXTENSIONS_BROWSER_EXTENSION_ICON_IMAGE_H_
117