| 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/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" | |
| 23 #include "chrome/browser/extensions/window_controller.h" | 22 #include "chrome/browser/extensions/window_controller.h" |
| 24 #include "chrome/browser/file_select_helper.h" | 23 #include "chrome/browser/file_select_helper.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" | 25 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" |
| 27 #include "chrome/browser/ui/browser.h" | 26 #include "chrome/browser/ui/browser.h" |
| 28 #include "chrome/browser/ui/browser_finder.h" | 27 #include "chrome/browser/ui/browser_finder.h" |
| 29 #include "chrome/browser/ui/browser_list.h" | 28 #include "chrome/browser/ui/browser_list.h" |
| 30 #include "chrome/browser/ui/browser_window.h" | 29 #include "chrome/browser/ui/browser_window.h" |
| 31 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" | 30 #include "chrome/browser/ui/prefs/prefs_tab_helper.h" |
| 32 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 31 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime", | 162 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime", |
| 164 since_created_.Elapsed()); | 163 since_created_.Elapsed()); |
| 165 } | 164 } |
| 166 content::NotificationService::current()->Notify( | 165 content::NotificationService::current()->Notify( |
| 167 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 166 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 168 content::Source<Profile>(profile_), | 167 content::Source<Profile>(profile_), |
| 169 content::Details<ExtensionHost>(this)); | 168 content::Details<ExtensionHost>(this)); |
| 170 ProcessCreationQueue::GetInstance()->Remove(this); | 169 ProcessCreationQueue::GetInstance()->Remove(this); |
| 171 } | 170 } |
| 172 | 171 |
| 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 | |
| 185 void ExtensionHost::CreateView(Browser* browser) { | 172 void ExtensionHost::CreateView(Browser* browser) { |
| 186 extension_view_.reset(ExtensionView::Create(this, browser)); | 173 #if defined(TOOLKIT_VIEWS) |
| 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 |
| 187 } | 188 } |
| 188 | 189 |
| 189 WebContents* ExtensionHost::GetAssociatedWebContents() const { | 190 WebContents* ExtensionHost::GetAssociatedWebContents() const { |
| 190 return associated_web_contents_; | 191 return associated_web_contents_; |
| 191 } | 192 } |
| 192 | 193 |
| 193 void ExtensionHost::SetAssociatedWebContents( | 194 void ExtensionHost::SetAssociatedWebContents( |
| 194 content::WebContents* web_contents) { | 195 content::WebContents* web_contents) { |
| 195 associated_web_contents_ = web_contents; | 196 associated_web_contents_ = web_contents; |
| 196 if (web_contents) { | 197 if (web_contents) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 226 void ExtensionHost::CreateRenderViewNow() { | 227 void ExtensionHost::CreateRenderViewNow() { |
| 227 LoadInitialURL(); | 228 LoadInitialURL(); |
| 228 if (is_background_page()) { | 229 if (is_background_page()) { |
| 229 DCHECK(IsRenderViewLive()); | 230 DCHECK(IsRenderViewLive()); |
| 230 profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(this); | 231 profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(this); |
| 231 } | 232 } |
| 232 } | 233 } |
| 233 | 234 |
| 234 extensions::WindowController* | 235 extensions::WindowController* |
| 235 ExtensionHost::GetExtensionWindowController() const { | 236 ExtensionHost::GetExtensionWindowController() const { |
| 236 return GetExtensionView() && GetExtensionView()->GetBrowser() ? | 237 return view() && view()->browser() ? |
| 237 GetExtensionView()->GetBrowser()->extension_window_controller() : NULL; | 238 view()->browser()->extension_window_controller() : NULL; |
| 238 } | 239 } |
| 239 | 240 |
| 240 const GURL& ExtensionHost::GetURL() const { | 241 const GURL& ExtensionHost::GetURL() const { |
| 241 return host_contents()->GetURL(); | 242 return host_contents()->GetURL(); |
| 242 } | 243 } |
| 243 | 244 |
| 244 void ExtensionHost::LoadInitialURL() { | 245 void ExtensionHost::LoadInitialURL() { |
| 245 if (!is_background_page() && | 246 if (!is_background_page() && |
| 246 !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) { | 247 !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) { |
| 247 // Make sure the background page loads before any others. | 248 // Make sure the background page loads before any others. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 289 } |
| 289 break; | 290 break; |
| 290 default: | 291 default: |
| 291 NOTREACHED() << "Unexpected notification sent."; | 292 NOTREACHED() << "Unexpected notification sent."; |
| 292 break; | 293 break; |
| 293 } | 294 } |
| 294 } | 295 } |
| 295 | 296 |
| 296 void ExtensionHost::ResizeDueToAutoResize(WebContents* source, | 297 void ExtensionHost::ResizeDueToAutoResize(WebContents* source, |
| 297 const gfx::Size& new_size) { | 298 const gfx::Size& new_size) { |
| 298 if (GetExtensionView()) | 299 if (view()) |
| 299 GetExtensionView()->ResizeDueToAutoResize(new_size); | 300 view()->ResizeDueToAutoResize(new_size); |
| 300 } | 301 } |
| 301 | 302 |
| 302 void ExtensionHost::RenderViewGone(base::TerminationStatus status) { | 303 void ExtensionHost::RenderViewGone(base::TerminationStatus status) { |
| 303 // During browser shutdown, we may use sudden termination on an extension | 304 // During browser shutdown, we may use sudden termination on an extension |
| 304 // process, so it is expected to lose our connection to the render view. | 305 // process, so it is expected to lose our connection to the render view. |
| 305 // Do nothing. | 306 // Do nothing. |
| 306 if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) | 307 if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) |
| 307 return; | 308 return; |
| 308 | 309 |
| 309 // In certain cases, multiple ExtensionHost objects may have pointed to | 310 // In certain cases, multiple ExtensionHost objects may have pointed to |
| (...skipping 25 matching lines...) Expand all Loading... |
| 335 } | 336 } |
| 336 | 337 |
| 337 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { | 338 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { |
| 338 bool notify = !did_stop_loading_; | 339 bool notify = !did_stop_loading_; |
| 339 did_stop_loading_ = true; | 340 did_stop_loading_ = true; |
| 340 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || | 341 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || |
| 341 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || | 342 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || |
| 342 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || | 343 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || |
| 343 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { | 344 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { |
| 344 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) | 345 #if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) |
| 345 if (GetExtensionView()) | 346 if (view()) |
| 346 GetExtensionView()->DidStopLoading(); | 347 view()->DidStopLoading(); |
| 347 #endif | 348 #endif |
| 348 } | 349 } |
| 349 if (notify) { | 350 if (notify) { |
| 350 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 351 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 351 if (extension_ && extension_->has_lazy_background_page()) { | 352 if (extension_ && extension_->has_lazy_background_page()) { |
| 352 UMA_HISTOGRAM_TIMES("Extensions.EventPageLoadTime", | 353 UMA_HISTOGRAM_TIMES("Extensions.EventPageLoadTime", |
| 353 since_created_.Elapsed()); | 354 since_created_.Elapsed()); |
| 354 } else { | 355 } else { |
| 355 UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime", | 356 UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime", |
| 356 since_created_.Elapsed()); | 357 since_created_.Elapsed()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || | 406 extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR || |
| 406 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { | 407 extension_host_type_ == chrome::VIEW_TYPE_PANEL) { |
| 407 Close(); | 408 Close(); |
| 408 } | 409 } |
| 409 } | 410 } |
| 410 | 411 |
| 411 void ExtensionHost::OnStartDownload( | 412 void ExtensionHost::OnStartDownload( |
| 412 content::WebContents* source, content::DownloadItem* download) { | 413 content::WebContents* source, content::DownloadItem* download) { |
| 413 // If |source| is in the context of a Browser, show the DownloadShelf on that | 414 // If |source| is in the context of a Browser, show the DownloadShelf on that |
| 414 // Browser. | 415 // Browser. |
| 415 if (!GetExtensionView() || !GetExtensionView()->GetBrowser()) | 416 if (!view() || !view()->browser()) |
| 416 return; | 417 return; |
| 417 static_cast<content::WebContentsDelegate*>(GetExtensionView()->GetBrowser())-> | 418 static_cast<content::WebContentsDelegate*>(view()->browser())-> |
| 418 OnStartDownload(source, download); | 419 OnStartDownload(source, download); |
| 419 } | 420 } |
| 420 | 421 |
| 421 void ExtensionHost::WebIntentDispatch( | 422 void ExtensionHost::WebIntentDispatch( |
| 422 content::WebContents* web_contents, | 423 content::WebContents* web_contents, |
| 423 content::WebIntentsDispatcher* intents_dispatcher) { | 424 content::WebIntentsDispatcher* intents_dispatcher) { |
| 424 #if !defined(OS_ANDROID) | 425 #if !defined(OS_ANDROID) |
| 425 scoped_ptr<content::WebIntentsDispatcher> dispatcher(intents_dispatcher); | 426 scoped_ptr<content::WebIntentsDispatcher> dispatcher(intents_dispatcher); |
| 426 | 427 |
| 427 Browser* browser = GetExtensionView() ? GetExtensionView()->GetBrowser() | 428 Browser* browser = view() ? view()->browser() |
| 428 : browser::FindBrowserWithWebContents(web_contents); | 429 : browser::FindBrowserWithWebContents(web_contents); |
| 429 | 430 |
| 430 // For background scripts/pages, there will be no GetExtensionView(). In this | 431 // For background scripts/pages, there will be no view(). In this case, we |
| 431 // case, we want to treat the intent as a browser-initiated one and deliver it | 432 // want to treat the intent as a browser-initiated one and deliver it into the |
| 432 // into the current browser. It probably came from a context menu click or | 433 // current browser. It probably came from a context menu click or similar. |
| 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 Loading... |
| 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 = GetExtensionView() ? | 471 Browser* browser = view() ? view()->browser() : NULL; |
| 472 GetExtensionView()->GetBrowser() : NULL; | |
| 473 return browser ? browser->OpenURL(params) : NULL; | 472 return browser ? browser->OpenURL(params) : NULL; |
| 474 } | 473 } |
| 475 default: | 474 default: |
| 476 return NULL; | 475 return NULL; |
| 477 } | 476 } |
| 478 } | 477 } |
| 479 | 478 |
| 480 bool ExtensionHost::PreHandleKeyboardEvent(WebContents* source, | 479 bool ExtensionHost::PreHandleKeyboardEvent(WebContents* source, |
| 481 const NativeWebKeyboardEvent& event, | 480 const NativeWebKeyboardEvent& event, |
| 482 bool* is_keyboard_shortcut) { | 481 bool* is_keyboard_shortcut) { |
| 483 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP && | 482 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP && |
| 484 event.type == NativeWebKeyboardEvent::RawKeyDown && | 483 event.type == NativeWebKeyboardEvent::RawKeyDown && |
| 485 event.windowsKeyCode == ui::VKEY_ESCAPE) { | 484 event.windowsKeyCode == ui::VKEY_ESCAPE) { |
| 486 DCHECK(is_keyboard_shortcut != NULL); | 485 DCHECK(is_keyboard_shortcut != NULL); |
| 487 *is_keyboard_shortcut = true; | 486 *is_keyboard_shortcut = true; |
| 488 return false; | 487 return false; |
| 489 } | 488 } |
| 490 | 489 |
| 491 // Handle higher priority browser shortcuts such as Ctrl-w. | 490 // Handle higher priority browser shortcuts such as Ctrl-w. |
| 492 Browser* browser = GetExtensionView() ? | 491 Browser* browser = view() ? view()->browser() : NULL; |
| 493 GetExtensionView()->GetBrowser() : NULL; | |
| 494 if (browser) | 492 if (browser) |
| 495 return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut); | 493 return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut); |
| 496 | 494 |
| 497 *is_keyboard_shortcut = false; | 495 *is_keyboard_shortcut = false; |
| 498 return false; | 496 return false; |
| 499 } | 497 } |
| 500 | 498 |
| 501 void ExtensionHost::HandleKeyboardEvent(WebContents* source, | 499 void ExtensionHost::HandleKeyboardEvent(WebContents* source, |
| 502 const NativeWebKeyboardEvent& event) { | 500 const NativeWebKeyboardEvent& event) { |
| 503 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP) { | 501 if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 void ExtensionHost::OnDecrementLazyKeepaliveCount() { | 543 void ExtensionHost::OnDecrementLazyKeepaliveCount() { |
| 546 ExtensionProcessManager* pm = | 544 ExtensionProcessManager* pm = |
| 547 ExtensionSystem::Get(profile_)->process_manager(); | 545 ExtensionSystem::Get(profile_)->process_manager(); |
| 548 if (pm) | 546 if (pm) |
| 549 pm->DecrementLazyKeepaliveCount(extension()); | 547 pm->DecrementLazyKeepaliveCount(extension()); |
| 550 } | 548 } |
| 551 | 549 |
| 552 void ExtensionHost::UnhandledKeyboardEvent( | 550 void ExtensionHost::UnhandledKeyboardEvent( |
| 553 WebContents* source, | 551 WebContents* source, |
| 554 const content::NativeWebKeyboardEvent& event) { | 552 const content::NativeWebKeyboardEvent& event) { |
| 555 Browser* browser = GetExtensionView() ? | 553 Browser* browser = view() ? view()->browser() : NULL; |
| 556 GetExtensionView()->GetBrowser() : NULL; | |
| 557 if (browser) { | 554 if (browser) { |
| 558 // Handle lower priority browser shortcuts such as Ctrl-f. | 555 // Handle lower priority browser shortcuts such as Ctrl-f. |
| 559 return browser->HandleKeyboardEvent(source, event); | 556 return browser->HandleKeyboardEvent(source, event); |
| 560 } else { | 557 } else { |
| 561 #if defined(TOOLKIT_VIEWS) | 558 #if defined(TOOLKIT_VIEWS) |
| 562 // In case there's no Browser (e.g. for dialogs), pass it to | 559 // In case there's no Browser (e.g. for dialogs), pass it to |
| 563 // ExtensionViewViews to handle acceleratos. The view's FocusManager does | 560 // ExtensionViewViews to handle acceleratos. The view's FocusManager does |
| 564 // not know anything about Browser accelerators, but might know others such | 561 // not know anything about Browser accelerators, but might know others such |
| 565 // as Ash's. | 562 // as Ash's. |
| 566 if (GetExtensionView()) | 563 if (view()) |
| 567 GetExtensionView()->HandleKeyboardEvent(event); | 564 view()->HandleKeyboardEvent(event); |
| 568 #endif | 565 #endif |
| 569 } | 566 } |
| 570 } | 567 } |
| 571 | 568 |
| 572 void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { | 569 void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { |
| 573 render_view_host_ = render_view_host; | 570 render_view_host_ = render_view_host; |
| 574 | 571 |
| 575 if (GetExtensionView()) | 572 if (view()) |
| 576 GetExtensionView()->RenderViewCreated(); | 573 view()->RenderViewCreated(); |
| 577 | 574 |
| 578 // If the host is bound to a window, then extract its id. Extensions hosted | 575 // If the host is bound to a window, then extract its id. Extensions hosted |
| 579 // in ExternalTabContainer objects may not have an associated window. | 576 // in ExternalTabContainer objects may not have an associated window. |
| 580 extensions::WindowController* window = GetExtensionWindowController(); | 577 extensions::WindowController* window = GetExtensionWindowController(); |
| 581 if (window) { | 578 if (window) { |
| 582 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( | 579 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( |
| 583 render_view_host->GetRoutingID(), window->GetWindowId())); | 580 render_view_host->GetRoutingID(), window->GetWindowId())); |
| 584 } | 581 } |
| 585 } | 582 } |
| 586 | 583 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 } | 634 } |
| 638 | 635 |
| 639 void ExtensionHost::RenderViewReady() { | 636 void ExtensionHost::RenderViewReady() { |
| 640 content::NotificationService::current()->Notify( | 637 content::NotificationService::current()->Notify( |
| 641 chrome::NOTIFICATION_EXTENSION_HOST_CREATED, | 638 chrome::NOTIFICATION_EXTENSION_HOST_CREATED, |
| 642 content::Source<Profile>(profile_), | 639 content::Source<Profile>(profile_), |
| 643 content::Details<ExtensionHost>(this)); | 640 content::Details<ExtensionHost>(this)); |
| 644 } | 641 } |
| 645 | 642 |
| 646 } // namespace extensions | 643 } // namespace extensions |
| OLD | NEW |