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

Side by Side Diff: chrome/browser/extensions/extension_host.cc

Issue 10913243: extensions: Add ExtensionView interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: weak Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
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/extension_host.h" 5 #include "chrome/browser/extensions/extension_host.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/singleton.h" 10 #include "base/memory/singleton.h"
11 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser_shutdown.h" 16 #include "chrome/browser/browser_shutdown.h"
17 #include "chrome/browser/extensions/event_router.h" 17 #include "chrome/browser/extensions/event_router.h"
18 #include "chrome/browser/extensions/extension_process_manager.h" 18 #include "chrome/browser/extensions/extension_process_manager.h"
19 #include "chrome/browser/extensions/extension_service.h" 19 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/extensions/extension_system.h" 20 #include "chrome/browser/extensions/extension_system.h"
21 #include "chrome/browser/extensions/extension_tab_util.h" 21 #include "chrome/browser/extensions/extension_tab_util.h"
22 #include "chrome/browser/extensions/extension_view.h"
22 #include "chrome/browser/extensions/window_controller.h" 23 #include "chrome/browser/extensions/window_controller.h"
23 #include "chrome/browser/file_select_helper.h" 24 #include "chrome/browser/file_select_helper.h"
24 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" 26 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h"
26 #include "chrome/browser/ui/browser.h" 27 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_finder.h" 28 #include "chrome/browser/ui/browser_finder.h"
28 #include "chrome/browser/ui/browser_list.h" 29 #include "chrome/browser/ui/browser_list.h"
29 #include "chrome/browser/ui/browser_window.h" 30 #include "chrome/browser/ui/browser_window.h"
30 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" 31 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
31 #include "chrome/browser/ui/tab_contents/tab_contents.h" 32 #include "chrome/browser/ui/tab_contents/tab_contents.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime", 163 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime",
163 since_created_.Elapsed()); 164 since_created_.Elapsed());
164 } 165 }
165 content::NotificationService::current()->Notify( 166 content::NotificationService::current()->Notify(
166 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, 167 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
167 content::Source<Profile>(profile_), 168 content::Source<Profile>(profile_),
168 content::Details<ExtensionHost>(this)); 169 content::Details<ExtensionHost>(this));
169 ProcessCreationQueue::GetInstance()->Remove(this); 170 ProcessCreationQueue::GetInstance()->Remove(this);
170 } 171 }
171 172
173 void ExtensionHost::SetExtensionView(ExtensionView* view) {
174 extension_view_.reset(view);
175 }
176
177 const ExtensionView* ExtensionHost::GetExtensionView() const {
178 return extension_view_.get();
179 }
180
181 ExtensionView* ExtensionHost::GetExtensionView() {
182 return extension_view_.get();
183 }
184
172 void ExtensionHost::CreateView(Browser* browser) { 185 void ExtensionHost::CreateView(Browser* browser) {
173 #if defined(TOOLKIT_VIEWS) 186 extension_view_.reset(ExtensionView::Create(this, browser));
174 view_.reset(new ExtensionViewViews(this, browser));
175 // We own |view_|, so don't auto delete when it's removed from the view
176 // hierarchy.
177 view_->set_owned_by_client();
178 #elif defined(OS_MACOSX)
179 view_.reset(new ExtensionViewMac(this, browser));
180 view_->Init();
181 #elif defined(TOOLKIT_GTK)
182 view_.reset(new ExtensionViewGtk(this, browser));
183 view_->Init();
184 #else
185 // TODO(port)
186 NOTREACHED();
187 #endif
188 } 187 }
189 188
190 WebContents* ExtensionHost::GetAssociatedWebContents() const { 189 WebContents* ExtensionHost::GetAssociatedWebContents() const {
191 return associated_web_contents_; 190 return associated_web_contents_;
192 } 191 }
193 192
194 void ExtensionHost::SetAssociatedWebContents( 193 void ExtensionHost::SetAssociatedWebContents(
195 content::WebContents* web_contents) { 194 content::WebContents* web_contents) {
196 associated_web_contents_ = web_contents; 195 associated_web_contents_ = web_contents;
197 if (web_contents) { 196 if (web_contents) {
(...skipping 29 matching lines...) Expand all
227 void ExtensionHost::CreateRenderViewNow() { 226 void ExtensionHost::CreateRenderViewNow() {
228 LoadInitialURL(); 227 LoadInitialURL();
229 if (is_background_page()) { 228 if (is_background_page()) {
230 DCHECK(IsRenderViewLive()); 229 DCHECK(IsRenderViewLive());
231 profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(this); 230 profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(this);
232 } 231 }
233 } 232 }
234 233
235 extensions::WindowController* 234 extensions::WindowController*
236 ExtensionHost::GetExtensionWindowController() const { 235 ExtensionHost::GetExtensionWindowController() const {
237 return view() && view()->browser() ? 236 return GetExtensionView() && GetExtensionView()->GetBrowser() ?
238 view()->browser()->extension_window_controller() : NULL; 237 GetExtensionView()->GetBrowser()->extension_window_controller() : NULL;
239 } 238 }
240 239
241 const GURL& ExtensionHost::GetURL() const { 240 const GURL& ExtensionHost::GetURL() const {
242 return host_contents()->GetURL(); 241 return host_contents()->GetURL();
243 } 242 }
244 243
245 void ExtensionHost::LoadInitialURL() { 244 void ExtensionHost::LoadInitialURL() {
246 if (!is_background_page() && 245 if (!is_background_page() &&
247 !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) { 246 !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) {
248 // Make sure the background page loads before any others. 247 // Make sure the background page loads before any others.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 288 }
290 break; 289 break;
291 default: 290 default:
292 NOTREACHED() << "Unexpected notification sent."; 291 NOTREACHED() << "Unexpected notification sent.";
293 break; 292 break;
294 } 293 }
295 } 294 }
296 295
297 void ExtensionHost::ResizeDueToAutoResize(WebContents* source, 296 void ExtensionHost::ResizeDueToAutoResize(WebContents* source,
298 const gfx::Size& new_size) { 297 const gfx::Size& new_size) {
299 if (view()) 298 if (GetExtensionView())
300 view()->ResizeDueToAutoResize(new_size); 299 GetExtensionView()->ResizeDueToAutoResize(new_size);
301 } 300 }
302 301
303 void ExtensionHost::RenderViewGone(base::TerminationStatus status) { 302 void ExtensionHost::RenderViewGone(base::TerminationStatus status) {
304 // During browser shutdown, we may use sudden termination on an extension 303 // During browser shutdown, we may use sudden termination on an extension
305 // process, so it is expected to lose our connection to the render view. 304 // process, so it is expected to lose our connection to the render view.
306 // Do nothing. 305 // Do nothing.
307 if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) 306 if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID)
308 return; 307 return;
309 308
310 // In certain cases, multiple ExtensionHost objects may have pointed to 309 // In certain cases, multiple ExtensionHost objects may have pointed to
(...skipping 25 matching lines...) Expand all
336 } 335 }
337 336
338 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { 337 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) {
339 bool notify = !did_stop_loading_; 338 bool notify = !did_stop_loading_;
340 did_stop_loading_ = true; 339 did_stop_loading_ = true;
341 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || 340 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP ||
342 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || 341 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG ||
343 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || 342 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR ||
344 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { 343 extension_host_type_ == chrome::VIEW_TYPE_PANEL) {
345 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) 344 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX)
346 if (view()) 345 if (GetExtensionView())
347 view()->DidStopLoading(); 346 GetExtensionView()->DidStopLoading();
348 #endif 347 #endif
349 } 348 }
350 if (notify) { 349 if (notify) {
351 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 350 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
352 if (extension_ && extension_->has_lazy_background_page()) { 351 if (extension_ && extension_->has_lazy_background_page()) {
353 UMA_HISTOGRAM_TIMES("Extensions.EventPageLoadTime", 352 UMA_HISTOGRAM_TIMES("Extensions.EventPageLoadTime",
354 since_created_.Elapsed()); 353 since_created_.Elapsed());
355 } else { 354 } else {
356 UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime", 355 UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime",
357 since_created_.Elapsed()); 356 since_created_.Elapsed());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || 405 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR ||
407 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { 406 extension_host_type_ == chrome::VIEW_TYPE_PANEL) {
408 Close(); 407 Close();
409 } 408 }
410 } 409 }
411 410
412 void ExtensionHost::OnStartDownload( 411 void ExtensionHost::OnStartDownload(
413 content::WebContents* source, content::DownloadItem* download) { 412 content::WebContents* source, content::DownloadItem* download) {
414 // If |source| is in the context of a Browser, show the DownloadShelf on that 413 // If |source| is in the context of a Browser, show the DownloadShelf on that
415 // Browser. 414 // Browser.
416 if (!view() || !view()->browser()) 415 if (!GetExtensionView() || !GetExtensionView()->GetBrowser())
417 return; 416 return;
418 static_cast<content::WebContentsDelegate*>(view()->browser())-> 417 static_cast<content::WebContentsDelegate*>(GetExtensionView()->GetBrowser())->
419 OnStartDownload(source, download); 418 OnStartDownload(source, download);
420 } 419 }
421 420
422 void ExtensionHost::WebIntentDispatch( 421 void ExtensionHost::WebIntentDispatch(
423 content::WebContents* web_contents, 422 content::WebContents* web_contents,
424 content::WebIntentsDispatcher* intents_dispatcher) { 423 content::WebIntentsDispatcher* intents_dispatcher) {
425 #if !defined(OS_ANDROID) 424 #if !defined(OS_ANDROID)
426 scoped_ptr<content::WebIntentsDispatcher> dispatcher(intents_dispatcher); 425 scoped_ptr<content::WebIntentsDispatcher> dispatcher(intents_dispatcher);
427 426
428 Browser* browser = view() ? view()->browser() 427 Browser* browser = GetExtensionView() ? GetExtensionView()->GetBrowser()
429 : browser::FindBrowserWithWebContents(web_contents); 428 : browser::FindBrowserWithWebContents(web_contents);
430 429
431 // For background scripts/pages, there will be no view(). In this case, we 430 // For background scripts/pages, there will be no GetExtensionView(). In this
432 // want to treat the intent as a browser-initiated one and deliver it into the 431 // case, we want to treat the intent as a browser-initiated one and deliver it
433 // current browser. It probably came from a context menu click or similar. 432 // into the current browser. It probably came from a context menu click or
433 // similar.
434 if (!browser) 434 if (!browser)
435 browser = web_intents::GetBrowserForBackgroundWebIntentDelivery(profile()); 435 browser = web_intents::GetBrowserForBackgroundWebIntentDelivery(profile());
436 436
437 if (browser) { 437 if (browser) {
438 static_cast<WebContentsDelegate*>(browser)-> 438 static_cast<WebContentsDelegate*>(browser)->
439 WebIntentDispatch(NULL, dispatcher.release()); 439 WebIntentDispatch(NULL, dispatcher.release());
440 } 440 }
441 #endif 441 #endif
442 } 442 }
443 443
(...skipping 17 matching lines...) Expand all
461 switch (params.disposition) { 461 switch (params.disposition) {
462 case SINGLETON_TAB: 462 case SINGLETON_TAB:
463 case NEW_FOREGROUND_TAB: 463 case NEW_FOREGROUND_TAB:
464 case NEW_BACKGROUND_TAB: 464 case NEW_BACKGROUND_TAB:
465 case NEW_POPUP: 465 case NEW_POPUP:
466 case NEW_WINDOW: 466 case NEW_WINDOW:
467 case SAVE_TO_DISK: 467 case SAVE_TO_DISK:
468 case OFF_THE_RECORD: { 468 case OFF_THE_RECORD: {
469 // Only allow these from hosts that are bound to a browser (e.g. popups). 469 // Only allow these from hosts that are bound to a browser (e.g. popups).
470 // Otherwise they are not driven by a user gesture. 470 // Otherwise they are not driven by a user gesture.
471 Browser* browser = view() ? view()->browser() : NULL; 471 Browser* browser = GetExtensionView() ?
472 GetExtensionView()->GetBrowser() : NULL;
472 return browser ? browser->OpenURL(params) : NULL; 473 return browser ? browser->OpenURL(params) : NULL;
473 } 474 }
474 default: 475 default:
475 return NULL; 476 return NULL;
476 } 477 }
477 } 478 }
478 479
479 bool ExtensionHost::PreHandleKeyboardEvent(WebContents* source, 480 bool ExtensionHost::PreHandleKeyboardEvent(WebContents* source,
480 const NativeWebKeyboardEvent& event, 481 const NativeWebKeyboardEvent& event,
481 bool* is_keyboard_shortcut) { 482 bool* is_keyboard_shortcut) {
482 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP && 483 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP &&
483 event.type == NativeWebKeyboardEvent::RawKeyDown && 484 event.type == NativeWebKeyboardEvent::RawKeyDown &&
484 event.windowsKeyCode == ui::VKEY_ESCAPE) { 485 event.windowsKeyCode == ui::VKEY_ESCAPE) {
485 DCHECK(is_keyboard_shortcut != NULL); 486 DCHECK(is_keyboard_shortcut != NULL);
486 *is_keyboard_shortcut = true; 487 *is_keyboard_shortcut = true;
487 return false; 488 return false;
488 } 489 }
489 490
490 // Handle higher priority browser shortcuts such as Ctrl-w. 491 // Handle higher priority browser shortcuts such as Ctrl-w.
491 Browser* browser = view() ? view()->browser() : NULL; 492 Browser* browser = GetExtensionView() ?
493 GetExtensionView()->GetBrowser() : NULL;
492 if (browser) 494 if (browser)
493 return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut); 495 return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut);
494 496
495 *is_keyboard_shortcut = false; 497 *is_keyboard_shortcut = false;
496 return false; 498 return false;
497 } 499 }
498 500
499 void ExtensionHost::HandleKeyboardEvent(WebContents* source, 501 void ExtensionHost::HandleKeyboardEvent(WebContents* source,
500 const NativeWebKeyboardEvent& event) { 502 const NativeWebKeyboardEvent& event) {
501 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP) { 503 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 void ExtensionHost::OnDecrementLazyKeepaliveCount() { 545 void ExtensionHost::OnDecrementLazyKeepaliveCount() {
544 ExtensionProcessManager* pm = 546 ExtensionProcessManager* pm =
545 ExtensionSystem::Get(profile_)->process_manager(); 547 ExtensionSystem::Get(profile_)->process_manager();
546 if (pm) 548 if (pm)
547 pm->DecrementLazyKeepaliveCount(extension()); 549 pm->DecrementLazyKeepaliveCount(extension());
548 } 550 }
549 551
550 void ExtensionHost::UnhandledKeyboardEvent( 552 void ExtensionHost::UnhandledKeyboardEvent(
551 WebContents* source, 553 WebContents* source,
552 const content::NativeWebKeyboardEvent& event) { 554 const content::NativeWebKeyboardEvent& event) {
553 Browser* browser = view() ? view()->browser() : NULL; 555 Browser* browser = GetExtensionView() ?
556 GetExtensionView()->GetBrowser() : NULL;
554 if (browser) { 557 if (browser) {
555 // Handle lower priority browser shortcuts such as Ctrl-f. 558 // Handle lower priority browser shortcuts such as Ctrl-f.
556 return browser->HandleKeyboardEvent(source, event); 559 return browser->HandleKeyboardEvent(source, event);
557 } else { 560 } else {
558 #if defined(TOOLKIT_VIEWS) 561 #if defined(TOOLKIT_VIEWS)
559 // In case there's no Browser (e.g. for dialogs), pass it to 562 // In case there's no Browser (e.g. for dialogs), pass it to
560 // ExtensionViewViews to handle acceleratos. The view's FocusManager does 563 // ExtensionViewViews to handle acceleratos. The view's FocusManager does
561 // not know anything about Browser accelerators, but might know others such 564 // not know anything about Browser accelerators, but might know others such
562 // as Ash's. 565 // as Ash's.
563 if (view()) 566 if (GetExtensionView())
564 view()->HandleKeyboardEvent(event); 567 GetExtensionView()->HandleKeyboardEvent(event);
565 #endif 568 #endif
566 } 569 }
567 } 570 }
568 571
569 void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { 572 void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
570 render_view_host_ = render_view_host; 573 render_view_host_ = render_view_host;
571 574
572 if (view()) 575 if (GetExtensionView())
573 view()->RenderViewCreated(); 576 GetExtensionView()->RenderViewCreated();
574 577
575 // If the host is bound to a window, then extract its id. Extensions hosted 578 // If the host is bound to a window, then extract its id. Extensions hosted
576 // in ExternalTabContainer objects may not have an associated window. 579 // in ExternalTabContainer objects may not have an associated window.
577 extensions::WindowController* window = GetExtensionWindowController(); 580 extensions::WindowController* window = GetExtensionWindowController();
578 if (window) { 581 if (window) {
579 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( 582 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId(
580 render_view_host->GetRoutingID(), window->GetWindowId())); 583 render_view_host->GetRoutingID(), window->GetWindowId()));
581 } 584 }
582 } 585 }
583 586
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 } 637 }
635 638
636 void ExtensionHost::RenderViewReady() { 639 void ExtensionHost::RenderViewReady() {
637 content::NotificationService::current()->Notify( 640 content::NotificationService::current()->Notify(
638 chrome::NOTIFICATION_EXTENSION_HOST_CREATED, 641 chrome::NOTIFICATION_EXTENSION_HOST_CREATED,
639 content::Source<Profile>(profile_), 642 content::Source<Profile>(profile_),
640 content::Details<ExtensionHost>(this)); 643 content::Details<ExtensionHost>(this));
641 } 644 }
642 645
643 } // namespace extensions 646 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_host.h ('k') | chrome/browser/extensions/extension_host_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698