• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_API_EXTENSION_ACTION_EXTENSION_ACTION_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_EXTENSION_ACTION_EXTENSION_ACTION_API_H_
7 
8 #include <string>
9 
10 #include "base/observer_list.h"
11 #include "chrome/browser/extensions/chrome_extension_function.h"
12 #include "chrome/browser/extensions/extension_action.h"
13 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.h"
15 #include "extensions/browser/browser_context_keyed_api_factory.h"
16 #include "third_party/skia/include/core/SkColor.h"
17 
18 namespace base {
19 class DictionaryValue;
20 }
21 
22 namespace content {
23 class BrowserContext;
24 class WebContents;
25 }
26 
27 namespace extensions {
28 class ExtensionPrefs;
29 
30 class ExtensionActionAPI : public BrowserContextKeyedAPI {
31  public:
32   class Observer {
33    public:
34     // Called when there is a change to the given |extension_action|.
35     // |web_contents| is the web contents that was affected, and
36     // |browser_context| is the associated BrowserContext. (The latter is
37     // included because ExtensionActionAPI is shared between normal and
38     // incognito contexts, so |browser_context| may not equal
39     // |browser_context_|.)
40     virtual void OnExtensionActionUpdated(
41         ExtensionAction* extension_action,
42         content::WebContents* web_contents,
43         content::BrowserContext* browser_context);
44 
45     // Called when the page actions have been refreshed do to a possible change
46     // in count or visibility.
47     virtual void OnPageActionsUpdated(content::WebContents* web_contents);
48 
49     // Called when the ExtensionActionAPI is shutting down, giving observers a
50     // chance to unregister themselves if there is not a definitive lifecycle.
51     virtual void OnExtensionActionAPIShuttingDown();
52 
53    protected:
54     virtual ~Observer();
55   };
56 
57   explicit ExtensionActionAPI(content::BrowserContext* context);
58   virtual ~ExtensionActionAPI();
59 
60   // Convenience method to get the instance for a profile.
61   static ExtensionActionAPI* Get(content::BrowserContext* context);
62 
63   static bool GetBrowserActionVisibility(const ExtensionPrefs* prefs,
64                                          const std::string& extension_id);
65   static void SetBrowserActionVisibility(ExtensionPrefs* prefs,
66                                          const std::string& extension_id,
67                                          bool visible);
68 
69   // BrowserContextKeyedAPI implementation.
70   static BrowserContextKeyedAPIFactory<ExtensionActionAPI>*
71       GetFactoryInstance();
72 
73   // Add or remove observers.
74   void AddObserver(Observer* observer);
75   void RemoveObserver(Observer* observer);
76 
77   // Executes the action of the given |extension| on the |browser|'s active
78   // web contents. If |grant_tab_permissions| is true, this will also grant
79   // activeTab to the extension (so this should only be done if this is through
80   // a direct user action). Returns the action that should be taken.
81   ExtensionAction::ShowAction ExecuteExtensionAction(
82       const Extension* extension,
83       Browser* browser,
84       bool grant_active_tab_permissions);
85 
86   // Opens the popup for the given |extension| in the given |browser|'s window.
87   // If |grant_active_tab_permissions| is true, this grants the extension
88   // activeTab (so this should only be done if this is through a direct user
89   // action).
90   bool ShowExtensionActionPopup(const Extension* extension,
91                                 Browser* browser,
92                                 bool grant_active_tab_permissions);
93 
94   // Notifies that there has been a change in the given |extension_action|.
95   void NotifyChange(ExtensionAction* extension_action,
96                     content::WebContents* web_contents,
97                     content::BrowserContext* browser_context);
98 
99   // Clears the values for all ExtensionActions for the tab associated with the
100   // given |web_contents| (and signals that page actions changed).
101   void ClearAllValuesForTab(content::WebContents* web_contents);
102 
103   // Notifies that the current set of page actions for |web_contents| has
104   // changed, and signals the browser to update.
105   void NotifyPageActionsChanged(content::WebContents* web_contents);
106 
107  private:
108   friend class BrowserContextKeyedAPIFactory<ExtensionActionAPI>;
109 
110   // The DispatchEvent methods forward events to the |context|'s event router.
111   void DispatchEventToExtension(content::BrowserContext* context,
112                                 const std::string& extension_id,
113                                 const std::string& event_name,
114                                 scoped_ptr<base::ListValue> event_args);
115 
116   // Called when either a browser or page action is executed. Figures out which
117   // event to send based on what the extension wants.
118   void ExtensionActionExecuted(const ExtensionAction& extension_action,
119                                content::WebContents* web_contents);
120 
121   // BrowserContextKeyedAPI implementation.
122   virtual void Shutdown() OVERRIDE;
service_name()123   static const char* service_name() { return "ExtensionActionAPI"; }
124   static const bool kServiceRedirectedInIncognito = true;
125 
126   ObserverList<Observer> observers_;
127 
128   content::BrowserContext* browser_context_;
129 
130   DISALLOW_COPY_AND_ASSIGN(ExtensionActionAPI);
131 };
132 
133 // Implementation of the browserAction and pageAction APIs.
134 //
135 // Divergent behaviour between the two is minimal (pageAction has required
136 // tabIds while browserAction's are optional, they have different internal
137 // browser notification requirements, and not all functions are defined for all
138 // APIs).
139 class ExtensionActionFunction : public ChromeSyncExtensionFunction {
140  public:
141   static bool ParseCSSColorString(const std::string& color_string,
142                                   SkColor* result);
143 
144  protected:
145   ExtensionActionFunction();
146   virtual ~ExtensionActionFunction();
147   virtual bool RunSync() OVERRIDE;
148   virtual bool RunExtensionAction() = 0;
149 
150   bool ExtractDataFromArguments();
151   void NotifyChange();
152   bool SetVisible(bool visible);
153 
154   // All the extension action APIs take a single argument called details that
155   // is a dictionary.
156   base::DictionaryValue* details_;
157 
158   // The tab id the extension action function should apply to, if any, or
159   // kDefaultTabId if none was specified.
160   int tab_id_;
161 
162   // WebContents for |tab_id_| if one exists.
163   content::WebContents* contents_;
164 
165   // The extension action for the current extension.
166   ExtensionAction* extension_action_;
167 };
168 
169 //
170 // Implementations of each extension action API.
171 //
172 // pageAction and browserAction bindings are created for these by extending them
173 // then declaring an EXTENSION_FUNCTION_NAME.
174 //
175 
176 // show
177 class ExtensionActionShowFunction : public ExtensionActionFunction {
178  protected:
~ExtensionActionShowFunction()179   virtual ~ExtensionActionShowFunction() {}
180   virtual bool RunExtensionAction() OVERRIDE;
181 };
182 
183 // hide
184 class ExtensionActionHideFunction : public ExtensionActionFunction {
185  protected:
~ExtensionActionHideFunction()186   virtual ~ExtensionActionHideFunction() {}
187   virtual bool RunExtensionAction() OVERRIDE;
188 };
189 
190 // setIcon
191 class ExtensionActionSetIconFunction : public ExtensionActionFunction {
192  protected:
~ExtensionActionSetIconFunction()193   virtual ~ExtensionActionSetIconFunction() {}
194   virtual bool RunExtensionAction() OVERRIDE;
195 };
196 
197 // setTitle
198 class ExtensionActionSetTitleFunction : public ExtensionActionFunction {
199  protected:
~ExtensionActionSetTitleFunction()200   virtual ~ExtensionActionSetTitleFunction() {}
201   virtual bool RunExtensionAction() OVERRIDE;
202 };
203 
204 // setPopup
205 class ExtensionActionSetPopupFunction : public ExtensionActionFunction {
206  protected:
~ExtensionActionSetPopupFunction()207   virtual ~ExtensionActionSetPopupFunction() {}
208   virtual bool RunExtensionAction() OVERRIDE;
209 };
210 
211 // setBadgeText
212 class ExtensionActionSetBadgeTextFunction : public ExtensionActionFunction {
213  protected:
~ExtensionActionSetBadgeTextFunction()214   virtual ~ExtensionActionSetBadgeTextFunction() {}
215   virtual bool RunExtensionAction() OVERRIDE;
216 };
217 
218 // setBadgeBackgroundColor
219 class ExtensionActionSetBadgeBackgroundColorFunction
220     : public ExtensionActionFunction {
221  protected:
~ExtensionActionSetBadgeBackgroundColorFunction()222   virtual ~ExtensionActionSetBadgeBackgroundColorFunction() {}
223   virtual bool RunExtensionAction() OVERRIDE;
224 };
225 
226 // getTitle
227 class ExtensionActionGetTitleFunction : public ExtensionActionFunction {
228  protected:
~ExtensionActionGetTitleFunction()229   virtual ~ExtensionActionGetTitleFunction() {}
230   virtual bool RunExtensionAction() OVERRIDE;
231 };
232 
233 // getPopup
234 class ExtensionActionGetPopupFunction : public ExtensionActionFunction {
235  protected:
~ExtensionActionGetPopupFunction()236   virtual ~ExtensionActionGetPopupFunction() {}
237   virtual bool RunExtensionAction() OVERRIDE;
238 };
239 
240 // getBadgeText
241 class ExtensionActionGetBadgeTextFunction : public ExtensionActionFunction {
242  protected:
~ExtensionActionGetBadgeTextFunction()243   virtual ~ExtensionActionGetBadgeTextFunction() {}
244   virtual bool RunExtensionAction() OVERRIDE;
245 };
246 
247 // getBadgeBackgroundColor
248 class ExtensionActionGetBadgeBackgroundColorFunction
249     : public ExtensionActionFunction {
250  protected:
~ExtensionActionGetBadgeBackgroundColorFunction()251   virtual ~ExtensionActionGetBadgeBackgroundColorFunction() {}
252   virtual bool RunExtensionAction() OVERRIDE;
253 };
254 
255 //
256 // browserAction.* aliases for supported browserAction APIs.
257 //
258 
259 class BrowserActionSetIconFunction : public ExtensionActionSetIconFunction {
260  public:
261   DECLARE_EXTENSION_FUNCTION("browserAction.setIcon", BROWSERACTION_SETICON)
262 
263  protected:
~BrowserActionSetIconFunction()264   virtual ~BrowserActionSetIconFunction() {}
265 };
266 
267 class BrowserActionSetTitleFunction : public ExtensionActionSetTitleFunction {
268  public:
269   DECLARE_EXTENSION_FUNCTION("browserAction.setTitle", BROWSERACTION_SETTITLE)
270 
271  protected:
~BrowserActionSetTitleFunction()272   virtual ~BrowserActionSetTitleFunction() {}
273 };
274 
275 class BrowserActionSetPopupFunction : public ExtensionActionSetPopupFunction {
276  public:
277   DECLARE_EXTENSION_FUNCTION("browserAction.setPopup", BROWSERACTION_SETPOPUP)
278 
279  protected:
~BrowserActionSetPopupFunction()280   virtual ~BrowserActionSetPopupFunction() {}
281 };
282 
283 class BrowserActionGetTitleFunction : public ExtensionActionGetTitleFunction {
284  public:
285   DECLARE_EXTENSION_FUNCTION("browserAction.getTitle", BROWSERACTION_GETTITLE)
286 
287  protected:
~BrowserActionGetTitleFunction()288   virtual ~BrowserActionGetTitleFunction() {}
289 };
290 
291 class BrowserActionGetPopupFunction : public ExtensionActionGetPopupFunction {
292  public:
293   DECLARE_EXTENSION_FUNCTION("browserAction.getPopup", BROWSERACTION_GETPOPUP)
294 
295  protected:
~BrowserActionGetPopupFunction()296   virtual ~BrowserActionGetPopupFunction() {}
297 };
298 
299 class BrowserActionSetBadgeTextFunction
300     : public ExtensionActionSetBadgeTextFunction {
301  public:
302   DECLARE_EXTENSION_FUNCTION("browserAction.setBadgeText",
303                              BROWSERACTION_SETBADGETEXT)
304 
305  protected:
~BrowserActionSetBadgeTextFunction()306   virtual ~BrowserActionSetBadgeTextFunction() {}
307 };
308 
309 class BrowserActionSetBadgeBackgroundColorFunction
310     : public ExtensionActionSetBadgeBackgroundColorFunction {
311  public:
312   DECLARE_EXTENSION_FUNCTION("browserAction.setBadgeBackgroundColor",
313                              BROWSERACTION_SETBADGEBACKGROUNDCOLOR)
314 
315  protected:
~BrowserActionSetBadgeBackgroundColorFunction()316   virtual ~BrowserActionSetBadgeBackgroundColorFunction() {}
317 };
318 
319 class BrowserActionGetBadgeTextFunction
320     : public ExtensionActionGetBadgeTextFunction {
321  public:
322   DECLARE_EXTENSION_FUNCTION("browserAction.getBadgeText",
323                              BROWSERACTION_GETBADGETEXT)
324 
325  protected:
~BrowserActionGetBadgeTextFunction()326   virtual ~BrowserActionGetBadgeTextFunction() {}
327 };
328 
329 class BrowserActionGetBadgeBackgroundColorFunction
330     : public ExtensionActionGetBadgeBackgroundColorFunction {
331  public:
332   DECLARE_EXTENSION_FUNCTION("browserAction.getBadgeBackgroundColor",
333                              BROWSERACTION_GETBADGEBACKGROUNDCOLOR)
334 
335  protected:
~BrowserActionGetBadgeBackgroundColorFunction()336   virtual ~BrowserActionGetBadgeBackgroundColorFunction() {}
337 };
338 
339 class BrowserActionEnableFunction : public ExtensionActionShowFunction {
340  public:
341   DECLARE_EXTENSION_FUNCTION("browserAction.enable", BROWSERACTION_ENABLE)
342 
343  protected:
~BrowserActionEnableFunction()344   virtual ~BrowserActionEnableFunction() {}
345 };
346 
347 class BrowserActionDisableFunction : public ExtensionActionHideFunction {
348  public:
349   DECLARE_EXTENSION_FUNCTION("browserAction.disable", BROWSERACTION_DISABLE)
350 
351  protected:
~BrowserActionDisableFunction()352   virtual ~BrowserActionDisableFunction() {}
353 };
354 
355 class BrowserActionOpenPopupFunction : public ChromeAsyncExtensionFunction,
356                                        public content::NotificationObserver {
357  public:
358   DECLARE_EXTENSION_FUNCTION("browserAction.openPopup",
359                              BROWSERACTION_OPEN_POPUP)
360   BrowserActionOpenPopupFunction();
361 
362  private:
~BrowserActionOpenPopupFunction()363   virtual ~BrowserActionOpenPopupFunction() {}
364 
365   // ExtensionFunction:
366   virtual bool RunAsync() OVERRIDE;
367 
368   virtual void Observe(int type,
369                        const content::NotificationSource& source,
370                        const content::NotificationDetails& details) OVERRIDE;
371   void OpenPopupTimedOut();
372 
373   content::NotificationRegistrar registrar_;
374   bool response_sent_;
375 
376   DISALLOW_COPY_AND_ASSIGN(BrowserActionOpenPopupFunction);
377 };
378 
379 }  // namespace extensions
380 
381 //
382 // pageAction.* aliases for supported pageAction APIs.
383 //
384 
385 class PageActionShowFunction : public extensions::ExtensionActionShowFunction {
386  public:
387   DECLARE_EXTENSION_FUNCTION("pageAction.show", PAGEACTION_SHOW)
388 
389  protected:
~PageActionShowFunction()390   virtual ~PageActionShowFunction() {}
391 };
392 
393 class PageActionHideFunction : public extensions::ExtensionActionHideFunction {
394  public:
395   DECLARE_EXTENSION_FUNCTION("pageAction.hide", PAGEACTION_HIDE)
396 
397  protected:
~PageActionHideFunction()398   virtual ~PageActionHideFunction() {}
399 };
400 
401 class PageActionSetIconFunction
402     : public extensions::ExtensionActionSetIconFunction {
403  public:
404   DECLARE_EXTENSION_FUNCTION("pageAction.setIcon", PAGEACTION_SETICON)
405 
406  protected:
~PageActionSetIconFunction()407   virtual ~PageActionSetIconFunction() {}
408 };
409 
410 class PageActionSetTitleFunction
411     : public extensions::ExtensionActionSetTitleFunction {
412  public:
413   DECLARE_EXTENSION_FUNCTION("pageAction.setTitle", PAGEACTION_SETTITLE)
414 
415  protected:
~PageActionSetTitleFunction()416   virtual ~PageActionSetTitleFunction() {}
417 };
418 
419 class PageActionSetPopupFunction
420     : public extensions::ExtensionActionSetPopupFunction {
421  public:
422   DECLARE_EXTENSION_FUNCTION("pageAction.setPopup", PAGEACTION_SETPOPUP)
423 
424  protected:
~PageActionSetPopupFunction()425   virtual ~PageActionSetPopupFunction() {}
426 };
427 
428 class PageActionGetTitleFunction
429     : public extensions::ExtensionActionGetTitleFunction {
430  public:
431   DECLARE_EXTENSION_FUNCTION("pageAction.getTitle", PAGEACTION_GETTITLE)
432 
433  protected:
~PageActionGetTitleFunction()434   virtual ~PageActionGetTitleFunction() {}
435 };
436 
437 class PageActionGetPopupFunction
438     : public extensions::ExtensionActionGetPopupFunction {
439  public:
440   DECLARE_EXTENSION_FUNCTION("pageAction.getPopup", PAGEACTION_GETPOPUP)
441 
442  protected:
~PageActionGetPopupFunction()443   virtual ~PageActionGetPopupFunction() {}
444 };
445 
446 #endif  // CHROME_BROWSER_EXTENSIONS_API_EXTENSION_ACTION_EXTENSION_ACTION_API_H_
447