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 18 class ExtensionIconSet; 19 class Profile; 20 class RefCountedMemory; 21 22 namespace gfx { 23 class 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 // 52 class 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