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 |