Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_action.h
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 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/observer_list.h"
18 #include "chrome/common/extensions/api/extension_action/action_info.h"
19 #include "chrome/common/extensions/extension_icon_set.h"
20 #include "third_party/skia/include/core/SkColor.h"
21 // TODO(robertphillips): change this to "class SkBaseDevice;"
22 #include "third_party/skia/include/core/SkDevice.h"
23 #include "ui/gfx/animation/linear_animation.h"
24
25 class GURL;
26 class SkBitmap;
27
28 namespace gfx {
29 class Canvas;
30 class Image;
31 class ImageSkia;
32 class Rect;
33 class Size;
34 }
35
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   // Use this ID to indicate the default state for properties that take a tab_id
42   // parameter.
43   static const int kDefaultTabId;
44
45   ExtensionAction(const std::string& extension_id,
46                   extensions::ActionInfo::Type action_type,
47                   const extensions::ActionInfo& manifest_data);
48   ~ExtensionAction();
49
50   // Gets a copy of this, ownership passed to caller.
51   // It doesn't make sense to copy of an ExtensionAction except in tests.
52   scoped_ptr<ExtensionAction> CopyForTest() const;
53
54   // Given the extension action type, returns the size the extension action icon
55   // should have. The icon should be square, so only one dimension is
56   // returned.
57   static int GetIconSizeForType(extensions::ActionInfo::Type type);
58
59   // extension id
60   const std::string& extension_id() const { return extension_id_; }
61
62   // What kind of action is this?
63   extensions::ActionInfo::Type action_type() const {
64     return action_type_;
65   }
66
67   // action id -- only used with legacy page actions API
68   std::string id() const { return id_; }
69   void set_id(const std::string& id) { id_ = id; }
70
71   bool has_changed() const { return has_changed_; }
72   void set_has_changed(bool value) { has_changed_ = value; }
73
74   // Set the url which the popup will load when the user clicks this action's
75   // icon.  Setting an empty URL will disable the popup for a given tab.
76   void SetPopupUrl(int tab_id, const GURL& url);
77
78   // Use HasPopup() to see if a popup should be displayed.
79   bool HasPopup(int tab_id) const;
80
81   // Get the URL to display in a popup.
82   GURL GetPopupUrl(int tab_id) const;
83
84   // Set this action's title on a specific tab.
85   void SetTitle(int tab_id, const std::string& title) {
86     SetValue(&title_, tab_id, title);
87   }
88
89   // If tab |tab_id| has a set title, return it.  Otherwise, return
90   // the default title.
91   std::string GetTitle(int tab_id) const { return GetValue(&title_, tab_id); }
92
93   // Icons are a bit different because the default value can be set to either a
94   // bitmap or a path. However, conceptually, there is only one default icon.
95   // Setting the default icon using a path clears the bitmap and vice-versa.
96   // To retrieve the icon for the extension action, use
97   // ExtensionActionIconFactory.
98
99   // Set this action's icon bitmap on a specific tab.
100   void SetIcon(int tab_id, const gfx::Image& image);
101
102   // Gets the icon that has been set using |SetIcon| for the tab.
103   gfx::ImageSkia GetExplicitlySetIcon(int tab_id) const;
104
105   // Non-tab-specific icon path. This is used to support the default_icon key of
106   // page and browser actions.
107   void set_default_icon(scoped_ptr<ExtensionIconSet> icon_set) {
108      default_icon_ = icon_set.Pass();
109   }
110
111   const ExtensionIconSet* default_icon() const {
112     return default_icon_.get();
113   }
114
115   // Set this action's badge text on a specific tab.
116   void SetBadgeText(int tab_id, const std::string& text) {
117     SetValue(&badge_text_, tab_id, text);
118   }
119   // Get the badge text for a tab, or the default if no badge text was set.
120   std::string GetBadgeText(int tab_id) const {
121     return GetValue(&badge_text_, tab_id);
122   }
123
124   // Set this action's badge text color on a specific tab.
125   void SetBadgeTextColor(int tab_id, SkColor text_color) {
126     SetValue(&badge_text_color_, tab_id, text_color);
127   }
128   // Get the text color for a tab, or the default color if no text color
129   // was set.
130   SkColor GetBadgeTextColor(int tab_id) const {
131     return GetValue(&badge_text_color_, tab_id);
132   }
133
134   // Set this action's badge background color on a specific tab.
135   void SetBadgeBackgroundColor(int tab_id, SkColor color) {
136     SetValue(&badge_background_color_, tab_id, color);
137   }
138   // Get the badge background color for a tab, or the default if no color
139   // was set.
140   SkColor GetBadgeBackgroundColor(int tab_id) const {
141     return GetValue(&badge_background_color_, tab_id);
142   }
143
144   // Set this action's badge visibility on a specific tab.  Returns true if
145   // the visibility has changed.
146   bool SetIsVisible(int tab_id, bool value);
147   // The declarative appearance overrides a default appearance but is overridden
148   // by an appearance set directly on the tab.
149   void DeclarativeShow(int tab_id);
150   void UndoDeclarativeShow(int tab_id);
151
152   // Get the badge visibility for a tab, or the default badge visibility
153   // if none was set.
154   // Gets the visibility of |tab_id|.  Returns the first of: a specific
155   // visibility set on the tab; a declarative visibility set on the tab; the
156   // default visibility set for all tabs; or |false|.  Don't return this
157   // result to an extension's background page because the declarative state can
158   // leak information about hosts the extension doesn't have permission to
159   // access.
160   bool GetIsVisible(int tab_id) const {
161     if (const bool* tab_is_visible = FindOrNull(&is_visible_, tab_id))
162       return *tab_is_visible;
163
164     if (ContainsKey(declarative_show_count_, tab_id))
165       return true;
166
167     if (const bool* default_is_visible =
168         FindOrNull(&is_visible_, kDefaultTabId))
169       return *default_is_visible;
170
171     return false;
172   }
173
174   // Remove all tab-specific state.
175   void ClearAllValuesForTab(int tab_id);
176
177   // If the specified tab has a badge, paint it into the provided bounds.
178   void PaintBadge(gfx::Canvas* canvas, const gfx::Rect& bounds, int tab_id);
179
180   // Returns icon image with badge for specified tab.
181   gfx::ImageSkia GetIconWithBadge(const gfx::ImageSkia& icon,
182                                   int tab_id,
183                                   const gfx::Size& spacing) const;
184
185  private:
186   // Returns width of the current icon for tab_id.
187   // TODO(tbarzic): The icon selection is done in ExtensionActionIconFactory.
188   // We should probably move this there too.
189   int GetIconWidth(int tab_id) const;
190
191   template <class T>
192   struct ValueTraits {
193     static T CreateEmpty() {
194       return T();
195     }
196   };
197
198   template<class T>
199   void SetValue(std::map<int, T>* map, int tab_id, const T& val) {
200     (*map)[tab_id] = val;
201   }
202
203   template<class Map>
204   static const typename Map::mapped_type* FindOrNull(
205       const Map* map,
206       const typename Map::key_type& key) {
207     typename Map::const_iterator iter = map->find(key);
208     if (iter == map->end())
209       return NULL;
210     return &iter->second;
211   }
212
213   template<class T>
214   T GetValue(const std::map<int, T>* map, int tab_id) const {
215     if (const T* tab_value = FindOrNull(map, tab_id)) {
216       return *tab_value;
217     } else if (const T* default_value = FindOrNull(map, kDefaultTabId)) {
218       return *default_value;
219     } else {
220       return ValueTraits<T>::CreateEmpty();
221     }
222   }
223
224   // The id for the extension this action belongs to (as defined in the
225   // extension manifest).
226   const std::string extension_id_;
227
228   const extensions::ActionInfo::Type action_type_;
229
230   // Each of these data items can have both a global state (stored with the key
231   // kDefaultTabId), or tab-specific state (stored with the tab_id as the key).
232   std::map<int, GURL> popup_url_;
233   std::map<int, std::string> title_;
234   std::map<int, gfx::ImageSkia> icon_;
235   std::map<int, std::string> badge_text_;
236   std::map<int, SkColor> badge_background_color_;
237   std::map<int, SkColor> badge_text_color_;
238   std::map<int, bool> is_visible_;
239
240   // Declarative state exists for two reasons: First, we need to hide it from
241   // the extension's background/event page to avoid leaking data from hosts the
242   // extension doesn't have permission to access.  Second, the action's state
243   // gets both reset and given its declarative values in response to a
244   // WebContentsObserver::DidNavigateMainFrame event, and there's no way to set
245   // those up to be called in the right order.
246
247   // Maps tab_id to the number of active (applied-but-not-reverted)
248   // declarativeContent.ShowPageAction actions.
249   std::map<int, int> declarative_show_count_;
250
251   // ExtensionIconSet containing paths to bitmaps from which default icon's
252   // image representations will be selected.
253   scoped_ptr<const ExtensionIconSet> default_icon_;
254
255   // The id for the ExtensionAction, for example: "RssPageAction". This is
256   // needed for compat with an older version of the page actions API.
257   std::string id_;
258
259   // True if the ExtensionAction's settings have changed from what was
260   // specified in the manifest.
261   bool has_changed_;
262
263   DISALLOW_COPY_AND_ASSIGN(ExtensionAction);
264 };
265
266 template<>
267 struct ExtensionAction::ValueTraits<int> {
268   static int CreateEmpty() {
269     return -1;
270   }
271 };
272
273 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_