15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_ICON_SOURCE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_ICON_SOURCE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/url_data_source.h"
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_icon_set.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension_resource.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionIconSet;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Profile;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionIconSource serves extension icons through network level chrome:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests. Icons can be retrieved for any installed extension or app.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The format for requesting an icon is as follows:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   chrome://extension-icon/<extension_id>/<icon_size>/<match_type>?[options]
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Parameters (<> required, [] optional):
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    <extension_id>  = the id of the extension
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    <icon_size>     = the size of the icon, as the integer value of the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                      corresponding Extension:Icons enum.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    <match_type>    = the fallback matching policy, as the integer value of
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                      the corresponding ExtensionIconSet::MatchType enum.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    [options]       = Optional transformations to apply. Supported options:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                        grayscale=true to desaturate the image.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Examples:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/32/1?grayscale=true
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     (ICON_SMALL, MATCH_BIGGER, grayscale)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   chrome-extension://gbmgkahjioeacddebbnengilkgbkhodg/128/0
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     (ICON_LARGE, MATCH_EXACTLY)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We attempt to load icons from the following sources in order:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) The icons as listed in the extension / app manifests.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) If a 16px icon was requested, the favicon for extension's launch URL.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The default extension / application icon if there are still no matches.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ExtensionIconSource : public content::URLDataSource,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            public base::SupportsWeakPtr<ExtensionIconSource> {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ExtensionIconSource(Profile* profile);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the URL of the |extension| icon in the given |icon_size|, falling back
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // based on the |match| type. If |grayscale|, the URL will be for the
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // desaturated version of the icon. |exists|, if non-NULL, will be set to true
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if the icon exists; false if it will lead to a default or not-present
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // image.
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  static GURL GetIconURL(const Extension* extension,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int icon_size,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ExtensionIconSet::MatchType match,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool grayscale,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool* exists);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A public utility function for accessing the bitmap of the image specified
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by |resource_id|.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static SkBitmap* LoadImageByResourceId(int resource_id);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::URLDataSource implementation.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::string GetSource() const OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual std::string GetMimeType(const std::string&) const OVERRIDE;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StartDataRequest(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& path,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int render_process_id,
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int render_frame_id,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Encapsulates the request parameters for |request_id|.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ExtensionIconRequest;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ExtensionIconSource();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the bitmap for the default app image.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap* GetDefaultAppImage();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the bitmap for the default extension.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkBitmap* GetDefaultExtensionImage();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Performs any remaining transformations (like desaturating the |image|),
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then returns the |image| to the client and clears up any temporary data
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // associated with the |request_id|.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FinalizeImage(const SkBitmap* image, int request_id);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads the default image for |request_id| and returns to the client.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadDefaultImage(int request_id);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads the extension's |icon| for the given |request_id| and returns the
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // image to the client.
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void LoadExtensionImage(const ExtensionResource& icon,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          int request_id);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads the favicon image for the app associated with the |request_id|. If
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the image does not exist, we fall back to the default image.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadFaviconImage(int request_id);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FaviconService callback
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnFaviconDataAvailable(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int request_id,
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const favicon_base::FaviconRawBitmapResult& bitmap_result);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ImageLoader callback
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnImageLoaded(int request_id, const gfx::Image& image);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the extension doesn't have an icon. We fall back to multiple
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sources, using the following order:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  1) The icons as listed in the extension / app manifests.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  2) If a 16px icon and the extension has a launch URL, see if Chrome
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     has a corresponding favicon.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  3) If still no matches, load the default extension / application icon.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadIconFailed(int request_id);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parses and savse an ExtensionIconRequest for the URL |path| for the
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified |request_id|.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ParseData(const std::string& path,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 int request_id,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 const content::URLDataSource::GotDataCallback& callback);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stores the parameters associated with the |request_id|, making them
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as an ExtensionIconRequest via GetData.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetData(int request_id,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               const content::URLDataSource::GotDataCallback& callback,
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)               const Extension* extension,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bool grayscale,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               int size,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ExtensionIconSet::MatchType match);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the ExtensionIconRequest for the given |request_id|.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionIconRequest* GetData(int request_id);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes temporary data associated with |request_id|.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearData(int request_id);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maps tracker ids to request ids.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, int> tracker_map_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maps request_ids to ExtensionIconRequests.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, ExtensionIconRequest*> request_map_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> default_app_data_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> default_extension_data_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::CancelableTaskTracker cancelable_task_tracker_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionIconSource);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace extensions
165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_ICON_SOURCE_H_
167