| 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/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/browser/extensions/active_script_controller.h" | 10 #include "chrome/browser/extensions/active_script_controller.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "chrome/common/extensions/api/extension_action/action_info.h" | 22 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 23 #include "chrome/common/render_messages.h" | 23 #include "chrome/common/render_messages.h" |
| 24 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 25 #include "extensions/browser/event_router.h" | 25 #include "extensions/browser/event_router.h" |
| 26 #include "extensions/browser/extension_function_registry.h" | 26 #include "extensions/browser/extension_function_registry.h" |
| 27 #include "extensions/browser/extension_host.h" | 27 #include "extensions/browser/extension_host.h" |
| 28 #include "extensions/browser/extension_registry.h" | 28 #include "extensions/browser/extension_registry.h" |
| 29 #include "extensions/browser/image_util.h" | 29 #include "extensions/browser/image_util.h" |
| 30 #include "extensions/browser/notification_types.h" | 30 #include "extensions/browser/notification_types.h" |
| 31 #include "extensions/common/error_utils.h" | 31 #include "extensions/common/error_utils.h" |
| 32 #include "extensions/common/feature_switch.h" |
| 32 #include "ui/gfx/image/image.h" | 33 #include "ui/gfx/image/image.h" |
| 33 #include "ui/gfx/image/image_skia.h" | 34 #include "ui/gfx/image/image_skia.h" |
| 34 | 35 |
| 35 using content::WebContents; | 36 using content::WebContents; |
| 36 | 37 |
| 37 namespace extensions { | 38 namespace extensions { |
| 38 | 39 |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 // Whether the browser action is visible in the toolbar. | 42 // Whether the browser action is visible in the toolbar. |
| 42 const char kBrowserActionVisible[] = "browser_action_visible"; | 43 const char kBrowserActionVisible[] = "browser_action_visible"; |
| 43 | 44 |
| 44 // Errors. | 45 // Errors. |
| 45 const char kNoExtensionActionError[] = | 46 const char kNoExtensionActionError[] = |
| 46 "This extension has no action specified."; | 47 "This extension has no action specified."; |
| 47 const char kNoTabError[] = "No tab with id: *."; | 48 const char kNoTabError[] = "No tab with id: *."; |
| 48 const char kOpenPopupError[] = | 49 const char kOpenPopupError[] = |
| 49 "Failed to show popup either because there is an existing popup or another " | 50 "Failed to show popup either because there is an existing popup or another " |
| 50 "error occurred."; | 51 "error occurred."; |
| 51 const char kInternalError[] = "Internal error."; | |
| 52 | 52 |
| 53 } // namespace | 53 } // namespace |
| 54 | 54 |
| 55 // | 55 // |
| 56 // ExtensionActionAPI::Observer | 56 // ExtensionActionAPI::Observer |
| 57 // | 57 // |
| 58 | 58 |
| 59 void ExtensionActionAPI::Observer::OnExtensionActionUpdated( | 59 void ExtensionActionAPI::Observer::OnExtensionActionUpdated( |
| 60 ExtensionAction* extension_action, | 60 ExtensionAction* extension_action, |
| 61 content::WebContents* web_contents, | 61 content::WebContents* web_contents, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 const Extension* extension, | 164 const Extension* extension, |
| 165 Browser* browser, | 165 Browser* browser, |
| 166 bool grant_active_tab_permissions) { | 166 bool grant_active_tab_permissions) { |
| 167 content::WebContents* web_contents = | 167 content::WebContents* web_contents = |
| 168 browser->tab_strip_model()->GetActiveWebContents(); | 168 browser->tab_strip_model()->GetActiveWebContents(); |
| 169 if (!web_contents) | 169 if (!web_contents) |
| 170 return ExtensionAction::ACTION_NONE; | 170 return ExtensionAction::ACTION_NONE; |
| 171 | 171 |
| 172 int tab_id = SessionTabHelper::IdForTab(web_contents); | 172 int tab_id = SessionTabHelper::IdForTab(web_contents); |
| 173 | 173 |
| 174 ExtensionActionManager* action_manager = | |
| 175 ExtensionActionManager::Get(static_cast<Profile*>(browser_context_)); | |
| 176 // TODO(devlin): Make a ExtensionActionManager::GetExtensionAction method. | |
| 177 ExtensionAction* extension_action = | 174 ExtensionAction* extension_action = |
| 178 action_manager->GetBrowserAction(*extension); | 175 ExtensionActionManager::Get(browser_context_)->GetExtensionAction( |
| 179 if (!extension_action) | 176 *extension); |
| 180 extension_action = action_manager->GetPageAction(*extension); | |
| 181 | 177 |
| 182 // Anything that calls this should have a page or browser action. | 178 // Anything that calls this should have a page or browser action. |
| 183 DCHECK(extension_action); | 179 DCHECK(extension_action); |
| 184 if (!extension_action->GetIsVisible(tab_id)) | 180 if (!extension_action->GetIsVisible(tab_id)) |
| 185 return ExtensionAction::ACTION_NONE; | 181 return ExtensionAction::ACTION_NONE; |
| 186 | 182 |
| 187 // Grant active tab if appropriate. | 183 // Grant active tab if appropriate. |
| 188 if (grant_active_tab_permissions) { | 184 if (grant_active_tab_permissions) { |
| 189 TabHelper::FromWebContents(web_contents)->active_tab_permission_granter()-> | 185 TabHelper::FromWebContents(web_contents)->active_tab_permission_granter()-> |
| 190 GrantIfRequested(extension); | 186 GrantIfRequested(extension); |
| 191 } | 187 } |
| 192 | 188 |
| 193 // Notify ActiveScriptController that the action was clicked, if appropriate. | 189 // Notify ActiveScriptController that the action was clicked, if appropriate. |
| 194 ActiveScriptController* active_script_controller = | 190 ActiveScriptController* active_script_controller = |
| 195 ActiveScriptController::GetForWebContents(web_contents); | 191 ActiveScriptController::GetForWebContents(web_contents); |
| 196 if (active_script_controller && | 192 if (active_script_controller && |
| 197 active_script_controller->GetActionForExtension(extension)) { | 193 active_script_controller->GetActionForExtension(extension)) { |
| 198 active_script_controller->OnClicked(extension); | 194 active_script_controller->OnClicked(extension); |
| 199 } | 195 } |
| 200 | 196 |
| 201 if (extension_action->HasPopup(tab_id)) | 197 if (extension_action->HasPopup(tab_id)) |
| 202 return ExtensionAction::ACTION_SHOW_POPUP; | 198 return ExtensionAction::ACTION_SHOW_POPUP; |
| 203 | 199 |
| 204 ExtensionActionExecuted(*extension_action, web_contents); | 200 ExtensionActionExecuted(*extension_action, web_contents); |
| 205 return ExtensionAction::ACTION_NONE; | 201 return ExtensionAction::ACTION_NONE; |
| 206 } | 202 } |
| 207 | 203 |
| 204 bool ExtensionActionAPI::ShowExtensionActionPopup( |
| 205 const Extension* extension, |
| 206 Browser* browser, |
| 207 bool grant_active_tab_permissions) { |
| 208 ExtensionAction* extension_action = |
| 209 ExtensionActionManager::Get(browser_context_)->GetExtensionAction( |
| 210 *extension); |
| 211 if (!extension_action) |
| 212 return false; |
| 213 |
| 214 if (extension_action->action_type() == ActionInfo::TYPE_PAGE && |
| 215 !FeatureSwitch::extension_action_redesign()->IsEnabled()) { |
| 216 // We show page actions in the location bar unless the new toolbar is |
| 217 // enabled. |
| 218 return browser->window()->GetLocationBar()->ShowPageActionPopup( |
| 219 extension, grant_active_tab_permissions); |
| 220 } else { |
| 221 return ExtensionToolbarModel::Get(browser->profile())-> |
| 222 ShowExtensionActionPopup( |
| 223 extension, browser, grant_active_tab_permissions); |
| 224 } |
| 225 } |
| 226 |
| 208 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, | 227 void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, |
| 209 content::WebContents* web_contents, | 228 content::WebContents* web_contents, |
| 210 content::BrowserContext* context) { | 229 content::BrowserContext* context) { |
| 211 FOR_EACH_OBSERVER( | 230 FOR_EACH_OBSERVER( |
| 212 Observer, | 231 Observer, |
| 213 observers_, | 232 observers_, |
| 214 OnExtensionActionUpdated(extension_action, web_contents, context)); | 233 OnExtensionActionUpdated(extension_action, web_contents, context)); |
| 215 | 234 |
| 216 if (extension_action->action_type() == ActionInfo::TYPE_PAGE) | 235 if (extension_action->action_type() == ActionInfo::TYPE_PAGE) |
| 217 NotifyPageActionsChanged(web_contents); | 236 NotifyPageActionsChanged(web_contents); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 new base::FundamentalValue(static_cast<int>(SkColorGetA(color)))); | 575 new base::FundamentalValue(static_cast<int>(SkColorGetA(color)))); |
| 557 SetResult(list); | 576 SetResult(list); |
| 558 return true; | 577 return true; |
| 559 } | 578 } |
| 560 | 579 |
| 561 BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() | 580 BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() |
| 562 : response_sent_(false) { | 581 : response_sent_(false) { |
| 563 } | 582 } |
| 564 | 583 |
| 565 bool BrowserActionOpenPopupFunction::RunAsync() { | 584 bool BrowserActionOpenPopupFunction::RunAsync() { |
| 566 ExtensionToolbarModel* model = ExtensionToolbarModel::Get(GetProfile()); | 585 // We only allow the popup in the active window. |
| 567 if (!model) { | 586 Browser* browser = chrome::FindLastActiveWithProfile( |
| 568 error_ = kInternalError; | 587 GetProfile(), chrome::GetActiveDesktop()); |
| 569 return false; | |
| 570 } | |
| 571 | 588 |
| 572 if (!model->ShowBrowserActionPopup(extension_.get())) { | 589 // If there's no active browser, or the Toolbar isn't visible, abort. |
| 590 // Otherwise, try to open a popup in the active browser. |
| 591 // TODO(justinlin): Remove toolbar check when http://crbug.com/308645 is |
| 592 // fixed. |
| 593 if (!browser || |
| 594 !browser->window()->IsActive() || |
| 595 !browser->window()->IsToolbarVisible() || |
| 596 !ExtensionActionAPI::Get(GetProfile())->ShowExtensionActionPopup( |
| 597 extension_.get(), browser, false)) { |
| 573 error_ = kOpenPopupError; | 598 error_ = kOpenPopupError; |
| 574 return false; | 599 return false; |
| 575 } | 600 } |
| 576 | 601 |
| 577 registrar_.Add(this, | 602 registrar_.Add(this, |
| 578 NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 603 NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, |
| 579 content::Source<Profile>(GetProfile())); | 604 content::Source<Profile>(GetProfile())); |
| 580 | 605 |
| 581 // Set a timeout for waiting for the notification that the popup is loaded. | 606 // Set a timeout for waiting for the notification that the popup is loaded. |
| 582 // Waiting is required so that the popup view can be retrieved by the custom | 607 // Waiting is required so that the popup view can be retrieved by the custom |
| (...skipping 28 matching lines...) Expand all Loading... |
| 611 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || | 636 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || |
| 612 host->extension()->id() != extension_->id()) | 637 host->extension()->id() != extension_->id()) |
| 613 return; | 638 return; |
| 614 | 639 |
| 615 SendResponse(true); | 640 SendResponse(true); |
| 616 response_sent_ = true; | 641 response_sent_ = true; |
| 617 registrar_.RemoveAll(); | 642 registrar_.RemoveAll(); |
| 618 } | 643 } |
| 619 | 644 |
| 620 } // namespace extensions | 645 } // namespace extensions |
| OLD | NEW |