Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / extension_icon_manager.cc
blob05972a6e55b6bd4f6c8aaca873caec9dc52e26d3
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.
5 #include "chrome/browser/extensions/extension_icon_manager.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "extensions/browser/image_loader.h"
11 #include "extensions/common/constants.h"
12 #include "extensions/common/extension.h"
13 #include "extensions/common/extension_icon_set.h"
14 #include "extensions/common/extension_resource.h"
15 #include "extensions/common/manifest_handlers/icons_handler.h"
16 #include "grit/theme_resources.h"
17 #include "skia/ext/image_operations.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/color_utils.h"
21 #include "ui/gfx/favicon_size.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "ui/gfx/image/image.h"
24 #include "ui/gfx/paint_vector_icon.h"
25 #include "ui/gfx/skbitmap_operations.h"
26 #include "ui/gfx/vector_icons_public.h"
27 #include "ui/native_theme/common_theme.h"
28 #include "ui/native_theme/native_theme.h"
30 namespace {
32 // Helper function to create a new bitmap with |padding| amount of empty space
33 // around the original bitmap.
34 static SkBitmap ApplyPadding(const SkBitmap& source,
35 const gfx::Insets& padding) {
36 scoped_ptr<gfx::Canvas> result(
37 new gfx::Canvas(gfx::Size(source.width() + padding.width(),
38 source.height() + padding.height()),
39 1.0f,
40 false));
41 result->DrawImageInt(
42 gfx::ImageSkia::CreateFrom1xBitmap(source),
43 0, 0, source.width(), source.height(),
44 padding.left(), padding.top(), source.width(), source.height(),
45 false);
46 return result->ExtractImageRep().sk_bitmap();
49 } // namespace
51 ExtensionIconManager::ExtensionIconManager()
52 : monochrome_(false),
53 weak_ptr_factory_(this) {
56 ExtensionIconManager::~ExtensionIconManager() {
59 void ExtensionIconManager::LoadIcon(content::BrowserContext* context,
60 const extensions::Extension* extension) {
61 extensions::ExtensionResource icon_resource =
62 extensions::IconsInfo::GetIconResource(
63 extension,
64 extension_misc::EXTENSION_ICON_BITTY,
65 ExtensionIconSet::MATCH_BIGGER);
66 if (!icon_resource.extension_root().empty()) {
67 // Insert into pending_icons_ first because LoadImage can call us back
68 // synchronously if the image is already cached.
69 pending_icons_.insert(extension->id());
70 extensions::ImageLoader* loader = extensions::ImageLoader::Get(context);
71 loader->LoadImageAsync(extension, icon_resource,
72 gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize),
73 base::Bind(
74 &ExtensionIconManager::OnImageLoaded,
75 weak_ptr_factory_.GetWeakPtr(),
76 extension->id()));
80 const SkBitmap& ExtensionIconManager::GetIcon(const std::string& extension_id) {
81 const SkBitmap* result = NULL;
82 if (ContainsKey(icons_, extension_id)) {
83 result = &icons_[extension_id];
84 } else {
85 EnsureDefaultIcon();
86 result = &default_icon_;
88 DCHECK(result);
89 DCHECK_EQ(gfx::kFaviconSize + padding_.width(), result->width());
90 DCHECK_EQ(gfx::kFaviconSize + padding_.height(), result->height());
91 return *result;
94 void ExtensionIconManager::RemoveIcon(const std::string& extension_id) {
95 icons_.erase(extension_id);
96 pending_icons_.erase(extension_id);
99 void ExtensionIconManager::OnImageLoaded(const std::string& extension_id,
100 const gfx::Image& image) {
101 if (image.IsEmpty())
102 return;
104 // We may have removed the icon while waiting for it to load. In that case,
105 // do nothing.
106 if (!ContainsKey(pending_icons_, extension_id))
107 return;
109 pending_icons_.erase(extension_id);
110 icons_[extension_id] = ApplyTransforms(*image.ToSkBitmap());
113 void ExtensionIconManager::EnsureDefaultIcon() {
114 if (default_icon_.empty()) {
115 SkColor icon_color;
116 ui::CommonThemeGetSystemColor(ui::NativeTheme::kColorId_ChromeIconGrey,
117 &icon_color);
118 // TODO(estade): use correct scale factor instead of 1x.
119 default_icon_ =
120 ApplyPadding(*gfx::CreateVectorIcon(gfx::VectorIconId::EXTENSION,
121 gfx::kFaviconSize, icon_color)
122 .bitmap(),
123 padding_);
127 SkBitmap ExtensionIconManager::ApplyTransforms(const SkBitmap& source) {
128 SkBitmap result = source;
130 if (result.width() != gfx::kFaviconSize ||
131 result.height() != gfx::kFaviconSize) {
132 result = skia::ImageOperations::Resize(
133 result, skia::ImageOperations::RESIZE_LANCZOS3,
134 gfx::kFaviconSize, gfx::kFaviconSize);
137 if (monochrome_) {
138 color_utils::HSL shift = {-1, 0, 0.6};
139 result = SkBitmapOperations::CreateHSLShiftedBitmap(result, shift);
142 if (!padding_.empty())
143 result = ApplyPadding(result, padding_);
145 return result;