Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: chrome/browser/extensions/extension_action.cc

Issue 885443004: [Extensions] Cache extension action icons (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_action.h" 5 #include "chrome/browser/extensions/extension_action.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/bind.h"
11 #include "base/logging.h" 10 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "chrome/common/badge_util.h" 11 #include "chrome/common/badge_util.h"
14 #include "chrome/common/icon_with_badge_image_source.h" 12 #include "chrome/common/icon_with_badge_image_source.h"
13 #include "extensions/browser/extension_icon_image.h"
15 #include "extensions/common/constants.h" 14 #include "extensions/common/constants.h"
15 #include "extensions/common/extension_icon_set.h"
16 #include "extensions/common/manifest_handlers/icons_handler.h"
16 #include "grit/theme_resources.h" 17 #include "grit/theme_resources.h"
17 #include "grit/ui_resources.h" 18 #include "grit/ui_resources.h"
18 #include "ipc/ipc_message.h" 19 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_message_utils.h" 20 #include "ipc/ipc_message_utils.h"
20 #include "third_party/skia/include/core/SkBitmap.h" 21 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "third_party/skia/include/core/SkCanvas.h" 22 #include "third_party/skia/include/core/SkCanvas.h"
22 #include "third_party/skia/include/core/SkPaint.h" 23 #include "third_party/skia/include/core/SkPaint.h"
23 #include "third_party/skia/include/effects/SkGradientShader.h" 24 #include "third_party/skia/include/effects/SkGradientShader.h"
24 #include "ui/base/resource/resource_bundle.h" 25 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/gfx/animation/animation_delegate.h" 26 #include "ui/gfx/animation/animation_delegate.h"
26 #include "ui/gfx/canvas.h" 27 #include "ui/gfx/canvas.h"
27 #include "ui/gfx/color_utils.h" 28 #include "ui/gfx/color_utils.h"
28 #include "ui/gfx/geometry/rect.h" 29 #include "ui/gfx/geometry/rect.h"
29 #include "ui/gfx/geometry/size.h" 30 #include "ui/gfx/geometry/size.h"
30 #include "ui/gfx/image/image.h" 31 #include "ui/gfx/image/image.h"
31 #include "ui/gfx/image/image_skia.h" 32 #include "ui/gfx/image/image_skia.h"
32 #include "ui/gfx/image/image_skia_source.h" 33 #include "ui/gfx/image/image_skia_source.h"
33 #include "ui/gfx/ipc/gfx_param_traits.h" 34 #include "ui/gfx/ipc/gfx_param_traits.h"
34 #include "ui/gfx/skbitmap_operations.h" 35 #include "ui/gfx/skbitmap_operations.h"
35 #include "url/gurl.h" 36 #include "url/gurl.h"
36 37
37 namespace { 38 namespace {
38 39
40 // Returns the default icon image for extensions.
41 gfx::Image GetDefaultIcon() {
42 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
43 IDR_EXTENSIONS_FAVICON);
44 }
45
46 // Given the extension action type, returns the size the extension action icon
47 // should have. The icon should be square, so only one dimension is
48 // returned.
49 int GetIconSizeForType(extensions::ActionInfo::Type type) {
50 switch (type) {
51 case extensions::ActionInfo::TYPE_BROWSER:
52 case extensions::ActionInfo::TYPE_PAGE:
53 case extensions::ActionInfo::TYPE_SYSTEM_INDICATOR:
54 // TODO(dewittj) Report the actual icon size of the system
55 // indicator.
56 return extension_misc::EXTENSION_ICON_ACTION;
57 default:
58 NOTREACHED();
59 return 0;
60 }
61 }
62
39 class GetAttentionImageSource : public gfx::ImageSkiaSource { 63 class GetAttentionImageSource : public gfx::ImageSkiaSource {
40 public: 64 public:
41 explicit GetAttentionImageSource(const gfx::ImageSkia& icon) 65 explicit GetAttentionImageSource(const gfx::ImageSkia& icon)
42 : icon_(icon) {} 66 : icon_(icon) {}
43 67
44 // gfx::ImageSkiaSource overrides: 68 // gfx::ImageSkiaSource overrides:
45 gfx::ImageSkiaRep GetImageForScale(float scale) override { 69 gfx::ImageSkiaRep GetImageForScale(float scale) override {
46 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale); 70 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale);
47 color_utils::HSL shift = {-1, 0, 0.5}; 71 color_utils::HSL shift = {-1, 0, 0.5};
48 return gfx::ImageSkiaRep( 72 return gfx::ImageSkiaRep(
(...skipping 20 matching lines...) Expand all
69 bool HasValue(const std::map<int, T>& map, int tab_id) { 93 bool HasValue(const std::map<int, T>& map, int tab_id) {
70 return map.find(tab_id) != map.end(); 94 return map.find(tab_id) != map.end();
71 } 95 }
72 96
73 } // namespace 97 } // namespace
74 98
75 const int ExtensionAction::kDefaultTabId = -1; 99 const int ExtensionAction::kDefaultTabId = -1;
76 const int ExtensionAction::kPageActionIconMaxSize = 100 const int ExtensionAction::kPageActionIconMaxSize =
77 extension_misc::EXTENSION_ICON_ACTION; 101 extension_misc::EXTENSION_ICON_ACTION;
78 102
79 ExtensionAction::ExtensionAction(const std::string& extension_id, 103 ExtensionAction::ExtensionAction(const extensions::Extension& extension,
80 extensions::ActionInfo::Type action_type, 104 extensions::ActionInfo::Type action_type,
81 const extensions::ActionInfo& manifest_data) 105 const extensions::ActionInfo& manifest_data)
82 : extension_id_(extension_id), action_type_(action_type) { 106 : extension_id_(extension.id()), action_type_(action_type) {
83 // Page/script actions are hidden/disabled by default, and browser actions are 107 // Page/script actions are hidden/disabled by default, and browser actions are
84 // visible/enabled by default. 108 // visible/enabled by default.
85 SetIsVisible(kDefaultTabId, 109 SetIsVisible(kDefaultTabId,
86 action_type == extensions::ActionInfo::TYPE_BROWSER); 110 action_type == extensions::ActionInfo::TYPE_BROWSER);
87 SetTitle(kDefaultTabId, manifest_data.default_title); 111 Populate(extension, manifest_data);
88 SetPopupUrl(kDefaultTabId, manifest_data.default_popup_url);
89 if (!manifest_data.default_icon.empty()) {
90 set_default_icon(make_scoped_ptr(new ExtensionIconSet(
91 manifest_data.default_icon)));
92 }
93 set_id(manifest_data.id);
94 } 112 }
95 113
96 ExtensionAction::~ExtensionAction() { 114 ExtensionAction::~ExtensionAction() {
97 } 115 }
98 116
99 scoped_ptr<ExtensionAction> ExtensionAction::CopyForTest() const {
100 scoped_ptr<ExtensionAction> copy(
101 new ExtensionAction(extension_id_, action_type_,
102 extensions::ActionInfo()));
103 copy->popup_url_ = popup_url_;
104 copy->title_ = title_;
105 copy->icon_ = icon_;
106 copy->badge_text_ = badge_text_;
107 copy->badge_background_color_ = badge_background_color_;
108 copy->badge_text_color_ = badge_text_color_;
109 copy->is_visible_ = is_visible_;
110 copy->id_ = id_;
111
112 if (default_icon_)
113 copy->default_icon_.reset(new ExtensionIconSet(*default_icon_));
114
115 return copy.Pass();
116 }
117
118 // static
119 int ExtensionAction::GetIconSizeForType(
120 extensions::ActionInfo::Type type) {
121 switch (type) {
122 case extensions::ActionInfo::TYPE_BROWSER:
123 case extensions::ActionInfo::TYPE_PAGE:
124 case extensions::ActionInfo::TYPE_SYSTEM_INDICATOR:
125 // TODO(dewittj) Report the actual icon size of the system
126 // indicator.
127 return extension_misc::EXTENSION_ICON_ACTION;
128 default:
129 NOTREACHED();
130 return 0;
131 }
132 }
133
134 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) { 117 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) {
135 // We store |url| even if it is empty, rather than removing a URL from the 118 // We store |url| even if it is empty, rather than removing a URL from the
136 // map. If an extension has a default popup, and removes it for a tab via 119 // map. If an extension has a default popup, and removes it for a tab via
137 // the API, we must remember that there is no popup for that specific tab. 120 // the API, we must remember that there is no popup for that specific tab.
138 // If we removed the tab's URL, GetPopupURL would incorrectly return the 121 // If we removed the tab's URL, GetPopupURL would incorrectly return the
139 // default URL. 122 // default URL.
140 SetValue(&popup_url_, tab_id, url); 123 SetValue(&popup_url_, tab_id, url);
141 } 124 }
142 125
143 bool ExtensionAction::HasPopup(int tab_id) const { 126 bool ExtensionAction::HasPopup(int tab_id) const {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 new IconWithBadgeImageSource(icon, 258 new IconWithBadgeImageSource(icon,
276 icon.size(), 259 icon.size(),
277 spacing, 260 spacing,
278 GetBadgeText(tab_id), 261 GetBadgeText(tab_id),
279 GetBadgeTextColor(tab_id), 262 GetBadgeTextColor(tab_id),
280 GetBadgeBackgroundColor(tab_id), 263 GetBadgeBackgroundColor(tab_id),
281 action_type()), 264 action_type()),
282 icon.size()); 265 icon.size());
283 } 266 }
284 267
268 extensions::IconImage* ExtensionAction::LoadDefaultIconImage(
269 const extensions::Extension& extension,
270 content::BrowserContext* browser_context) {
271 if (default_icon_ && !default_icon_image_) {
272 default_icon_image_.reset(new extensions::IconImage(
273 browser_context,
274 &extension,
275 *default_icon(),
276 GetIconSizeForType(action_type_),
277 *GetDefaultIcon().ToImageSkia(),
278 nullptr));
279 }
280 return default_icon_image_.get();
281 }
282
283 gfx::ImageSkia ExtensionAction::GetDefaultIconImage() const {
284 // If we have a default icon, it should be loaded before trying to use it.
285 DCHECK(!default_icon_image_ == !default_icon_);
286 return default_icon_image_ ? default_icon_image_->image_skia() :
287 *GetDefaultIcon().ToImageSkia();
288 }
289
285 bool ExtensionAction::HasPopupUrl(int tab_id) const { 290 bool ExtensionAction::HasPopupUrl(int tab_id) const {
286 return HasValue(popup_url_, tab_id); 291 return HasValue(popup_url_, tab_id);
287 } 292 }
288 293
289 bool ExtensionAction::HasTitle(int tab_id) const { 294 bool ExtensionAction::HasTitle(int tab_id) const {
290 return HasValue(title_, tab_id); 295 return HasValue(title_, tab_id);
291 } 296 }
292 297
293 bool ExtensionAction::HasBadgeText(int tab_id) const { 298 bool ExtensionAction::HasBadgeText(int tab_id) const {
294 return HasValue(badge_text_, tab_id); 299 return HasValue(badge_text_, tab_id);
295 } 300 }
296 301
297 bool ExtensionAction::HasBadgeBackgroundColor(int tab_id) const { 302 bool ExtensionAction::HasBadgeBackgroundColor(int tab_id) const {
298 return HasValue(badge_background_color_, tab_id); 303 return HasValue(badge_background_color_, tab_id);
299 } 304 }
300 305
301 bool ExtensionAction::HasBadgeTextColor(int tab_id) const { 306 bool ExtensionAction::HasBadgeTextColor(int tab_id) const {
302 return HasValue(badge_text_color_, tab_id); 307 return HasValue(badge_text_color_, tab_id);
303 } 308 }
304 309
305 bool ExtensionAction::HasIsVisible(int tab_id) const { 310 bool ExtensionAction::HasIsVisible(int tab_id) const {
306 return HasValue(is_visible_, tab_id); 311 return HasValue(is_visible_, tab_id);
307 } 312 }
308 313
309 bool ExtensionAction::HasIcon(int tab_id) const { 314 bool ExtensionAction::HasIcon(int tab_id) const {
310 return HasValue(icon_, tab_id); 315 return HasValue(icon_, tab_id);
311 } 316 }
312 317
318 void ExtensionAction::SetDefaultIconForTest(
319 scoped_ptr<ExtensionIconSet> default_icon) {
320 default_icon_ = default_icon.Pass();
321 }
322
323 void ExtensionAction::Populate(const extensions::Extension& extension,
324 const extensions::ActionInfo& manifest_data) {
325 // If the manifest doesn't specify a title, set it to |extension|'s name.
326 const std::string& title =
327 !manifest_data.default_title.empty() ? manifest_data.default_title :
328 extension.name();
329 SetTitle(kDefaultTabId, title);
330 SetPopupUrl(kDefaultTabId, manifest_data.default_popup_url);
331 set_id(manifest_data.id);
332
333 // Initialize the specified icon set.
334 if (!manifest_data.default_icon.empty())
335 default_icon_.reset(new ExtensionIconSet(manifest_data.default_icon));
336
337 const ExtensionIconSet& extension_icons =
338 extensions::IconsInfo::GetIcons(&extension);
339 // Look for any other icons.
340 std::string largest_icon = extension_icons.Get(
341 extension_misc::EXTENSION_ICON_GIGANTOR,
342 ExtensionIconSet::MATCH_SMALLER);
343
344 if (!largest_icon.empty()) {
345 // We found an icon to use, so create an icon set if one doesn't exist.
346 if (!default_icon_)
347 default_icon_.reset(new ExtensionIconSet());
348 int largest_icon_size = extension_icons.GetIconSizeFromPath(largest_icon);
349 // Replace any missing extension action icons with the largest icon
350 // retrieved from |extension|'s manifest so long as the largest icon is
351 // larger than the current key.
352 for (int i = extension_misc::kNumExtensionActionIconSizes - 1;
353 i >= 0; --i) {
354 int size = extension_misc::kExtensionActionIconSizes[i].size;
355 if (default_icon_->Get(size, ExtensionIconSet::MATCH_BIGGER).empty()
356 && largest_icon_size > size) {
357 default_icon_->Add(size, largest_icon);
358 break;
359 }
360 }
361 }
362 }
363
313 // Determines which icon would be returned by |GetIcon|, and returns its width. 364 // Determines which icon would be returned by |GetIcon|, and returns its width.
314 int ExtensionAction::GetIconWidth(int tab_id) const { 365 int ExtensionAction::GetIconWidth(int tab_id) const {
315 // If icon has been set, return its width. 366 // If icon has been set, return its width.
316 gfx::ImageSkia icon = GetValue(&icon_, tab_id); 367 gfx::ImageSkia icon = GetValue(&icon_, tab_id);
317 if (!icon.isNull()) 368 if (!icon.isNull())
318 return icon.width(); 369 return icon.width();
319 // If there is a default icon, the icon width will be set depending on our 370 // If there is a default icon, the icon width will be set depending on our
320 // action type. 371 // action type.
321 if (default_icon_) 372 if (default_icon_)
322 return GetIconSizeForType(action_type()); 373 return GetIconSizeForType(action_type());
323 374
324 // If no icon has been set and there is no default icon, we need favicon 375 // If no icon has been set and there is no default icon, we need favicon
325 // width. 376 // width.
326 return ui::ResourceBundle::GetSharedInstance().GetImageNamed( 377 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
327 IDR_EXTENSIONS_FAVICON).ToImageSkia()->width(); 378 IDR_EXTENSIONS_FAVICON).Width();
328 } 379 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_action.h ('k') | chrome/browser/extensions/extension_action_icon_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698