Chromium Code Reviews| 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" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
| 30 #include "extensions/browser/event_router.h" | 30 #include "extensions/browser/event_router.h" |
| 31 #include "extensions/browser/extension_function_registry.h" | 31 #include "extensions/browser/extension_function_registry.h" |
| 32 #include "extensions/browser/extension_host.h" | 32 #include "extensions/browser/extension_host.h" |
| 33 #include "extensions/browser/extension_registry.h" | 33 #include "extensions/browser/extension_registry.h" |
| 34 #include "extensions/browser/extension_system.h" | 34 #include "extensions/browser/extension_system.h" |
| 35 #include "extensions/browser/image_util.h" | 35 #include "extensions/browser/image_util.h" |
| 36 #include "extensions/browser/notification_types.h" | 36 #include "extensions/browser/notification_types.h" |
| 37 #include "extensions/browser/state_store.h" | 37 #include "extensions/browser/state_store.h" |
| 38 #include "extensions/common/error_utils.h" | 38 #include "extensions/common/error_utils.h" |
| 39 #include "extensions/common/feature_switch.h" | |
| 39 #include "ui/gfx/codec/png_codec.h" | 40 #include "ui/gfx/codec/png_codec.h" |
| 40 #include "ui/gfx/image/image.h" | 41 #include "ui/gfx/image/image.h" |
| 41 #include "ui/gfx/image/image_skia.h" | 42 #include "ui/gfx/image/image_skia.h" |
| 42 | 43 |
| 43 using content::WebContents; | 44 using content::WebContents; |
| 44 | 45 |
| 45 namespace page_actions_keys = extension_page_actions_api_constants; | 46 namespace page_actions_keys = extension_page_actions_api_constants; |
| 46 | 47 |
| 47 namespace extensions { | 48 namespace extensions { |
| 48 | 49 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 73 // Whether the browser action is visible in the toolbar. | 74 // Whether the browser action is visible in the toolbar. |
| 74 const char kBrowserActionVisible[] = "browser_action_visible"; | 75 const char kBrowserActionVisible[] = "browser_action_visible"; |
| 75 | 76 |
| 76 // Errors. | 77 // Errors. |
| 77 const char kNoExtensionActionError[] = | 78 const char kNoExtensionActionError[] = |
| 78 "This extension has no action specified."; | 79 "This extension has no action specified."; |
| 79 const char kNoTabError[] = "No tab with id: *."; | 80 const char kNoTabError[] = "No tab with id: *."; |
| 80 const char kOpenPopupError[] = | 81 const char kOpenPopupError[] = |
| 81 "Failed to show popup either because there is an existing popup or another " | 82 "Failed to show popup either because there is an existing popup or another " |
| 82 "error occurred."; | 83 "error occurred."; |
| 83 const char kInternalError[] = "Internal error."; | |
| 84 | 84 |
| 85 struct IconRepresentationInfo { | 85 struct IconRepresentationInfo { |
| 86 // Size as a string that will be used to retrieve representation value from | 86 // Size as a string that will be used to retrieve representation value from |
| 87 // SetIcon function arguments. | 87 // SetIcon function arguments. |
| 88 const char* size_string; | 88 const char* size_string; |
| 89 // Scale factor for which the represantion should be used. | 89 // Scale factor for which the represantion should be used. |
| 90 ui::ScaleFactor scale; | 90 ui::ScaleFactor scale; |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 const IconRepresentationInfo kIconSizes[] = { | 93 const IconRepresentationInfo kIconSizes[] = { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 const Extension* extension, | 346 const Extension* extension, |
| 347 Browser* browser, | 347 Browser* browser, |
| 348 bool grant_active_tab_permissions) { | 348 bool grant_active_tab_permissions) { |
| 349 content::WebContents* web_contents = | 349 content::WebContents* web_contents = |
| 350 browser->tab_strip_model()->GetActiveWebContents(); | 350 browser->tab_strip_model()->GetActiveWebContents(); |
| 351 if (!web_contents) | 351 if (!web_contents) |
| 352 return ExtensionAction::ACTION_NONE; | 352 return ExtensionAction::ACTION_NONE; |
| 353 | 353 |
| 354 int tab_id = SessionTabHelper::IdForTab(web_contents); | 354 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 355 | 355 |
| 356 ExtensionActionManager* action_manager = | |
| 357 ExtensionActionManager::Get(static_cast<Profile*>(browser_context_)); | |
| 358 // TODO(devlin): Make a ExtensionActionManager::GetExtensionAction method. | |
| 359 ExtensionAction* extension_action = | 356 ExtensionAction* extension_action = |
| 360 action_manager->GetBrowserAction(*extension); | 357 ExtensionActionManager::Get(browser_context_)->GetExtensionAction( |
| 361 if (!extension_action) | 358 *extension); |
| 362 extension_action = action_manager->GetPageAction(*extension); | |
| 363 | 359 |
| 364 // Anything that calls this should have a page or browser action. | 360 // Anything that calls this should have a page or browser action. |
| 365 DCHECK(extension_action); | 361 DCHECK(extension_action); |
| 366 if (!extension_action->GetIsVisible(tab_id)) | 362 if (!extension_action->GetIsVisible(tab_id)) |
| 367 return ExtensionAction::ACTION_NONE; | 363 return ExtensionAction::ACTION_NONE; |
| 368 | 364 |
| 369 // Grant active tab if appropriate. | 365 // Grant active tab if appropriate. |
| 370 if (grant_active_tab_permissions) { | 366 if (grant_active_tab_permissions) { |
| 371 TabHelper::FromWebContents(web_contents)->active_tab_permission_granter()-> | 367 TabHelper::FromWebContents(web_contents)->active_tab_permission_granter()-> |
| 372 GrantIfRequested(extension); | 368 GrantIfRequested(extension); |
| 373 } | 369 } |
| 374 | 370 |
| 375 // Notify ActiveScriptController that the action was clicked, if appropriate. | 371 // Notify ActiveScriptController that the action was clicked, if appropriate. |
| 376 ActiveScriptController* active_script_controller = | 372 ActiveScriptController* active_script_controller = |
| 377 ActiveScriptController::GetForWebContents(web_contents); | 373 ActiveScriptController::GetForWebContents(web_contents); |
| 378 if (active_script_controller && | 374 if (active_script_controller && |
| 379 active_script_controller->GetActionForExtension(extension)) { | 375 active_script_controller->GetActionForExtension(extension)) { |
| 380 active_script_controller->OnClicked(extension); | 376 active_script_controller->OnClicked(extension); |
| 381 } | 377 } |
| 382 | 378 |
| 383 if (extension_action->HasPopup(tab_id)) | 379 if (extension_action->HasPopup(tab_id)) |
| 384 return ExtensionAction::ACTION_SHOW_POPUP; | 380 return ExtensionAction::ACTION_SHOW_POPUP; |
| 385 | 381 |
| 386 ExtensionActionExecuted(*extension_action, web_contents); | 382 ExtensionActionExecuted(*extension_action, web_contents); |
| 387 return ExtensionAction::ACTION_NONE; | 383 return ExtensionAction::ACTION_NONE; |
| 388 } | 384 } |
| 389 | 385 |
| 386 bool ExtensionActionAPI::ShowExtensionActionPopup( | |
| 387 const Extension* extension, | |
| 388 Browser* browser, | |
| 389 bool grant_active_tab_permissions) { | |
| 390 ExtensionAction* extension_action = | |
| 391 ExtensionActionManager::Get(browser_context_)->GetExtensionAction( | |
| 392 *extension); | |
| 393 if (!extension_action) | |
| 394 return false; | |
| 395 | |
| 396 if (extension_action->action_type() == ActionInfo::TYPE_PAGE && | |
| 397 !FeatureSwitch::extension_action_redesign()->IsEnabled()) { | |
| 398 // We show page actions in the location bar unless the new toolbar is | |
| 399 // enabled. | |
| 400 return browser->window()->GetLocationBar()->ShowPageActionPopup( | |
| 401 extension, grant_active_tab_permissions); | |
| 402 } else { | |
| 403 return ExtensionToolbarModel::Get(browser->profile())-> | |
| 404 ShowExtensionActionPopup( | |
| 405 extension, browser, grant_active_tab_permissions); | |
| 406 } | |
| 407 } | |
| 408 | |
| 390 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, | 409 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, |
| 391 content::WebContents* web_contents, | 410 content::WebContents* web_contents, |
| 392 content::BrowserContext* context) { | 411 content::BrowserContext* context) { |
| 393 FOR_EACH_OBSERVER( | 412 FOR_EACH_OBSERVER( |
| 394 Observer, | 413 Observer, |
| 395 observers_, | 414 observers_, |
| 396 OnExtensionActionUpdated(extension_action, web_contents, context)); | 415 OnExtensionActionUpdated(extension_action, web_contents, context)); |
| 397 | 416 |
| 398 if (extension_action->action_type() == ActionInfo::TYPE_PAGE) | 417 if (extension_action->action_type() == ActionInfo::TYPE_PAGE) |
| 399 NotifyPageActionsChanged(web_contents); | 418 NotifyPageActionsChanged(web_contents); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 new base::FundamentalValue(static_cast<int>(SkColorGetA(color)))); | 845 new base::FundamentalValue(static_cast<int>(SkColorGetA(color)))); |
| 827 SetResult(list); | 846 SetResult(list); |
| 828 return true; | 847 return true; |
| 829 } | 848 } |
| 830 | 849 |
| 831 BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() | 850 BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() |
| 832 : response_sent_(false) { | 851 : response_sent_(false) { |
| 833 } | 852 } |
| 834 | 853 |
| 835 bool BrowserActionOpenPopupFunction::RunAsync() { | 854 bool BrowserActionOpenPopupFunction::RunAsync() { |
| 836 ExtensionToolbarModel* model = ExtensionToolbarModel::Get(GetProfile()); | 855 // We only allow the a popup in the active window. |
|
Finnur
2014/08/27 11:53:02
s/the a/the/
Devlin
2014/08/27 15:43:22
Done.
| |
| 837 if (!model) { | 856 Browser* browser = chrome::FindLastActiveWithProfile( |
|
Finnur
2014/08/27 11:53:02
Hmmm... is there no way around looking up the brow
Devlin
2014/08/27 15:43:22
Sadly, I don't think so, no :( I think there are
| |
| 838 error_ = kInternalError; | 857 GetProfile(), chrome::GetActiveDesktop()); |
| 839 return false; | |
| 840 } | |
| 841 | 858 |
| 842 if (!model->ShowBrowserActionPopup(extension_.get())) { | 859 // If there's no active browser, or the Toolbar isn't visible, abort. |
| 860 // Otherwise, try to open a popup in the active browser. | |
| 861 // TODO(justinlin): Remove toolbar check when http://crbug.com/308645 is | |
| 862 // fixed. | |
| 863 if (!browser || | |
| 864 !browser->window()->IsActive() || | |
| 865 !browser->window()->IsToolbarVisible() || | |
| 866 !ExtensionActionAPI::Get(GetProfile())->ShowExtensionActionPopup( | |
| 867 extension_.get(), browser, false)) { | |
| 843 error_ = kOpenPopupError; | 868 error_ = kOpenPopupError; |
| 844 return false; | 869 return false; |
| 845 } | 870 } |
| 846 | 871 |
| 847 registrar_.Add(this, | 872 registrar_.Add(this, |
| 848 NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 873 NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
| 849 content::Source<Profile>(GetProfile())); | 874 content::Source<Profile>(GetProfile())); |
| 850 | 875 |
| 851 // Set a timeout for waiting for the notification that the popup is loaded. | 876 // Set a timeout for waiting for the notification that the popup is loaded. |
| 852 // Waiting is required so that the popup view can be retrieved by the custom | 877 // Waiting is required so that the popup view can be retrieved by the custom |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 881 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || | 906 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || |
| 882 host->extension()->id() != extension_->id()) | 907 host->extension()->id() != extension_->id()) |
| 883 return; | 908 return; |
| 884 | 909 |
| 885 SendResponse(true); | 910 SendResponse(true); |
| 886 response_sent_ = true; | 911 response_sent_ = true; |
| 887 registrar_.RemoveAll(); | 912 registrar_.RemoveAll(); |
| 888 } | 913 } |
| 889 | 914 |
| 890 } // namespace extensions | 915 } // namespace extensions |
| OLD | NEW |