Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/browser/ui/extensions/extension_action_view_controller.cc

Issue 869873008: [Extensions Toolbar] Move some popup logic to be platform-agnostic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/ui/extensions/extension_action_view_controller.h" 5 #include "chrome/browser/ui/extensions/extension_action_view_controller.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/api/commands/command_service.h" 9 #include "chrome/browser/extensions/api/commands/command_service.h"
10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
11 #include "chrome/browser/extensions/extension_action.h" 11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/extensions/extension_view_host.h"
12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sessions/session_tab_helper.h" 14 #include "chrome/browser/sessions/session_tab_helper.h"
14 #include "chrome/browser/ui/browser.h" 15 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/extensions/accelerator_priority.h" 16 #include "chrome/browser/ui/extensions/accelerator_priority.h"
16 #include "chrome/browser/ui/extensions/extension_action_platform_delegate.h" 17 #include "chrome/browser/ui/extensions/extension_action_platform_delegate.h"
17 #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h" 18 #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
18 #include "chrome/common/extensions/api/extension_action/action_info.h" 19 #include "chrome/common/extensions/api/extension_action/action_info.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_source.h"
22 #include "extensions/browser/extension_host.h"
19 #include "extensions/browser/extension_registry.h" 23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/browser/notification_types.h"
20 #include "extensions/common/extension.h" 25 #include "extensions/common/extension.h"
21 #include "extensions/common/manifest_constants.h" 26 #include "extensions/common/manifest_constants.h"
22 #include "ui/gfx/image/image_skia.h" 27 #include "ui/gfx/image/image_skia.h"
23 #include "ui/gfx/image/image_skia_operations.h" 28 #include "ui/gfx/image/image_skia_operations.h"
24 29
25 using extensions::ActionInfo; 30 using extensions::ActionInfo;
26 using extensions::CommandService; 31 using extensions::CommandService;
27 32
28 ExtensionActionViewController::ExtensionActionViewController( 33 ExtensionActionViewController::ExtensionActionViewController(
29 const extensions::Extension* extension, 34 const extensions::Extension* extension,
30 Browser* browser, 35 Browser* browser,
31 ExtensionAction* extension_action) 36 ExtensionAction* extension_action)
32 : extension_(extension), 37 : extension_(extension),
33 browser_(browser), 38 browser_(browser),
34 extension_action_(extension_action), 39 extension_action_(extension_action),
40 popup_host_(nullptr),
35 view_delegate_(nullptr), 41 view_delegate_(nullptr),
36 platform_delegate_(ExtensionActionPlatformDelegate::Create(this)), 42 platform_delegate_(ExtensionActionPlatformDelegate::Create(this)),
37 icon_factory_(browser->profile(), extension, extension_action, this), 43 icon_factory_(browser->profile(), extension, extension_action, this),
38 icon_observer_(nullptr), 44 icon_observer_(nullptr),
39 extension_registry_( 45 extension_registry_(
40 extensions::ExtensionRegistry::Get(browser_->profile())) { 46 extensions::ExtensionRegistry::Get(browser_->profile())) {
41 DCHECK(extension_action); 47 DCHECK(extension_action);
42 DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE || 48 DCHECK(extension_action->action_type() == ActionInfo::TYPE_PAGE ||
43 extension_action->action_type() == ActionInfo::TYPE_BROWSER); 49 extension_action->action_type() == ActionInfo::TYPE_BROWSER);
44 DCHECK(extension); 50 DCHECK(extension);
45 } 51 }
46 52
47 ExtensionActionViewController::~ExtensionActionViewController() { 53 ExtensionActionViewController::~ExtensionActionViewController() {
48 } 54 }
49 55
50 const std::string& ExtensionActionViewController::GetId() const { 56 const std::string& ExtensionActionViewController::GetId() const {
51 return extension_->id(); 57 return extension_->id();
52 } 58 }
53 59
54 void ExtensionActionViewController::SetDelegate( 60 void ExtensionActionViewController::SetDelegate(
55 ToolbarActionViewDelegate* delegate) { 61 ToolbarActionViewDelegate* delegate) {
56 DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr)); 62 DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr));
57 if (delegate) { 63 if (delegate) {
58 view_delegate_ = delegate; 64 view_delegate_ = delegate;
59 platform_delegate_->OnDelegateSet(); 65 platform_delegate_->OnDelegateSet();
60 } else { 66 } else {
67 if (is_showing_popup())
68 HidePopup();
61 platform_delegate_.reset(); 69 platform_delegate_.reset();
62 view_delegate_ = nullptr; 70 view_delegate_ = nullptr;
63 } 71 }
64 } 72 }
65 73
66 gfx::Image ExtensionActionViewController::GetIcon( 74 gfx::Image ExtensionActionViewController::GetIcon(
67 content::WebContents* web_contents) { 75 content::WebContents* web_contents) {
68 if (!ExtensionIsValid()) 76 if (!ExtensionIsValid())
69 return gfx::Image(); 77 return gfx::Image();
70 78
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 bool ExtensionActionViewController::HasPopup( 134 bool ExtensionActionViewController::HasPopup(
127 content::WebContents* web_contents) const { 135 content::WebContents* web_contents) const {
128 if (!ExtensionIsValid()) 136 if (!ExtensionIsValid())
129 return false; 137 return false;
130 138
131 int tab_id = SessionTabHelper::IdForTab(web_contents); 139 int tab_id = SessionTabHelper::IdForTab(web_contents);
132 return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id); 140 return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id);
133 } 141 }
134 142
135 void ExtensionActionViewController::HidePopup() { 143 void ExtensionActionViewController::HidePopup() {
136 if (platform_delegate_->IsShowingPopup()) 144 if (is_showing_popup()) {
137 platform_delegate_->CloseOwnPopup(); 145 platform_delegate_->CloseOwnPopup();
146 // We need to do these actions synchronously (instead of closing and then
147 // performing the rest of the cleanup in Observe()) because the extension
148 // host can close asynchronously, and we need to keep the view delegate
149 // up-to-date.
150 OnPopupClosed();
151 }
138 } 152 }
139 153
140 gfx::NativeView ExtensionActionViewController::GetPopupNativeView() { 154 gfx::NativeView ExtensionActionViewController::GetPopupNativeView() {
141 return platform_delegate_->GetPopupNativeView(); 155 return platform_delegate_->GetPopupNativeView();
142 } 156 }
143 157
144 ui::MenuModel* ExtensionActionViewController::GetContextMenu() { 158 ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
145 if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus()) 159 if (!ExtensionIsValid() || !extension()->ShowConfigureContextMenus())
146 return nullptr; 160 return nullptr;
147 161
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 ExecuteAction(SHOW_POPUP_AND_INSPECT, true); 225 ExecuteAction(SHOW_POPUP_AND_INSPECT, true);
212 } 226 }
213 227
214 void ExtensionActionViewController::OnIconUpdated() { 228 void ExtensionActionViewController::OnIconUpdated() {
215 if (icon_observer_) 229 if (icon_observer_)
216 icon_observer_->OnIconUpdated(); 230 icon_observer_->OnIconUpdated();
217 if (view_delegate_) 231 if (view_delegate_)
218 view_delegate_->UpdateState(); 232 view_delegate_->UpdateState();
219 } 233 }
220 234
235 void ExtensionActionViewController::Observe(
236 int type,
237 const content::NotificationSource& source,
238 const content::NotificationDetails& details) {
239 // TODO(devlin): Ew. Notifications. Extract out an observer interface for
Avi (use Gerrit) 2015/01/29 02:59:26 Ew! That's the spirit!
240 // ExtensionHost and convert this.
241 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, type);
242 extensions::ExtensionHost* host =
243 content::Details<extensions::ExtensionHost>(details).ptr();
244 if (host == popup_host_)
245 OnPopupClosed();
246 }
247
221 bool ExtensionActionViewController::ExtensionIsValid() const { 248 bool ExtensionActionViewController::ExtensionIsValid() const {
222 return extension_registry_->enabled_extensions().Contains(extension_->id()); 249 return extension_registry_->enabled_extensions().Contains(extension_->id());
223 } 250 }
224 251
225 bool ExtensionActionViewController::GetExtensionCommand( 252 bool ExtensionActionViewController::GetExtensionCommand(
226 extensions::Command* command) { 253 extensions::Command* command) {
227 DCHECK(command); 254 DCHECK(command);
228 if (!ExtensionIsValid()) 255 if (!ExtensionIsValid())
229 return false; 256 return false;
230 257
231 CommandService* command_service = CommandService::Get(browser_->profile()); 258 CommandService* command_service = CommandService::Get(browser_->profile());
232 if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) { 259 if (extension_action_->action_type() == ActionInfo::TYPE_PAGE) {
233 return command_service->GetPageActionCommand( 260 return command_service->GetPageActionCommand(
234 extension_->id(), CommandService::ACTIVE, command, NULL); 261 extension_->id(), CommandService::ACTIVE, command, NULL);
235 } 262 }
236 return command_service->GetBrowserActionCommand( 263 return command_service->GetBrowserActionCommand(
237 extension_->id(), CommandService::ACTIVE, command, NULL); 264 extension_->id(), CommandService::ACTIVE, command, NULL);
238 } 265 }
239 266
240 bool ExtensionActionViewController::ShowPopupWithUrl( 267 bool ExtensionActionViewController::ShowPopupWithUrl(
241 PopupShowAction show_action, 268 PopupShowAction show_action,
242 const GURL& popup_url, 269 const GURL& popup_url,
243 bool grant_tab_permissions) { 270 bool grant_tab_permissions) {
244 if (!ExtensionIsValid()) 271 if (!ExtensionIsValid())
245 return false; 272 return false;
246 273
247 bool already_showing = platform_delegate_->IsShowingPopup(); 274 bool already_showing = is_showing_popup();
248 275
249 // Always hide the current popup, even if it's not owned by this extension. 276 // Always hide the current popup, even if it's not owned by this extension.
250 // Only one popup should be visible at a time. 277 // Only one popup should be visible at a time.
251 platform_delegate_->CloseActivePopup(); 278 platform_delegate_->CloseActivePopup();
252 279
253 // If we were showing a popup already, then we treat the action to open the 280 // If we were showing a popup already, then we treat the action to open the
254 // same one as a desire to close it (like clicking a menu button that was 281 // same one as a desire to close it (like clicking a menu button that was
255 // already open). 282 // already open).
256 if (already_showing) 283 if (already_showing)
257 return false; 284 return false;
258 285
259 return platform_delegate_->ShowPopupWithUrl( 286 popup_host_ = platform_delegate_->ShowPopupWithUrl(
260 show_action, popup_url, grant_tab_permissions); 287 show_action, popup_url, grant_tab_permissions);
288 if (popup_host_) {
289 // Lazily register for notifications about extension host destructions.
290 static const int kType = extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED;
291 content::Source<content::BrowserContext> source(browser_->profile());
292 if (!registrar_.IsRegistered(this, kType, source))
293 registrar_.Add(this, kType, source);
294
295 view_delegate_->OnPopupShown(grant_tab_permissions);
296 }
297 return is_showing_popup();
261 } 298 }
299
300 void ExtensionActionViewController::OnPopupClosed() {
301 popup_host_ = nullptr;
302 view_delegate_->OnPopupClosed();
303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698