1// Copyright (c) 2012 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_EXTENSIONS_EXTENSION_ICON_SOURCE_H_ 6#define CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_ICON_SOURCE_H_ 7 8#include <map> 9#include <string> 10 11#include "base/basictypes.h" 12#include "base/memory/weak_ptr.h" 13#include "base/task/cancelable_task_tracker.h" 14#include "chrome/browser/favicon/favicon_service.h" 15#include "content/public/browser/url_data_source.h" 16#include "extensions/common/extension_icon_set.h" 17#include "extensions/common/extension_resource.h" 18#include "third_party/skia/include/core/SkBitmap.h" 19 20class ExtensionIconSet; 21class Profile; 22 23namespace extensions { 24class Extension; 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 content::URLDataSource, 53 public base::SupportsWeakPtr<ExtensionIconSource> { 54 public: 55 explicit ExtensionIconSource(Profile* profile); 56 57 // Gets the URL of the |extension| icon in the given |icon_size|, falling back 58 // based on the |match| type. If |grayscale|, the URL will be for the 59 // desaturated version of the icon. |exists|, if non-NULL, will be set to true 60 // if the icon exists; false if it will lead to a default or not-present 61 // image. 62 static GURL GetIconURL(const Extension* extension, 63 int icon_size, 64 ExtensionIconSet::MatchType match, 65 bool grayscale, 66 bool* exists); 67 68 // A public utility function for accessing the bitmap of the image specified 69 // by |resource_id|. 70 static SkBitmap* LoadImageByResourceId(int resource_id); 71 72 // content::URLDataSource implementation. 73 virtual std::string GetSource() const OVERRIDE; 74 virtual std::string GetMimeType(const std::string&) const OVERRIDE; 75 virtual void StartDataRequest( 76 const std::string& path, 77 int render_process_id, 78 int render_frame_id, 79 const content::URLDataSource::GotDataCallback& callback) OVERRIDE; 80 81 private: 82 // Encapsulates the request parameters for |request_id|. 83 struct ExtensionIconRequest; 84 85 virtual ~ExtensionIconSource(); 86 87 // Returns the bitmap for the default app image. 88 const SkBitmap* GetDefaultAppImage(); 89 90 // Returns the bitmap for the default extension. 91 const SkBitmap* GetDefaultExtensionImage(); 92 93 // Performs any remaining transformations (like desaturating the |image|), 94 // then returns the |image| to the client and clears up any temporary data 95 // associated with the |request_id|. 96 void FinalizeImage(const SkBitmap* image, int request_id); 97 98 // Loads the default image for |request_id| and returns to the client. 99 void LoadDefaultImage(int request_id); 100 101 // Loads the extension's |icon| for the given |request_id| and returns the 102 // image to the client. 103 void LoadExtensionImage(const ExtensionResource& icon, 104 int request_id); 105 106 // Loads the favicon image for the app associated with the |request_id|. If 107 // the image does not exist, we fall back to the default image. 108 void LoadFaviconImage(int request_id); 109 110 // FaviconService callback 111 void OnFaviconDataAvailable( 112 int request_id, 113 const favicon_base::FaviconRawBitmapResult& bitmap_result); 114 115 // ImageLoader callback 116 void OnImageLoaded(int request_id, const gfx::Image& image); 117 118 // Called when the extension doesn't have an icon. We fall back to multiple 119 // sources, using the following order: 120 // 1) The icons as listed in the extension / app manifests. 121 // 2) If a 16px icon and the extension has a launch URL, see if Chrome 122 // has a corresponding favicon. 123 // 3) If still no matches, load the default extension / application icon. 124 void LoadIconFailed(int request_id); 125 126 // Parses and savse an ExtensionIconRequest for the URL |path| for the 127 // specified |request_id|. 128 bool ParseData(const std::string& path, 129 int request_id, 130 const content::URLDataSource::GotDataCallback& callback); 131 132 // Stores the parameters associated with the |request_id|, making them 133 // as an ExtensionIconRequest via GetData. 134 void SetData(int request_id, 135 const content::URLDataSource::GotDataCallback& callback, 136 const Extension* extension, 137 bool grayscale, 138 int size, 139 ExtensionIconSet::MatchType match); 140 141 // Returns the ExtensionIconRequest for the given |request_id|. 142 ExtensionIconRequest* GetData(int request_id); 143 144 // Removes temporary data associated with |request_id|. 145 void ClearData(int request_id); 146 147 Profile* profile_; 148 149 // Maps tracker ids to request ids. 150 std::map<int, int> tracker_map_; 151 152 // Maps request_ids to ExtensionIconRequests. 153 std::map<int, ExtensionIconRequest*> request_map_; 154 155 scoped_ptr<SkBitmap> default_app_data_; 156 157 scoped_ptr<SkBitmap> default_extension_data_; 158 159 base::CancelableTaskTracker cancelable_task_tracker_; 160 161 DISALLOW_COPY_AND_ASSIGN(ExtensionIconSource); 162}; 163 164} // namespace extensions 165 166#endif // CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_ICON_SOURCE_H_ 167