Home | History | Annotate | Download | only in extensions
      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 
     18 namespace {
     19 
     20 const 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 
     31 namespace extensions {
     32 
     33 AppIconLoaderImpl::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 
     43 AppIconLoaderImpl::~AppIconLoaderImpl() {
     44   STLDeleteContainerPairFirstPointers(map_.begin(), map_.end());
     45 }
     46 
     47 void 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 
     74 void 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 
     85 void 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 
     95 void 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 
    104 void 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