[Extensions UI] Add a placeholder icon for extensions in the toolbar
[chromium-blink-merge.git] / chrome / browser / extensions / extension_action.h
blobefdceeef6509828d233fbc761dd4228563962c0b
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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_
8 #include <map>
9 #include <string>
10 #include <vector>
12 #include "base/memory/scoped_ptr.h"
13 #include "base/stl_util.h"
14 #include "chrome/common/extensions/api/extension_action/action_info.h"
15 #include "third_party/skia/include/core/SkColor.h"
17 class GURL;
19 namespace content {
20 class BrowserContext;
23 namespace extensions {
24 class Extension;
25 class IconImage;
28 namespace gfx {
29 class Canvas;
30 class Image;
31 class ImageSkia;
32 class Rect;
33 class Size;
36 // ExtensionAction encapsulates the state of a browser action or page action.
37 // Instances can have both global and per-tab state. If a property does not have
38 // a per-tab value, the global value is used instead.
39 class ExtensionAction {
40 public:
41 // The action that the UI should take after the ExtensionAction is clicked.
42 enum ShowAction {
43 ACTION_NONE,
44 ACTION_SHOW_POPUP,
45 // We don't need a SHOW_CONTEXT_MENU because that's handled separately in
46 // the UI.
49 // Use this ID to indicate the default state for properties that take a tab_id
50 // parameter.
51 static const int kDefaultTabId;
53 // Max size (both dimensions) for page actions.
54 static const int kPageActionIconMaxSize;
56 ExtensionAction(const extensions::Extension& extension,
57 extensions::ActionInfo::Type action_type,
58 const extensions::ActionInfo& manifest_data);
59 ~ExtensionAction();
61 // extension id
62 const std::string& extension_id() const { return extension_id_; }
64 // What kind of action is this?
65 extensions::ActionInfo::Type action_type() const {
66 return action_type_;
69 // action id -- only used with legacy page actions API
70 std::string id() const { return id_; }
71 void set_id(const std::string& id) { id_ = id; }
73 // Set the url which the popup will load when the user clicks this action's
74 // icon. Setting an empty URL will disable the popup for a given tab.
75 void SetPopupUrl(int tab_id, const GURL& url);
77 // Use HasPopup() to see if a popup should be displayed.
78 bool HasPopup(int tab_id) const;
80 // Get the URL to display in a popup.
81 GURL GetPopupUrl(int tab_id) const;
83 // Set this action's title on a specific tab.
84 void SetTitle(int tab_id, const std::string& title) {
85 SetValue(&title_, tab_id, title);
88 // If tab |tab_id| has a set title, return it. Otherwise, return
89 // the default title.
90 std::string GetTitle(int tab_id) const { return GetValue(&title_, tab_id); }
92 // Icons are a bit different because the default value can be set to either a
93 // bitmap or a path. However, conceptually, there is only one default icon.
94 // Setting the default icon using a path clears the bitmap and vice-versa.
95 // To retrieve the icon for the extension action, use
96 // ExtensionActionIconFactory.
98 // Set this action's icon bitmap on a specific tab.
99 void SetIcon(int tab_id, const gfx::Image& image);
101 // Tries to parse |*icon| from a dictionary {"19": imageData19, "38":
102 // imageData38}, returning false if a value is corrupt.
103 static bool ParseIconFromCanvasDictionary(const base::DictionaryValue& dict,
104 gfx::ImageSkia* icon);
106 // Gets the icon that has been set using |SetIcon| for the tab.
107 gfx::Image GetExplicitlySetIcon(int tab_id) const;
109 // Sets the icon for a tab, in a way that can't be read by the extension's
110 // javascript. Multiple icons can be set at the same time; some icon with the
111 // highest priority will be used.
112 void DeclarativeSetIcon(int tab_id, int priority, const gfx::Image& icon);
113 void UndoDeclarativeSetIcon(int tab_id, int priority, const gfx::Image& icon);
115 const ExtensionIconSet* default_icon() const {
116 return default_icon_.get();
119 // Set this action's badge text on a specific tab.
120 void SetBadgeText(int tab_id, const std::string& text) {
121 SetValue(&badge_text_, tab_id, text);
123 // Get the badge text for a tab, or the default if no badge text was set.
124 std::string GetBadgeText(int tab_id) const {
125 return GetValue(&badge_text_, tab_id);
128 // Set this action's badge text color on a specific tab.
129 void SetBadgeTextColor(int tab_id, SkColor text_color) {
130 SetValue(&badge_text_color_, tab_id, text_color);
132 // Get the text color for a tab, or the default color if no text color
133 // was set.
134 SkColor GetBadgeTextColor(int tab_id) const {
135 return GetValue(&badge_text_color_, tab_id);
138 // Set this action's badge background color on a specific tab.
139 void SetBadgeBackgroundColor(int tab_id, SkColor color) {
140 SetValue(&badge_background_color_, tab_id, color);
142 // Get the badge background color for a tab, or the default if no color
143 // was set.
144 SkColor GetBadgeBackgroundColor(int tab_id) const {
145 return GetValue(&badge_background_color_, tab_id);
148 // Set this action's badge visibility on a specific tab. Returns true if
149 // the visibility has changed.
150 bool SetIsVisible(int tab_id, bool value);
151 // The declarative appearance overrides a default appearance but is overridden
152 // by an appearance set directly on the tab.
153 void DeclarativeShow(int tab_id);
154 void UndoDeclarativeShow(int tab_id);
155 const gfx::Image GetDeclarativeIcon(int tab_id) const;
157 // Get the badge visibility for a tab, or the default badge visibility
158 // if none was set.
159 // Gets the visibility of |tab_id|. Returns the first of: a specific
160 // visibility set on the tab; a declarative visibility set on the tab; the
161 // default visibility set for all tabs; or |false|. Don't return this
162 // result to an extension's background page because the declarative state can
163 // leak information about hosts the extension doesn't have permission to
164 // access.
165 bool GetIsVisible(int tab_id) const {
166 if (const bool* tab_is_visible = FindOrNull(&is_visible_, tab_id))
167 return *tab_is_visible;
169 if (ContainsKey(declarative_show_count_, tab_id))
170 return true;
172 if (const bool* default_is_visible =
173 FindOrNull(&is_visible_, kDefaultTabId))
174 return *default_is_visible;
176 return false;
179 // Remove all tab-specific state.
180 void ClearAllValuesForTab(int tab_id);
182 // If the specified tab has a badge, paint it into the provided bounds.
183 void PaintBadge(gfx::Canvas* canvas, const gfx::Rect& bounds, int tab_id);
185 // Returns icon image with badge for specified tab.
186 gfx::ImageSkia GetIconWithBadge(const gfx::ImageSkia& icon,
187 int tab_id,
188 const gfx::Size& spacing) const;
190 // Lazily loads and returns the default icon image, if one exists for the
191 // action.
192 extensions::IconImage* LoadDefaultIconImage(
193 const extensions::Extension& extension,
194 content::BrowserContext* browser_context);
196 // Returns the image to use as the default icon for the action. Can only be
197 // called after LoadDefaultIconImage().
198 gfx::Image GetDefaultIconImage() const;
200 // Determine whether or not the ExtensionAction has a value set for the given
201 // |tab_id| for each property.
202 bool HasPopupUrl(int tab_id) const;
203 bool HasTitle(int tab_id) const;
204 bool HasBadgeText(int tab_id) const;
205 bool HasBadgeBackgroundColor(int tab_id) const;
206 bool HasBadgeTextColor(int tab_id) const;
207 bool HasIsVisible(int tab_id) const;
208 bool HasIcon(int tab_id) const;
210 void SetDefaultIconForTest(scoped_ptr<ExtensionIconSet> default_icon);
212 private:
213 // Populates the action from the |extension| and |manifest_data|, filling in
214 // any missing values (like title or icons) as possible.
215 void Populate(const extensions::Extension& extension,
216 const extensions::ActionInfo& manifest_data);
218 // Returns width of the current icon for tab_id.
219 // TODO(tbarzic): The icon selection is done in ExtensionActionIconFactory.
220 // We should probably move this there too.
221 int GetIconWidth(int tab_id) const;
223 template <class T>
224 struct ValueTraits {
225 static T CreateEmpty() {
226 return T();
230 template<class T>
231 void SetValue(std::map<int, T>* map, int tab_id, const T& val) {
232 (*map)[tab_id] = val;
235 template<class Map>
236 static const typename Map::mapped_type* FindOrNull(
237 const Map* map,
238 const typename Map::key_type& key) {
239 typename Map::const_iterator iter = map->find(key);
240 if (iter == map->end())
241 return NULL;
242 return &iter->second;
245 template<class T>
246 T GetValue(const std::map<int, T>* map, int tab_id) const {
247 if (const T* tab_value = FindOrNull(map, tab_id)) {
248 return *tab_value;
249 } else if (const T* default_value = FindOrNull(map, kDefaultTabId)) {
250 return *default_value;
251 } else {
252 return ValueTraits<T>::CreateEmpty();
256 // The id for the extension this action belongs to (as defined in the
257 // extension manifest).
258 const std::string extension_id_;
260 // The name of the extension.
261 const std::string extension_name_;
263 const extensions::ActionInfo::Type action_type_;
265 // Each of these data items can have both a global state (stored with the key
266 // kDefaultTabId), or tab-specific state (stored with the tab_id as the key).
267 std::map<int, GURL> popup_url_;
268 std::map<int, std::string> title_;
269 std::map<int, gfx::Image> icon_;
270 std::map<int, std::string> badge_text_;
271 std::map<int, SkColor> badge_background_color_;
272 std::map<int, SkColor> badge_text_color_;
273 std::map<int, bool> is_visible_;
275 // Declarative state exists for two reasons: First, we need to hide it from
276 // the extension's background/event page to avoid leaking data from hosts the
277 // extension doesn't have permission to access. Second, the action's state
278 // gets both reset and given its declarative values in response to a
279 // WebContentsObserver::DidNavigateMainFrame event, and there's no way to set
280 // those up to be called in the right order.
282 // Maps tab_id to the number of active (applied-but-not-reverted)
283 // declarativeContent.ShowPageAction actions.
284 std::map<int, int> declarative_show_count_;
286 // declarative_icon_[tab_id][declarative_rule_priority] is a vector of icon
287 // images that are currently in effect
288 std::map<int, std::map<int, std::vector<gfx::Image> > > declarative_icon_;
290 // ExtensionIconSet containing paths to bitmaps from which default icon's
291 // image representations will be selected.
292 scoped_ptr<ExtensionIconSet> default_icon_;
294 // The default icon image, if |default_icon_| exists.
295 // Lazily initialized via LoadDefaultIconImage().
296 scoped_ptr<extensions::IconImage> default_icon_image_;
298 // The id for the ExtensionAction, for example: "RssPageAction". This is
299 // needed for compat with an older version of the page actions API.
300 std::string id_;
302 DISALLOW_COPY_AND_ASSIGN(ExtensionAction);
305 template<>
306 struct ExtensionAction::ValueTraits<int> {
307 static int CreateEmpty() {
308 return -1;
312 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_