Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_action.cc
blobddf8d4f080d78a1af85f17ada06ef36abcd1c388
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.
5 #include "chrome/browser/extensions/extension_action.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "chrome/common/badge_util.h"
13 #include "chrome/common/icon_with_badge_image_source.h"
14 #include "extensions/common/constants.h"
15 #include "grit/theme_resources.h"
16 #include "grit/ui_resources.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "third_party/skia/include/core/SkCanvas.h"
19 #include "third_party/skia/include/core/SkPaint.h"
20 #include "third_party/skia/include/effects/SkGradientShader.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/animation/animation_delegate.h"
23 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/color_utils.h"
25 #include "ui/gfx/image/image.h"
26 #include "ui/gfx/image/image_skia.h"
27 #include "ui/gfx/image/image_skia_source.h"
28 #include "ui/gfx/rect.h"
29 #include "ui/gfx/size.h"
30 #include "ui/gfx/skbitmap_operations.h"
31 #include "url/gurl.h"
33 namespace {
35 class GetAttentionImageSource : public gfx::ImageSkiaSource {
36 public:
37 explicit GetAttentionImageSource(const gfx::ImageSkia& icon)
38 : icon_(icon) {}
40 // gfx::ImageSkiaSource overrides:
41 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
42 gfx::ImageSkiaRep icon_rep = icon_.GetRepresentation(scale);
43 color_utils::HSL shift = {-1, 0, 0.5};
44 return gfx::ImageSkiaRep(
45 SkBitmapOperations::CreateHSLShiftedBitmap(icon_rep.sk_bitmap(), shift),
46 icon_rep.scale());
49 private:
50 const gfx::ImageSkia icon_;
53 template <class T>
54 bool HasValue(const std::map<int, T>& map, int tab_id) {
55 return map.find(tab_id) != map.end();
58 } // namespace
60 const int ExtensionAction::kDefaultTabId = -1;
61 const int ExtensionAction::kPageActionIconMaxSize = 19;
63 ExtensionAction::ExtensionAction(const std::string& extension_id,
64 extensions::ActionInfo::Type action_type,
65 const extensions::ActionInfo& manifest_data)
66 : extension_id_(extension_id), action_type_(action_type) {
67 // Page/script actions are hidden/disabled by default, and browser actions are
68 // visible/enabled by default.
69 SetIsVisible(kDefaultTabId,
70 action_type == extensions::ActionInfo::TYPE_BROWSER);
71 SetTitle(kDefaultTabId, manifest_data.default_title);
72 SetPopupUrl(kDefaultTabId, manifest_data.default_popup_url);
73 if (!manifest_data.default_icon.empty()) {
74 set_default_icon(make_scoped_ptr(new ExtensionIconSet(
75 manifest_data.default_icon)));
77 set_id(manifest_data.id);
80 ExtensionAction::~ExtensionAction() {
83 scoped_ptr<ExtensionAction> ExtensionAction::CopyForTest() const {
84 scoped_ptr<ExtensionAction> copy(
85 new ExtensionAction(extension_id_, action_type_,
86 extensions::ActionInfo()));
87 copy->popup_url_ = popup_url_;
88 copy->title_ = title_;
89 copy->icon_ = icon_;
90 copy->badge_text_ = badge_text_;
91 copy->badge_background_color_ = badge_background_color_;
92 copy->badge_text_color_ = badge_text_color_;
93 copy->is_visible_ = is_visible_;
94 copy->id_ = id_;
96 if (default_icon_)
97 copy->default_icon_.reset(new ExtensionIconSet(*default_icon_));
99 return copy.Pass();
102 // static
103 int ExtensionAction::GetIconSizeForType(
104 extensions::ActionInfo::Type type) {
105 switch (type) {
106 case extensions::ActionInfo::TYPE_BROWSER:
107 case extensions::ActionInfo::TYPE_PAGE:
108 case extensions::ActionInfo::TYPE_SYSTEM_INDICATOR:
109 // TODO(dewittj) Report the actual icon size of the system
110 // indicator.
111 return extension_misc::EXTENSION_ICON_ACTION;
112 default:
113 NOTREACHED();
114 return 0;
118 void ExtensionAction::SetPopupUrl(int tab_id, const GURL& url) {
119 // We store |url| even if it is empty, rather than removing a URL from the
120 // map. If an extension has a default popup, and removes it for a tab via
121 // the API, we must remember that there is no popup for that specific tab.
122 // If we removed the tab's URL, GetPopupURL would incorrectly return the
123 // default URL.
124 SetValue(&popup_url_, tab_id, url);
127 bool ExtensionAction::HasPopup(int tab_id) const {
128 return !GetPopupUrl(tab_id).is_empty();
131 GURL ExtensionAction::GetPopupUrl(int tab_id) const {
132 return GetValue(&popup_url_, tab_id);
135 void ExtensionAction::SetIcon(int tab_id, const gfx::Image& image) {
136 SetValue(&icon_, tab_id, image.AsImageSkia());
139 gfx::ImageSkia ExtensionAction::GetExplicitlySetIcon(int tab_id) const {
140 return GetValue(&icon_, tab_id);
143 bool ExtensionAction::SetIsVisible(int tab_id, bool new_visibility) {
144 const bool old_visibility = GetValue(&is_visible_, tab_id);
146 if (old_visibility == new_visibility)
147 return false;
149 SetValue(&is_visible_, tab_id, new_visibility);
151 return true;
154 void ExtensionAction::DeclarativeShow(int tab_id) {
155 DCHECK_NE(tab_id, kDefaultTabId);
156 ++declarative_show_count_[tab_id]; // Use default initialization to 0.
159 void ExtensionAction::UndoDeclarativeShow(int tab_id) {
160 int& show_count = declarative_show_count_[tab_id];
161 DCHECK_GT(show_count, 0);
162 if (--show_count == 0)
163 declarative_show_count_.erase(tab_id);
166 void ExtensionAction::ClearAllValuesForTab(int tab_id) {
167 popup_url_.erase(tab_id);
168 title_.erase(tab_id);
169 icon_.erase(tab_id);
170 badge_text_.erase(tab_id);
171 badge_text_color_.erase(tab_id);
172 badge_background_color_.erase(tab_id);
173 is_visible_.erase(tab_id);
174 // TODO(jyasskin): Erase the element from declarative_show_count_
175 // when the tab's closed. There's a race between the
176 // PageActionController and the ContentRulesRegistry on navigation,
177 // which prevents me from cleaning everything up now.
180 void ExtensionAction::PaintBadge(gfx::Canvas* canvas,
181 const gfx::Rect& bounds,
182 int tab_id) {
183 badge_util::PaintBadge(
184 canvas,
185 bounds,
186 GetBadgeText(tab_id),
187 GetBadgeTextColor(tab_id),
188 GetBadgeBackgroundColor(tab_id),
189 GetIconWidth(tab_id),
190 action_type());
193 gfx::ImageSkia ExtensionAction::GetIconWithBadge(
194 const gfx::ImageSkia& icon,
195 int tab_id,
196 const gfx::Size& spacing) const {
197 if (tab_id < 0)
198 return icon;
200 return gfx::ImageSkia(
201 new IconWithBadgeImageSource(icon,
202 icon.size(),
203 spacing,
204 GetBadgeText(tab_id),
205 GetBadgeTextColor(tab_id),
206 GetBadgeBackgroundColor(tab_id),
207 action_type()),
208 icon.size());
211 bool ExtensionAction::HasPopupUrl(int tab_id) const {
212 return HasValue(popup_url_, tab_id);
215 bool ExtensionAction::HasTitle(int tab_id) const {
216 return HasValue(title_, tab_id);
219 bool ExtensionAction::HasBadgeText(int tab_id) const {
220 return HasValue(badge_text_, tab_id);
223 bool ExtensionAction::HasBadgeBackgroundColor(int tab_id) const {
224 return HasValue(badge_background_color_, tab_id);
227 bool ExtensionAction::HasBadgeTextColor(int tab_id) const {
228 return HasValue(badge_text_color_, tab_id);
231 bool ExtensionAction::HasIsVisible(int tab_id) const {
232 return HasValue(is_visible_, tab_id);
235 bool ExtensionAction::HasIcon(int tab_id) const {
236 return HasValue(icon_, tab_id);
239 // Determines which icon would be returned by |GetIcon|, and returns its width.
240 int ExtensionAction::GetIconWidth(int tab_id) const {
241 // If icon has been set, return its width.
242 gfx::ImageSkia icon = GetValue(&icon_, tab_id);
243 if (!icon.isNull())
244 return icon.width();
245 // If there is a default icon, the icon width will be set depending on our
246 // action type.
247 if (default_icon_)
248 return GetIconSizeForType(action_type());
250 // If no icon has been set and there is no default icon, we need favicon
251 // width.
252 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(
253 IDR_EXTENSIONS_FAVICON).ToImageSkia()->width();