extension_icon_source.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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_UI_WEBUI_EXTENSION_ICON_SOURCE_H_
6#define CHROME_BROWSER_UI_WEBUI_EXTENSION_ICON_SOURCE_H_
7#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "chrome/browser/extensions/image_loading_tracker.h"
13#include "chrome/browser/favicon_service.h"
14#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
15#include "chrome/common/extensions/extension.h"
16#include "third_party/skia/include/core/SkBitmap.h"
17
18class ExtensionIconSet;
19class Profile;
20class RefCountedMemory;
21
22namespace gfx {
23class Size;
24}
25
26// ExtensionIconSource serves extension icons through network level chrome:
27// requests. Icons can be retrieved for any installed extension or app.
28//
29// The format for requesting an icon is as follows:
30//   chrome://extension-icon/<extension_id>/<icon_size>/<match_type>?[options]
31//
32//   Parameters (<> required, [] optional):
33//    <extension_id>  = the id of the extension
34//    <icon_size>     = the size of the icon, as the integer value of the
35//                      corresponding Extension:Icons enum.
36//    <match_type>    = the fallback matching policy, as the integer value of
37//                      the corresponding ExtensionIconSet::MatchType enum.
38//    [options]       = Optional transformations to apply. Supported options:
39//                        grayscale=true to desaturate the image.
40//
41// Examples:
42//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/32/1?grayscale=true
43//     (ICON_SMALL, MATCH_BIGGER, grayscale)
44//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/128/0
45//     (ICON_LARGE, MATCH_EXACTLY)
46//
47// We attempt to load icons from the following sources in order:
48//  1) The icons as listed in the extension / app manifests.
49//  2) If a 16px icon was requested, the favicon for extension's launch URL.
50//  3) The default extension / application icon if there are still no matches.
51//
52class ExtensionIconSource : public ChromeURLDataManager::DataSource,
53                            public ImageLoadingTracker::Observer {
54 public:
55  explicit ExtensionIconSource(Profile* profile);
56  virtual ~ExtensionIconSource();
57
58  // Gets the URL of the |extension| icon in the given |size|, falling back
59  // based on the |match| type. If |grayscale|, the URL will be for the
60  // desaturated version of the icon.
61  static GURL GetIconURL(const Extension* extension,
62                         Extension::Icons icon_size,
63                         ExtensionIconSet::MatchType match,
64                         bool grayscale);
65
66  // ChromeURLDataManager::DataSource
67
68  virtual std::string GetMimeType(const std::string&) const;
69
70  virtual void StartDataRequest(const std::string& path,
71                                bool is_incognito,
72                                int request_id);
73
74
75 private:
76  // Encapsulates the request parameters for |request_id|.
77  struct ExtensionIconRequest;
78
79  // Returns the bitmap for the default app image.
80  SkBitmap* GetDefaultAppImage();
81
82  // Returns the bitmap for the default extension.
83  SkBitmap* GetDefaultExtensionImage();
84
85  // Performs any remaining transformations (like desaturating the |image|),
86  // then returns the |image| to the client and clears up any temporary data
87  // associated with the |request_id|.
88  void FinalizeImage(SkBitmap* image, int request_id);
89
90  // Loads the default image for |request_id| and returns to the client.
91  void LoadDefaultImage(int request_id);
92
93  // Loads the extension's |icon| for the given |request_id| and returns the
94  // image to the client.
95  void LoadExtensionImage(const ExtensionResource& icon, int request_id);
96
97  // Loads the favicon image for the app associated with the |request_id|. If
98  // the image does not exist, we fall back to the default image.
99  void LoadFaviconImage(int request_id);
100
101  // FaviconService callback
102  void OnFaviconDataAvailable(FaviconService::Handle request_handle,
103                              history::FaviconData favicon);
104
105  // ImageLoadingTracker::Observer
106  virtual void OnImageLoaded(SkBitmap* image,
107                             const ExtensionResource& resource,
108                             int id);
109
110  // Called when the extension doesn't have an icon. We fall back to multiple
111  // sources, using the following order:
112  //  1) The icons as listed in the extension / app manifests.
113  //  2) If a 16px icon and the extension has a launch URL, see if Chrome
114  //     has a corresponding favicon.
115  //  3) If still no matches, load the default extension / application icon.
116  void LoadIconFailed(int request_id);
117
118  // Parses and savse an ExtensionIconRequest for the URL |path| for the
119  // specified |request_id|.
120  bool ParseData(const std::string& path, int request_id);
121
122  // Sends the default response to |request_id|, used for invalid requests.
123  void SendDefaultResponse(int request_id);
124
125  // Stores the parameters associated with the |request_id|, making them
126  // as an ExtensionIconRequest via GetData.
127  void SetData(int request_id,
128               const Extension* extension,
129               bool grayscale,
130               Extension::Icons size,
131               ExtensionIconSet::MatchType match);
132
133  // Returns the ExtensionIconRequest for the given |request_id|.
134  ExtensionIconRequest* GetData(int request_id);
135
136  // Removes temporary data associated with |request_id|.
137  void ClearData(int request_id);
138
139  Profile* profile_;
140
141  // Maps tracker ids to request ids.
142  std::map<int, int> tracker_map_;
143
144  // Maps request_ids to ExtensionIconRequests.
145  std::map<int, ExtensionIconRequest*> request_map_;
146
147  scoped_ptr<ImageLoadingTracker> tracker_;
148
149  int next_tracker_id_;
150
151  scoped_ptr<SkBitmap> default_app_data_;
152
153  scoped_ptr<SkBitmap> default_extension_data_;
154
155  CancelableRequestConsumerT<int, 0> cancelable_consumer_;
156
157  DISALLOW_COPY_AND_ASSIGN(ExtensionIconSource);
158};
159
160#endif  // CHROME_BROWSER_UI_WEBUI_EXTENSION_ICON_SOURCE_H_
161