Home | History | Annotate | Download | only in extensions
      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 
     20 class ExtensionIconSet;
     21 class Profile;
     22 
     23 namespace extensions {
     24 class 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 //
     52 class 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