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