summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_icon_manager.cc
blob: 1e3befcc89677f6f72a0aed4f23243cc06ee9723 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright (c) 2010 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 "app/resource_bundle.h"
#include "base/logging.h"
#include "base/stl_util-inl.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_resource.h"
#include "gfx/color_utils.h"
#include "gfx/favicon_size.h"
#include "gfx/skbitmap_operations.h"
#include "gfx/size.h"
#include "grit/theme_resources.h"
#include "skia/ext/image_operations.h"

ExtensionIconManager::ExtensionIconManager()
    : ALLOW_THIS_IN_INITIALIZER_LIST(image_tracker_(this)),
      monochrome_(false) {
}

void ExtensionIconManager::LoadIcon(Extension* extension) {
  ExtensionResource icon_resource;
  extension->GetIconPathAllowLargerSize(&icon_resource,
                                        Extension::EXTENSION_ICON_BITTY);
  if (!icon_resource.extension_root().empty()) {
    image_tracker_.LoadImage(extension,
                             icon_resource,
                             gfx::Size(kFavIconSize, kFavIconSize),
                             ImageLoadingTracker::CACHE);
    pending_icons_.insert(extension->id());
  }
}

const SkBitmap& ExtensionIconManager::GetIcon(const std::string& extension_id) {
  const SkBitmap* result = NULL;
  if (ContainsKey(icons_, extension_id)) {
    result = &icons_[extension_id];
  } else {
    EnsureDefaultIcon();
    result = &default_icon_;
  }
  DCHECK(result);
  DCHECK(result->width() == kFavIconSize);
  DCHECK(result->height() == kFavIconSize);
  return *result;
}

void ExtensionIconManager::RemoveIcon(const std::string& extension_id) {
  icons_.erase(extension_id);
  pending_icons_.erase(extension_id);
}

void ExtensionIconManager::OnImageLoaded(SkBitmap* image,
                                         ExtensionResource resource,
                                         int index) {
  if (!image)
    return;

  const std::string extension_id = resource.extension_id();

  // We may have removed the icon while waiting for it to load. In that case,
  // do nothing.
  if (!ContainsKey(pending_icons_, extension_id))
    return;

  pending_icons_.erase(extension_id);
  icons_[extension_id] = ApplyTransforms(*image);
}

void ExtensionIconManager::EnsureDefaultIcon() {
  if (default_icon_.empty()) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    SkBitmap* src = rb.GetBitmapNamed(IDR_EXTENSIONS_SECTION);
    default_icon_ = ApplyTransforms(*src);
  }
}

SkBitmap ExtensionIconManager::ApplyTransforms(const SkBitmap& source) {
  SkBitmap result = source;

  if (result.width() != kFavIconSize || result.height() != kFavIconSize) {
    result = skia::ImageOperations::Resize(
        result, skia::ImageOperations::RESIZE_LANCZOS3,
        kFavIconSize, kFavIconSize);
  }

  if (monochrome_) {
    color_utils::HSL shift = {-1, 0, 0.6};
    result = SkBitmapOperations::CreateHSLShiftedBitmap(result, shift);
  }

  return result;
}