Home | History | Annotate | Download | only in extension_action
      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;
    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:
    179   virtual ~ExtensionActionShowFunction() {}
    180   virtual bool RunExtensionAction() OVERRIDE;
    181 };
    182 
    183 // hide
    184 class ExtensionActionHideFunction : public ExtensionActionFunction {
    185  protected:
    186   virtual ~ExtensionActionHideFunction() {}
    187   virtual bool RunExtensionAction() OVERRIDE;
    188 };
    189 
    190 // setIcon
    191 class ExtensionActionSetIconFunction : public ExtensionActionFunction {
    192  protected:
    193   virtual ~ExtensionActionSetIconFunction() {}
    194   virtual bool RunExtensionAction() OVERRIDE;
    195 };
    196 
    197 // setTitle
    198 class ExtensionActionSetTitleFunction : public ExtensionActionFunction {
    199  protected:
    200   virtual ~ExtensionActionSetTitleFunction() {}
    201   virtual bool RunExtensionAction() OVERRIDE;
    202 };
    203 
    204 // setPopup
    205 class ExtensionActionSetPopupFunction : public ExtensionActionFunction {
    206  protected:
    207   virtual ~ExtensionActionSetPopupFunction() {}
    208   virtual bool RunExtensionAction() OVERRIDE;
    209 };
    210 
    211 // setBadgeText
    212 class ExtensionActionSetBadgeTextFunction : public ExtensionActionFunction {
    213  protected:
    214   virtual ~ExtensionActionSetBadgeTextFunction() {}
    215   virtual bool RunExtensionAction() OVERRIDE;
    216 };
    217 
    218 // setBadgeBackgroundColor
    219 class ExtensionActionSetBadgeBackgroundColorFunction
    220     : public ExtensionActionFunction {
    221  protected:
    222   virtual ~ExtensionActionSetBadgeBackgroundColorFunction() {}
    223   virtual bool RunExtensionAction() OVERRIDE;
    224 };
    225 
    226 // getTitle
    227 class ExtensionActionGetTitleFunction : public ExtensionActionFunction {
    228  protected:
    229   virtual ~ExtensionActionGetTitleFunction() {}
    230   virtual bool RunExtensionAction() OVERRIDE;
    231 };
    232 
    233 // getPopup
    234 class ExtensionActionGetPopupFunction : public ExtensionActionFunction {
    235  protected:
    236   virtual ~ExtensionActionGetPopupFunction() {}
    237   virtual bool RunExtensionAction() OVERRIDE;
    238 };
    239 
    240 // getBadgeText
    241 class ExtensionActionGetBadgeTextFunction : public ExtensionActionFunction {
    242  protected:
    243   virtual ~ExtensionActionGetBadgeTextFunction() {}
    244   virtual bool RunExtensionAction() OVERRIDE;
    245 };
    246 
    247 // getBadgeBackgroundColor
    248 class ExtensionActionGetBadgeBackgroundColorFunction
    249     : public ExtensionActionFunction {
    250  protected:
    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:
    264   virtual ~BrowserActionSetIconFunction() {}
    265 };
    266 
    267 class BrowserActionSetTitleFunction : public ExtensionActionSetTitleFunction {
    268  public:
    269   DECLARE_EXTENSION_FUNCTION("browserAction.setTitle", BROWSERACTION_SETTITLE)
    270 
    271  protected:
    272   virtual ~BrowserActionSetTitleFunction() {}
    273 };
    274 
    275 class BrowserActionSetPopupFunction : public ExtensionActionSetPopupFunction {
    276  public:
    277   DECLARE_EXTENSION_FUNCTION("browserAction.setPopup", BROWSERACTION_SETPOPUP)
    278 
    279  protected:
    280   virtual ~BrowserActionSetPopupFunction() {}
    281 };
    282 
    283 class BrowserActionGetTitleFunction : public ExtensionActionGetTitleFunction {
    284  public:
    285   DECLARE_EXTENSION_FUNCTION("browserAction.getTitle", BROWSERACTION_GETTITLE)
    286 
    287  protected:
    288   virtual ~BrowserActionGetTitleFunction() {}
    289 };
    290 
    291 class BrowserActionGetPopupFunction : public ExtensionActionGetPopupFunction {
    292  public:
    293   DECLARE_EXTENSION_FUNCTION("browserAction.getPopup", BROWSERACTION_GETPOPUP)
    294 
    295  protected:
    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:
    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:
    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:
    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:
    336   virtual ~BrowserActionGetBadgeBackgroundColorFunction() {}
    337 };
    338 
    339 class BrowserActionEnableFunction : public ExtensionActionShowFunction {
    340  public:
    341   DECLARE_EXTENSION_FUNCTION("browserAction.enable", BROWSERACTION_ENABLE)
    342 
    343  protected:
    344   virtual ~BrowserActionEnableFunction() {}
    345 };
    346 
    347 class BrowserActionDisableFunction : public ExtensionActionHideFunction {
    348  public:
    349   DECLARE_EXTENSION_FUNCTION("browserAction.disable", BROWSERACTION_DISABLE)
    350 
    351  protected:
    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:
    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:
    390   virtual ~PageActionShowFunction() {}
    391 };
    392 
    393 class PageActionHideFunction : public extensions::ExtensionActionHideFunction {
    394  public:
    395   DECLARE_EXTENSION_FUNCTION("pageAction.hide", PAGEACTION_HIDE)
    396 
    397  protected:
    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:
    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:
    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:
    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:
    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:
    443   virtual ~PageActionGetPopupFunction() {}
    444 };
    445 
    446 #endif  // CHROME_BROWSER_EXTENSIONS_API_EXTENSION_ACTION_EXTENSION_ACTION_API_H_
    447