| // Copyright (c) 2012 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. |
| |
| #include "chrome/browser/extensions/extension_icon_manager.h" |
| |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/stl_util.h" |
| #include "chrome/app/vector_icons/vector_icons.h" |
| #include "extensions/browser/image_loader.h" |
| #include "extensions/common/constants.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/extension_icon_set.h" |
| #include "extensions/common/extension_resource.h" |
| #include "extensions/common/manifest_handlers/icons_handler.h" |
| #include "skia/ext/image_operations.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/gfx/color_utils.h" |
| #include "ui/gfx/favicon_size.h" |
| #include "ui/gfx/geometry/size.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/native_theme/common_theme.h" |
| #include "ui/native_theme/native_theme.h" |
| |
| ExtensionIconManager::ExtensionIconManager() |
| : monochrome_(false), |
| weak_ptr_factory_(this) { |
| } |
| |
| ExtensionIconManager::~ExtensionIconManager() { |
| } |
| |
| void ExtensionIconManager::LoadIcon(content::BrowserContext* context, |
| const extensions::Extension* extension) { |
| // Insert into pending_icons_ first because LoadImage can call us back |
| // synchronously if the image is already cached. |
| pending_icons_.insert(extension->id()); |
| extensions::ImageLoader* loader = extensions::ImageLoader::Get(context); |
| loader->LoadImageAtEveryScaleFactorAsync( |
| extension, gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize), |
| base::Bind(&ExtensionIconManager::OnImageLoaded, |
| weak_ptr_factory_.GetWeakPtr(), extension->id())); |
| } |
| |
| gfx::Image ExtensionIconManager::GetIcon(const std::string& extension_id) { |
| auto iter = icons_.find(extension_id); |
| gfx::Image* result = nullptr; |
| if (iter == icons_.end()) { |
| EnsureDefaultIcon(); |
| result = &default_icon_; |
| } else { |
| result = &iter->second; |
| } |
| |
| DCHECK(result); |
| DCHECK_EQ(gfx::kFaviconSize, result->Width()); |
| DCHECK_EQ(gfx::kFaviconSize, result->Height()); |
| return *result; |
| } |
| |
| void ExtensionIconManager::RemoveIcon(const std::string& extension_id) { |
| icons_.erase(extension_id); |
| pending_icons_.erase(extension_id); |
| } |
| |
| void ExtensionIconManager::OnImageLoaded(const std::string& extension_id, |
| const gfx::Image& image) { |
| if (image.IsEmpty()) |
| return; |
| |
| // We may have removed the icon while waiting for it to load. In that case, |
| // do nothing. |
| if (pending_icons_.erase(extension_id) == 0) |
| return; |
| |
| gfx::Image modified_image = image; |
| if (monochrome_) { |
| color_utils::HSL shift = {-1, 0, 0.6}; |
| modified_image = gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage( |
| image.AsImageSkia(), shift)); |
| } |
| icons_[extension_id] = modified_image; |
| } |
| |
| void ExtensionIconManager::EnsureDefaultIcon() { |
| if (default_icon_.IsEmpty()) { |
| default_icon_ = gfx::Image(gfx::CreateVectorIcon( |
| kExtensionIcon, gfx::kFaviconSize, gfx::kChromeIconGrey)); |
| } |
| } |