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/memory/weak_ptr.h"
     11 #include "base/scoped_observer.h"
     12 #include "chrome/browser/extensions/chrome_extension_function.h"
     13 #include "chrome/browser/extensions/extension_action.h"
     14 #include "content/public/browser/notification_observer.h"
     15 #include "content/public/browser/notification_registrar.h"
     16 #include "extensions/browser/browser_context_keyed_api_factory.h"
     17 #include "extensions/browser/extension_registry_observer.h"
     18 
     19 namespace base {
     20 class DictionaryValue;
     21 }
     22 
     23 namespace content {
     24 class BrowserContext;
     25 class WebContents;
     26 }
     27 
     28 namespace extensions {
     29 class ExtensionPrefs;
     30 class ExtensionRegistry;
     31 class TabHelper;
     32 
     33 class ExtensionActionAPI : public BrowserContextKeyedAPI {
     34  public:
     35   explicit ExtensionActionAPI(content::BrowserContext* context);
     36   virtual ~ExtensionActionAPI();
     37 
     38   // Convenience method to get the instance for a profile.
     39   static ExtensionActionAPI* Get(content::BrowserContext* context);
     40 
     41   static bool GetBrowserActionVisibility(const ExtensionPrefs* prefs,
     42                                          const std::string& extension_id);
     43   static void SetBrowserActionVisibility(ExtensionPrefs* prefs,
     44                                          const std::string& extension_id,
     45                                          bool visible);
     46 
     47   // Fires the onClicked event for page_action.
     48   static void PageActionExecuted(content::BrowserContext* context,
     49                                  const ExtensionAction& page_action,
     50                                  int tab_id,
     51                                  const std::string& url,
     52                                  int button);
     53 
     54   // Fires the onClicked event for browser_action.
     55   static void BrowserActionExecuted(content::BrowserContext* context,
     56                                     const ExtensionAction& browser_action,
     57                                     content::WebContents* web_contents);
     58 
     59   // BrowserContextKeyedAPI implementation.
     60   static BrowserContextKeyedAPIFactory<ExtensionActionAPI>*
     61       GetFactoryInstance();
     62 
     63  private:
     64   friend class BrowserContextKeyedAPIFactory<ExtensionActionAPI>;
     65 
     66   // The DispatchEvent methods forward events to the |profile|'s event router.
     67   static void DispatchEventToExtension(content::BrowserContext* context,
     68                                        const std::string& extension_id,
     69                                        const std::string& event_name,
     70                                        scoped_ptr<base::ListValue> event_args);
     71 
     72   // Called to dispatch a deprecated style page action click event that was
     73   // registered like:
     74   //   chrome.pageActions["name"].addListener(function(actionId, info){})
     75   static void DispatchOldPageActionEvent(content::BrowserContext* context,
     76                                          const std::string& extension_id,
     77                                          const std::string& page_action_id,
     78                                          int tab_id,
     79                                          const std::string& url,
     80                                          int button);
     81 
     82   // Called when either a browser or page action is executed. Figures out which
     83   // event to send based on what the extension wants.
     84   static void ExtensionActionExecuted(content::BrowserContext* context,
     85                                       const ExtensionAction& extension_action,
     86                                       content::WebContents* web_contents);
     87 
     88   // BrowserContextKeyedAPI implementation.
     89   static const char* service_name() { return "ExtensionActionAPI"; }
     90 
     91   DISALLOW_COPY_AND_ASSIGN(ExtensionActionAPI);
     92 };
     93 
     94 // This class manages reading and writing browser action values from storage.
     95 class ExtensionActionStorageManager
     96     : public content::NotificationObserver,
     97       public ExtensionRegistryObserver,
     98       public base::SupportsWeakPtr<ExtensionActionStorageManager> {
     99  public:
    100   explicit ExtensionActionStorageManager(Profile* profile);
    101   virtual ~ExtensionActionStorageManager();
    102 
    103  private:
    104   // NotificationObserver:
    105   virtual void Observe(int type,
    106                        const content::NotificationSource& source,
    107                        const content::NotificationDetails& details) OVERRIDE;
    108 
    109   // ExtensionRegistryObserver:
    110   virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
    111                                  const Extension* extension) OVERRIDE;
    112 
    113   // Reads/Writes the ExtensionAction's default values to/from storage.
    114   void WriteToStorage(ExtensionAction* extension_action);
    115   void ReadFromStorage(
    116       const std::string& extension_id, scoped_ptr<base::Value> value);
    117 
    118   Profile* profile_;
    119   content::NotificationRegistrar registrar_;
    120 
    121   // Listen to extension loaded notification.
    122   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
    123       extension_registry_observer_;
    124 };
    125 
    126 // Implementation of the browserAction and pageAction APIs.
    127 //
    128 // Divergent behaviour between the two is minimal (pageAction has required
    129 // tabIds while browserAction's are optional, they have different internal
    130 // browser notification requirements, and not all functions are defined for all
    131 // APIs).
    132 class ExtensionActionFunction : public ChromeSyncExtensionFunction {
    133  public:
    134   static bool ParseCSSColorString(const std::string& color_string,
    135                                   SkColor* result);
    136 
    137  protected:
    138   ExtensionActionFunction();
    139   virtual ~ExtensionActionFunction();
    140   virtual bool RunSync() OVERRIDE;
    141   virtual bool RunExtensionAction() = 0;
    142 
    143   bool ExtractDataFromArguments();
    144   void NotifyChange();
    145   void NotifyBrowserActionChange();
    146   void NotifyLocationBarChange();
    147   void NotifySystemIndicatorChange();
    148   bool SetVisible(bool visible);
    149 
    150   // Extension-related information for |tab_id_|.
    151   // CHECK-fails if there is no tab.
    152   extensions::TabHelper& tab_helper() const;
    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 // Base class for deprecated page actions APIs
    447 class PageActionsFunction : public ChromeSyncExtensionFunction {
    448  protected:
    449   PageActionsFunction();
    450   virtual ~PageActionsFunction();
    451   bool SetPageActionEnabled(bool enable);
    452 };
    453 
    454 // Implement chrome.pageActions.enableForTab().
    455 class EnablePageActionsFunction : public PageActionsFunction {
    456  public:
    457   DECLARE_EXTENSION_FUNCTION("pageActions.enableForTab",
    458                              PAGEACTIONS_ENABLEFORTAB)
    459 
    460  protected:
    461   virtual ~EnablePageActionsFunction() {}
    462 
    463   // ExtensionFunction:
    464   virtual bool RunSync() OVERRIDE;
    465 };
    466 
    467 // Implement chrome.pageActions.disableForTab().
    468 class DisablePageActionsFunction : public PageActionsFunction {
    469  public:
    470   DECLARE_EXTENSION_FUNCTION("pageActions.disableForTab",
    471                              PAGEACTIONS_DISABLEFORTAB)
    472 
    473  protected:
    474   virtual ~DisablePageActionsFunction() {}
    475 
    476   // ExtensionFunction:
    477   virtual bool RunSync() OVERRIDE;
    478 };
    479 
    480 #endif  // CHROME_BROWSER_EXTENSIONS_API_EXTENSION_ACTION_EXTENSION_ACTION_API_H_
    481