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"
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"
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()),
42 gfx::ImageSkia::CreateFrom1xBitmap(source
),
43 0, 0, source
.width(), source
.height(),
44 padding
.left(), padding
.top(), source
.width(), source
.height(),
46 return result
->ExtractImageRep().sk_bitmap();
51 ExtensionIconManager::ExtensionIconManager()
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(
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
),
74 &ExtensionIconManager::OnImageLoaded
,
75 weak_ptr_factory_
.GetWeakPtr(),
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
];
86 result
= &default_icon_
;
89 DCHECK_EQ(gfx::kFaviconSize
+ padding_
.width(), result
->width());
90 DCHECK_EQ(gfx::kFaviconSize
+ padding_
.height(), result
->height());
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
) {
104 // We may have removed the icon while waiting for it to load. In that case,
106 if (!ContainsKey(pending_icons_
, extension_id
))
109 pending_icons_
.erase(extension_id
);
110 icons_
[extension_id
] = ApplyTransforms(*image
.ToSkBitmap());
113 void ExtensionIconManager::EnsureDefaultIcon() {
114 if (default_icon_
.empty()) {
116 ui::CommonThemeGetSystemColor(ui::NativeTheme::kColorId_ChromeIconGrey
,
118 // TODO(estade): use correct scale factor instead of 1x.
120 ApplyPadding(*gfx::CreateVectorIcon(gfx::VectorIconId::EXTENSION
,
121 gfx::kFaviconSize
, icon_color
)
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
);
138 color_utils::HSL shift
= {-1, 0, 0.6};
139 result
= SkBitmapOperations::CreateHSLShiftedBitmap(result
, shift
);
142 if (!padding_
.empty())
143 result
= ApplyPadding(result
, padding_
);