OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 5 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "chrome/browser/extensions/active_script_controller.h" |
12 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_
api_constants.h" | 13 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_
api_constants.h" |
13 #include "chrome/browser/extensions/extension_action.h" | 14 #include "chrome/browser/extensions/extension_action.h" |
14 #include "chrome/browser/extensions/extension_action_manager.h" | 15 #include "chrome/browser/extensions/extension_action_manager.h" |
15 #include "chrome/browser/extensions/extension_service.h" | |
16 #include "chrome/browser/extensions/extension_tab_util.h" | 16 #include "chrome/browser/extensions/extension_tab_util.h" |
17 #include "chrome/browser/extensions/extension_toolbar_model.h" | 17 #include "chrome/browser/extensions/extension_toolbar_model.h" |
18 #include "chrome/browser/extensions/location_bar_controller.h" | |
19 #include "chrome/browser/extensions/tab_helper.h" | 18 #include "chrome/browser/extensions/tab_helper.h" |
20 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
21 #include "chrome/browser/sessions/session_tab_helper.h" | 20 #include "chrome/browser/sessions/session_tab_helper.h" |
| 21 #include "chrome/browser/ui/browser.h" |
| 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
22 #include "chrome/common/extensions/api/extension_action/action_info.h" | 23 #include "chrome/common/extensions/api/extension_action/action_info.h" |
23 #include "chrome/common/render_messages.h" | 24 #include "chrome/common/render_messages.h" |
24 #include "content/public/browser/navigation_entry.h" | 25 #include "content/public/browser/navigation_entry.h" |
25 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
26 #include "extensions/browser/event_router.h" | 27 #include "extensions/browser/event_router.h" |
27 #include "extensions/browser/extension_function_registry.h" | 28 #include "extensions/browser/extension_function_registry.h" |
28 #include "extensions/browser/extension_host.h" | 29 #include "extensions/browser/extension_host.h" |
29 #include "extensions/browser/extension_registry.h" | 30 #include "extensions/browser/extension_registry.h" |
30 #include "extensions/browser/extension_system.h" | 31 #include "extensions/browser/extension_system.h" |
31 #include "extensions/browser/image_util.h" | 32 #include "extensions/browser/image_util.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 | 304 |
304 prefs->UpdateExtensionPref(extension_id, | 305 prefs->UpdateExtensionPref(extension_id, |
305 kBrowserActionVisible, | 306 kBrowserActionVisible, |
306 new base::FundamentalValue(visible)); | 307 new base::FundamentalValue(visible)); |
307 content::NotificationService::current()->Notify( | 308 content::NotificationService::current()->Notify( |
308 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, | 309 NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED, |
309 content::Source<ExtensionPrefs>(prefs), | 310 content::Source<ExtensionPrefs>(prefs), |
310 content::Details<const std::string>(&extension_id)); | 311 content::Details<const std::string>(&extension_id)); |
311 } | 312 } |
312 | 313 |
313 // static | 314 void ExtensionActionAPI::AddObserver(Observer* observer) { |
314 void ExtensionActionAPI::BrowserActionExecuted( | 315 observers_.AddObserver(observer); |
315 content::BrowserContext* context, | |
316 const ExtensionAction& browser_action, | |
317 WebContents* web_contents) { | |
318 ExtensionActionExecuted(context, browser_action, web_contents); | |
319 } | 316 } |
320 | 317 |
321 // static | 318 void ExtensionActionAPI::RemoveObserver(Observer* observer) { |
322 void ExtensionActionAPI::PageActionExecuted(content::BrowserContext* context, | 319 observers_.RemoveObserver(observer); |
323 const ExtensionAction& page_action, | |
324 int tab_id, | |
325 const std::string& url, | |
326 int button) { | |
327 WebContents* web_contents = NULL; | |
328 if (!ExtensionTabUtil::GetTabById( | |
329 tab_id, | |
330 Profile::FromBrowserContext(context), | |
331 context->IsOffTheRecord(), | |
332 NULL, | |
333 NULL, | |
334 &web_contents, | |
335 NULL)) { | |
336 return; | |
337 } | |
338 ExtensionActionExecuted(context, page_action, web_contents); | |
339 } | 320 } |
340 | 321 |
341 // static | 322 ExtensionAction::ShowAction ExtensionActionAPI::ExecuteExtensionAction( |
| 323 const Extension* extension, |
| 324 Browser* browser, |
| 325 bool grant_active_tab_permissions) { |
| 326 content::WebContents* web_contents = |
| 327 browser->tab_strip_model()->GetActiveWebContents(); |
| 328 if (!web_contents) |
| 329 return ExtensionAction::ACTION_NONE; |
| 330 |
| 331 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 332 |
| 333 ExtensionActionManager* action_manager = |
| 334 ExtensionActionManager::Get(static_cast<Profile*>(browser_context_)); |
| 335 // TODO(devlin): Make a ExtensionActionManager::GetExtensionAction method. |
| 336 ExtensionAction* extension_action = |
| 337 action_manager->GetBrowserAction(*extension); |
| 338 if (!extension_action) |
| 339 extension_action = action_manager->GetPageAction(*extension); |
| 340 |
| 341 // Anything that calls this should have a page or browser action. |
| 342 DCHECK(extension_action); |
| 343 if (!extension_action->GetIsVisible(tab_id)) |
| 344 return ExtensionAction::ACTION_NONE; |
| 345 |
| 346 // Grant active tab if appropriate. |
| 347 if (grant_active_tab_permissions) { |
| 348 TabHelper::FromWebContents(web_contents)->active_tab_permission_granter()-> |
| 349 GrantIfRequested(extension); |
| 350 } |
| 351 |
| 352 // Notify ActiveScriptController that the action was clicked, if appropriate. |
| 353 ActiveScriptController* active_script_controller = |
| 354 ActiveScriptController::GetForWebContents(web_contents); |
| 355 if (active_script_controller && |
| 356 active_script_controller->GetActionForExtension(extension)) { |
| 357 active_script_controller->OnClicked(extension); |
| 358 } |
| 359 |
| 360 if (extension_action->HasPopup(tab_id)) |
| 361 return ExtensionAction::ACTION_SHOW_POPUP; |
| 362 |
| 363 ExtensionActionExecuted(*extension_action, web_contents); |
| 364 return ExtensionAction::ACTION_NONE; |
| 365 } |
| 366 |
| 367 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, |
| 368 content::WebContents* web_contents, |
| 369 content::BrowserContext* context) { |
| 370 FOR_EACH_OBSERVER( |
| 371 Observer, |
| 372 observers_, |
| 373 OnExtensionActionUpdated(extension_action, web_contents, context)); |
| 374 } |
| 375 |
| 376 void ExtensionActionAPI::ClearAllValuesForTab( |
| 377 content::WebContents* web_contents) { |
| 378 DCHECK(web_contents); |
| 379 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 380 content::BrowserContext* browser_context = web_contents->GetBrowserContext(); |
| 381 const ExtensionSet& enabled_extensions = |
| 382 ExtensionRegistry::Get(browser_context_)->enabled_extensions(); |
| 383 ExtensionActionManager* action_manager = |
| 384 ExtensionActionManager::Get(browser_context_); |
| 385 |
| 386 for (ExtensionSet::const_iterator iter = enabled_extensions.begin(); |
| 387 iter != enabled_extensions.end(); ++iter) { |
| 388 ExtensionAction* extension_action = |
| 389 action_manager->GetBrowserAction(*iter->get()); |
| 390 if (!extension_action) |
| 391 extension_action = action_manager->GetPageAction(*iter->get()); |
| 392 if (extension_action) { |
| 393 extension_action->ClearAllValuesForTab(tab_id); |
| 394 NotifyChange(extension_action, web_contents, browser_context); |
| 395 } |
| 396 } |
| 397 } |
| 398 |
342 void ExtensionActionAPI::DispatchEventToExtension( | 399 void ExtensionActionAPI::DispatchEventToExtension( |
343 content::BrowserContext* context, | 400 content::BrowserContext* context, |
344 const std::string& extension_id, | 401 const std::string& extension_id, |
345 const std::string& event_name, | 402 const std::string& event_name, |
346 scoped_ptr<base::ListValue> event_args) { | 403 scoped_ptr<base::ListValue> event_args) { |
347 if (!EventRouter::Get(context)) | 404 if (!EventRouter::Get(context)) |
348 return; | 405 return; |
349 | 406 |
350 scoped_ptr<Event> event(new Event(event_name, event_args.Pass())); | 407 scoped_ptr<Event> event(new Event(event_name, event_args.Pass())); |
351 event->restrict_to_browser_context = context; | 408 event->restrict_to_browser_context = context; |
352 event->user_gesture = EventRouter::USER_GESTURE_ENABLED; | 409 event->user_gesture = EventRouter::USER_GESTURE_ENABLED; |
353 EventRouter::Get(context) | 410 EventRouter::Get(context) |
354 ->DispatchEventToExtension(extension_id, event.Pass()); | 411 ->DispatchEventToExtension(extension_id, event.Pass()); |
355 } | 412 } |
356 | 413 |
357 // static | |
358 void ExtensionActionAPI::ExtensionActionExecuted( | 414 void ExtensionActionAPI::ExtensionActionExecuted( |
359 content::BrowserContext* context, | |
360 const ExtensionAction& extension_action, | 415 const ExtensionAction& extension_action, |
361 WebContents* web_contents) { | 416 WebContents* web_contents) { |
362 const char* event_name = NULL; | 417 const char* event_name = NULL; |
363 switch (extension_action.action_type()) { | 418 switch (extension_action.action_type()) { |
364 case ActionInfo::TYPE_BROWSER: | 419 case ActionInfo::TYPE_BROWSER: |
365 event_name = "browserAction.onClicked"; | 420 event_name = "browserAction.onClicked"; |
366 break; | 421 break; |
367 case ActionInfo::TYPE_PAGE: | 422 case ActionInfo::TYPE_PAGE: |
368 event_name = "pageAction.onClicked"; | 423 event_name = "pageAction.onClicked"; |
369 break; | 424 break; |
370 case ActionInfo::TYPE_SYSTEM_INDICATOR: | 425 case ActionInfo::TYPE_SYSTEM_INDICATOR: |
371 // The System Indicator handles its own clicks. | 426 // The System Indicator handles its own clicks. |
372 break; | 427 break; |
373 } | 428 } |
374 | 429 |
375 if (event_name) { | 430 if (event_name) { |
376 scoped_ptr<base::ListValue> args(new base::ListValue()); | 431 scoped_ptr<base::ListValue> args(new base::ListValue()); |
377 base::DictionaryValue* tab_value = | 432 base::DictionaryValue* tab_value = |
378 ExtensionTabUtil::CreateTabValue(web_contents); | 433 ExtensionTabUtil::CreateTabValue(web_contents); |
379 args->Append(tab_value); | 434 args->Append(tab_value); |
380 | 435 |
381 DispatchEventToExtension( | 436 DispatchEventToExtension( |
382 context, extension_action.extension_id(), event_name, args.Pass()); | 437 web_contents->GetBrowserContext(), |
| 438 extension_action.extension_id(), |
| 439 event_name, |
| 440 args.Pass()); |
383 } | 441 } |
384 } | 442 } |
385 | 443 |
386 void ExtensionActionAPI::AddObserver(Observer* observer) { | |
387 observers_.AddObserver(observer); | |
388 } | |
389 | |
390 void ExtensionActionAPI::RemoveObserver(Observer* observer) { | |
391 observers_.RemoveObserver(observer); | |
392 } | |
393 | |
394 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, | |
395 content::WebContents* web_contents, | |
396 content::BrowserContext* context) { | |
397 FOR_EACH_OBSERVER( | |
398 Observer, | |
399 observers_, | |
400 OnExtensionActionUpdated(extension_action, web_contents, context)); | |
401 } | |
402 | |
403 void ExtensionActionAPI::ClearAllValuesForTab( | |
404 content::WebContents* web_contents) { | |
405 DCHECK(web_contents); | |
406 int tab_id = SessionTabHelper::IdForTab(web_contents); | |
407 content::BrowserContext* browser_context = web_contents->GetBrowserContext(); | |
408 const ExtensionSet& enabled_extensions = | |
409 ExtensionRegistry::Get(browser_context_)->enabled_extensions(); | |
410 ExtensionActionManager* action_manager = | |
411 ExtensionActionManager::Get(browser_context_); | |
412 | |
413 for (ExtensionSet::const_iterator iter = enabled_extensions.begin(); | |
414 iter != enabled_extensions.end(); ++iter) { | |
415 ExtensionAction* extension_action = | |
416 action_manager->GetBrowserAction(*iter->get()); | |
417 if (!extension_action) | |
418 extension_action = action_manager->GetPageAction(*iter->get()); | |
419 if (extension_action) { | |
420 extension_action->ClearAllValuesForTab(tab_id); | |
421 NotifyChange(extension_action, web_contents, browser_context); | |
422 } | |
423 } | |
424 } | |
425 | |
426 void ExtensionActionAPI::Shutdown() { | 444 void ExtensionActionAPI::Shutdown() { |
427 FOR_EACH_OBSERVER(Observer, observers_, OnExtensionActionAPIShuttingDown()); | 445 FOR_EACH_OBSERVER(Observer, observers_, OnExtensionActionAPIShuttingDown()); |
428 } | 446 } |
429 | 447 |
430 // | 448 // |
431 // ExtensionActionStorageManager | 449 // ExtensionActionStorageManager |
432 // | 450 // |
433 | 451 |
434 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile) | 452 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile) |
435 : profile_(profile), | 453 : profile_(profile), |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 | 502 |
485 scoped_ptr<base::DictionaryValue> defaults = | 503 scoped_ptr<base::DictionaryValue> defaults = |
486 DefaultsToValue(extension_action); | 504 DefaultsToValue(extension_action); |
487 storage->SetExtensionValue(extension_action->extension_id(), | 505 storage->SetExtensionValue(extension_action->extension_id(), |
488 kBrowserActionStorageKey, | 506 kBrowserActionStorageKey, |
489 defaults.PassAs<base::Value>()); | 507 defaults.PassAs<base::Value>()); |
490 } | 508 } |
491 | 509 |
492 void ExtensionActionStorageManager::ReadFromStorage( | 510 void ExtensionActionStorageManager::ReadFromStorage( |
493 const std::string& extension_id, scoped_ptr<base::Value> value) { | 511 const std::string& extension_id, scoped_ptr<base::Value> value) { |
494 const Extension* extension = | 512 const Extension* extension = ExtensionRegistry::Get(profile_)-> |
495 ExtensionSystem::Get(profile_)->extension_service()-> | 513 enabled_extensions().GetByID(extension_id); |
496 extensions()->GetByID(extension_id); | |
497 if (!extension) | 514 if (!extension) |
498 return; | 515 return; |
499 | 516 |
500 ExtensionAction* browser_action = | 517 ExtensionAction* browser_action = |
501 ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension); | 518 ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension); |
502 if (!browser_action) { | 519 if (!browser_action) { |
503 // This can happen if the extension is updated between startup and when the | 520 // This can happen if the extension is updated between startup and when the |
504 // storage read comes back, and the update removes the browser action. | 521 // storage read comes back, and the update removes the browser action. |
505 // http://crbug.com/349371 | 522 // http://crbug.com/349371 |
506 return; | 523 return; |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || | 841 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || |
825 host->extension()->id() != extension_->id()) | 842 host->extension()->id() != extension_->id()) |
826 return; | 843 return; |
827 | 844 |
828 SendResponse(true); | 845 SendResponse(true); |
829 response_sent_ = true; | 846 response_sent_ = true; |
830 registrar_.RemoveAll(); | 847 registrar_.RemoveAll(); |
831 } | 848 } |
832 | 849 |
833 } // namespace extensions | 850 } // namespace extensions |
OLD | NEW |