summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/webui/extension_icon_source.h
blob: 7b2bc85dd13538bc772be4e38928909c0968b391 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_WEBUI_EXTENSION_ICON_SOURCE_H_
#define CHROME_BROWSER_UI_WEBUI_EXTENSION_ICON_SOURCE_H_
#pragma once

#include <string>

#include "base/basictypes.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/favicon_service.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#include "chrome/common/extensions/extension.h"
#include "third_party/skia/include/core/SkBitmap.h"

class ExtensionIconSet;
class Profile;
class RefCountedMemory;

namespace gfx {
class Size;
}

// ExtensionIconSource serves extension icons through network level chrome:
// requests. Icons can be retrieved for any installed extension or app.
//
// The format for requesting an icon is as follows:
//   chrome://extension-icon/<extension_id>/<icon_size>/<match_type>?[options]
//
//   Parameters (<> required, [] optional):
//    <extension_id>  = the id of the extension
//    <icon_size>     = the size of the icon, as the integer value of the
//                      corresponding Extension:Icons enum.
//    <match_type>    = the fallback matching policy, as the integer value of
//                      the corresponding ExtensionIconSet::MatchType enum.
//    [options]       = Optional transformations to apply. Supported options:
//                        grayscale=true to desaturate the image.
//
// Examples:
//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/32/1?grayscale=true
//     (ICON_SMALL, MATCH_BIGGER, grayscale)
//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/128/0
//     (ICON_LARGE, MATCH_EXACTLY)
//
// We attempt to load icons from the following sources in order:
//  1) The icons as listed in the extension / app manifests.
//  2) If a 16px icon was requested, the favicon for extension's launch URL.
//  3) The default extension / application icon if there are still no matches.
//
class ExtensionIconSource : public ChromeURLDataManager::DataSource,
                            public ImageLoadingTracker::Observer {
 public:
  explicit ExtensionIconSource(Profile* profile);
  virtual ~ExtensionIconSource();

  // Gets the URL of the |extension| icon in the given |size|, falling back
  // based on the |match| type. If |grayscale|, the URL will be for the
  // desaturated version of the icon.
  static GURL GetIconURL(const Extension* extension,
                         Extension::Icons icon_size,
                         ExtensionIconSet::MatchType match,
                         bool grayscale);

  // ChromeURLDataManager::DataSource

  virtual std::string GetMimeType(const std::string&) const;

  virtual void StartDataRequest(const std::string& path,
                                bool is_off_the_record,
                                int request_id);


 private:
  // Encapsulates the request parameters for |request_id|.
  struct ExtensionIconRequest;

  // Returns the bitmap for the default app image.
  SkBitmap* GetDefaultAppImage();

  // Returns the bitmap for the default extension.
  SkBitmap* GetDefaultExtensionImage();

  // Performs any remaining transformations (like desaturating the |image|),
  // then returns the |image| to the client and clears up any temporary data
  // associated with the |request_id|.
  void FinalizeImage(SkBitmap* image, int request_id);

  // Loads the default image for |request_id| and returns to the client.
  void LoadDefaultImage(int request_id);

  // Loads the extension's |icon| for the given |request_id| and returns the
  // image to the client.
  void LoadExtensionImage(const ExtensionResource& icon, int request_id);

  // Loads the favicon image for the app associated with the |request_id|. If
  // the image does not exist, we fall back to the default image.
  void LoadFaviconImage(int request_id);

  // FaviconService callback
  void OnFaviconDataAvailable(FaviconService::Handle request_handle,
                              bool know_favicon,
                              scoped_refptr<RefCountedMemory> data,
                              bool expired,
                              GURL icon_url);

  // ImageLoadingTracker::Observer
  virtual void OnImageLoaded(SkBitmap* image,
                             const ExtensionResource& resource,
                             int id);

  // Called when the extension doesn't have an icon. We fall back to multiple
  // sources, using the following order:
  //  1) The icons as listed in the extension / app manifests.
  //  2) If a 16px icon and the extension has a launch URL, see if Chrome
  //     has a corresponding favicon.
  //  3) If still no matches, load the default extension / application icon.
  void LoadIconFailed(int request_id);

  // Parses and savse an ExtensionIconRequest for the URL |path| for the
  // specified |request_id|.
  bool ParseData(const std::string& path, int request_id);

  // Sends the default response to |request_id|, used for invalid requests.
  void SendDefaultResponse(int request_id);

  // Stores the parameters associated with the |request_id|, making them
  // as an ExtensionIconRequest via GetData.
  void SetData(int request_id,
               const Extension* extension,
               bool grayscale,
               Extension::Icons size,
               ExtensionIconSet::MatchType match);

  // Returns the ExtensionIconRequest for the given |request_id|.
  ExtensionIconRequest* GetData(int request_id);

  // Removes temporary data associated with |request_id|.
  void ClearData(int request_id);

  Profile* profile_;

  // Maps tracker ids to request ids.
  std::map<int, int> tracker_map_;

  // Maps request_ids to ExtensionIconRequests.
  std::map<int, ExtensionIconRequest*> request_map_;

  scoped_ptr<ImageLoadingTracker> tracker_;

  int next_tracker_id_;

  scoped_ptr<SkBitmap> default_app_data_;

  scoped_ptr<SkBitmap> default_extension_data_;

  CancelableRequestConsumerT<int, 0> cancelable_consumer_;

  DISALLOW_COPY_AND_ASSIGN(ExtensionIconSource);
};

#endif  // CHROME_BROWSER_UI_WEBUI_EXTENSION_ICON_SOURCE_H_