// 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_incognito, 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, history::FaviconData favicon); // 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_