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#include "chrome/browser/extensions/app_icon_loader_impl.h" 6 7#include "base/stl_util.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/extensions/extension_util.h" 10#include "chrome/browser/profiles/profile.h" 11#include "chrome/common/extensions/extension_constants.h" 12#include "extensions/browser/extension_system.h" 13#include "extensions/common/extension.h" 14#include "extensions/common/manifest_handlers/icons_handler.h" 15#include "ui/gfx/color_utils.h" 16#include "ui/gfx/image/image_skia_operations.h" 17 18namespace { 19 20const extensions::Extension* GetExtensionByID(Profile* profile, 21 const std::string& id) { 22 ExtensionService* service = 23 extensions::ExtensionSystem::Get(profile)->extension_service(); 24 if (!service) 25 return NULL; 26 return service->GetInstalledExtension(id); 27} 28 29} // namespace 30 31namespace extensions { 32 33AppIconLoaderImpl::AppIconLoaderImpl( 34 Profile* profile, 35 int icon_size, 36 AppIconLoader::Delegate* delegate) 37 : profile_(profile), 38 delegate_(delegate), 39 icon_size_(icon_size) { 40 41} 42 43AppIconLoaderImpl::~AppIconLoaderImpl() { 44 STLDeleteContainerPairFirstPointers(map_.begin(), map_.end()); 45} 46 47void AppIconLoaderImpl::FetchImage(const std::string& id) { 48 for (ImageToExtensionIDMap::const_iterator i = map_.begin(); 49 i != map_.end(); ++i) { 50 if (i->second == id) 51 return; // Already loading the image. 52 } 53 54 const extensions::Extension* extension = GetExtensionByID(profile_, id); 55 if (!extension) 56 return; 57 58 extensions::IconImage* image = new extensions::IconImage( 59 profile_, 60 extension, 61 extensions::IconsInfo::GetIcons(extension), 62 icon_size_, 63 extensions::util::GetDefaultAppIcon(), 64 this); 65 // |map_| takes ownership of |image|. 66 map_[image] = id; 67 68 // Triggers image loading now instead of depending on paint message. This 69 // makes the temp blank image be shown for shorter time and improves user 70 // experience. See http://crbug.com/146114. 71 image->image_skia().EnsureRepsForSupportedScales(); 72} 73 74void AppIconLoaderImpl::ClearImage(const std::string& id) { 75 for (ImageToExtensionIDMap::iterator i = map_.begin(); 76 i != map_.end(); ++i) { 77 if (i->second == id) { 78 delete i->first; 79 map_.erase(i); 80 break; 81 } 82 } 83} 84 85void AppIconLoaderImpl::UpdateImage(const std::string& id) { 86 for (ImageToExtensionIDMap::iterator i = map_.begin(); 87 i != map_.end(); ++i) { 88 if (i->second == id) { 89 BuildImage(i->second, i->first->image_skia()); 90 break; 91 } 92 } 93} 94 95void AppIconLoaderImpl::OnExtensionIconImageChanged( 96 extensions::IconImage* image) { 97 ImageToExtensionIDMap::iterator i = map_.find(image); 98 if (i == map_.end()) 99 return; // The image has been removed, do nothing. 100 101 BuildImage(i->second, i->first->image_skia()); 102} 103 104void AppIconLoaderImpl::BuildImage(const std::string& id, 105 const gfx::ImageSkia& icon) { 106 gfx::ImageSkia image = icon; 107 108 if (!util::IsAppLaunchable(id, profile_)) { 109 const color_utils::HSL shift = {-1, 0, 0.6}; 110 image = gfx::ImageSkiaOperations::CreateHSLShiftedImage(image, shift); 111 } 112 113 delegate_->SetAppImage(id, image); 114} 115 116} // namespace extensions 117