Chromium Code Reviews| 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "chrome/browser/extensions/extension_process_manager.h" | 7 #include "chrome/browser/extensions/extension_process_manager.h" |
| 8 | 8 |
| 9 #include "chrome/browser/extensions/extension_event_router.h" | 9 #include "chrome/browser/extensions/extension_event_router.h" |
| 10 #include "chrome/browser/ui/browser_window.h" | 10 #include "chrome/browser/ui/browser_window.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 116 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
| 117 content::Source<Profile>(original_profile)); | 117 content::Source<Profile>(original_profile)); |
| 118 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 118 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 119 content::Source<Profile>(original_profile)); | 119 content::Source<Profile>(original_profile)); |
| 120 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 120 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 121 content::Source<Profile>(original_profile)); | 121 content::Source<Profile>(original_profile)); |
| 122 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 122 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 123 content::Source<Profile>(profile)); | 123 content::Source<Profile>(profile)); |
| 124 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, | 124 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, |
| 125 content::Source<Profile>(profile)); | 125 content::Source<Profile>(profile)); |
| 126 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, | |
| 127 content::NotificationService::AllSources()); | |
| 126 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, | 128 registrar_.Add(this, content::NOTIFICATION_APP_TERMINATING, |
| 127 content::NotificationService::AllSources()); | 129 content::NotificationService::AllSources()); |
| 128 } | 130 } |
| 129 | 131 |
| 130 ExtensionProcessManager::~ExtensionProcessManager() { | 132 ExtensionProcessManager::~ExtensionProcessManager() { |
| 131 CloseBackgroundHosts(); | 133 CloseBackgroundHosts(); |
| 132 DCHECK(background_hosts_.empty()); | 134 DCHECK(background_hosts_.empty()); |
| 133 } | 135 } |
| 134 | 136 |
| 135 ExtensionHost* ExtensionProcessManager::CreateShellHost( | 137 ExtensionHost* ExtensionProcessManager::CreateShellHost( |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 | 258 |
| 257 ExtensionHost* ExtensionProcessManager::GetBackgroundHostForExtension( | 259 ExtensionHost* ExtensionProcessManager::GetBackgroundHostForExtension( |
| 258 const std::string& extension_id) { | 260 const std::string& extension_id) { |
| 259 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); | 261 for (ExtensionHostSet::iterator iter = background_hosts_.begin(); |
| 260 iter != background_hosts_.end(); ++iter) { | 262 iter != background_hosts_.end(); ++iter) { |
| 261 ExtensionHost* host = *iter; | 263 ExtensionHost* host = *iter; |
| 262 if (host->extension_id() == extension_id) | 264 if (host->extension_id() == extension_id) |
| 263 return host; | 265 return host; |
| 264 } | 266 } |
| 265 return NULL; | 267 return NULL; |
| 266 | |
| 267 } | 268 } |
| 268 | 269 |
| 269 std::set<RenderViewHost*> | 270 std::set<RenderViewHost*> |
| 270 ExtensionProcessManager::GetRenderViewHostsForExtension( | 271 ExtensionProcessManager::GetRenderViewHostsForExtension( |
| 271 const std::string& extension_id) { | 272 const std::string& extension_id) { |
| 272 std::set<RenderViewHost*> result; | 273 std::set<RenderViewHost*> result; |
| 273 | 274 |
| 274 SiteInstance* site_instance = GetSiteInstanceForURL( | 275 SiteInstance* site_instance = GetSiteInstanceForURL( |
| 275 Extension::GetBaseURLFromExtensionId(extension_id)); | 276 Extension::GetBaseURLFromExtensionId(extension_id)); |
| 276 if (!site_instance) | 277 if (!site_instance) |
| 277 return result; | 278 return result; |
| 278 | 279 |
| 279 // Gather up all the views for that site. | 280 // Gather up all the views for that site. |
| 280 for (RenderViewHostSet::iterator view = all_extension_views_.begin(); | 281 for (ExtensionRenderViews::iterator view = all_extension_views_.begin(); |
| 281 view != all_extension_views_.end(); ++view) { | 282 view != all_extension_views_.end(); ++view) { |
| 282 if ((*view)->site_instance() == site_instance) | 283 if (view->first->site_instance() == site_instance) |
| 283 result.insert(*view); | 284 result.insert(view->first); |
| 284 } | 285 } |
| 285 | 286 |
| 286 return result; | 287 return result; |
| 287 } | 288 } |
| 288 | 289 |
| 289 void ExtensionProcessManager::RegisterRenderViewHost( | 290 void ExtensionProcessManager::RegisterRenderViewHost( |
| 290 RenderViewHost* render_view_host, | 291 RenderViewHost* render_view_host, |
| 291 const Extension* extension) { | 292 const Extension* extension) { |
| 292 all_extension_views_.insert(render_view_host); | 293 all_extension_views_[render_view_host] = content::VIEW_TYPE_INVALID; |
| 293 } | 294 } |
| 294 | 295 |
| 295 void ExtensionProcessManager::UnregisterRenderViewHost( | 296 void ExtensionProcessManager::UnregisterRenderViewHost( |
| 296 RenderViewHost* render_view_host) { | 297 RenderViewHost* render_view_host) { |
| 297 all_extension_views_.erase(render_view_host); | 298 ExtensionRenderViews::iterator view = |
| 299 all_extension_views_.find(render_view_host); | |
| 300 if (view == all_extension_views_.end()) | |
| 301 return; | |
| 302 | |
| 303 content::ViewType view_type = view->second; | |
| 304 all_extension_views_.erase(view); | |
| 305 | |
| 306 // Keepalive count, balanced in UpdateRegisteredRenderView. | |
| 307 if (view_type != content::VIEW_TYPE_INVALID && | |
| 308 view_type != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
| 309 const Extension* extension = | |
| 310 GetProfile()->GetExtensionService()->extensions()->GetByID( | |
| 311 render_view_host->site_instance()->GetSite().host()); | |
|
Yoyo Zhou
2012/03/02 03:10:46
Maybe a TODO: it seems like this could be a helper
Matt Perry
2012/03/02 20:25:21
Added a local helper.
| |
| 312 if (extension) | |
| 313 DecrementLazyKeepaliveCount(extension); | |
| 314 } | |
| 298 } | 315 } |
| 299 | 316 |
| 300 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL( | 317 void ExtensionProcessManager::UpdateRegisteredRenderView( |
| 301 const GURL& url) { | 318 RenderViewHost* render_view_host) { |
| 319 ExtensionRenderViews::iterator view = | |
| 320 all_extension_views_.find(render_view_host); | |
| 321 if (view == all_extension_views_.end()) | |
| 322 return; | |
| 323 | |
| 324 view->second = render_view_host->delegate()->GetRenderViewType(); | |
| 325 | |
| 326 // Keep the lazy background page alive as long as any non-background-page | |
| 327 // extension views are visible. Keepalive count balanced in | |
| 328 // UnregisterRenderViewHost. | |
| 329 if (view->second != content::VIEW_TYPE_INVALID && | |
| 330 view->second != chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
| 331 const Extension* extension = | |
| 332 GetProfile()->GetExtensionService()->extensions()->GetByID( | |
| 333 render_view_host->site_instance()->GetSite().host()); | |
| 334 if (extension) | |
| 335 IncrementLazyKeepaliveCount(extension); | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { | |
| 302 return site_instance_->GetRelatedSiteInstance(url); | 340 return site_instance_->GetRelatedSiteInstance(url); |
| 303 } | 341 } |
| 304 | 342 |
| 305 bool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const { | 343 bool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const { |
| 306 return all_hosts_.find(host) != all_hosts_.end(); | 344 return all_hosts_.find(host) != all_hosts_.end(); |
| 307 } | 345 } |
| 308 | 346 |
| 309 int ExtensionProcessManager::GetLazyKeepaliveCount(const Extension* extension) { | 347 int ExtensionProcessManager::GetLazyKeepaliveCount(const Extension* extension) { |
| 310 if (extension->background_page_persists()) | 348 if (extension->background_page_persists()) |
| 311 return 0; | 349 return 0; |
| 312 | 350 |
| 313 return ::GetLazyKeepaliveCount(GetProfile(), extension); | 351 return ::GetLazyKeepaliveCount(GetProfile(), extension); |
| 314 } | 352 } |
| 315 | 353 |
| 316 int ExtensionProcessManager::IncrementLazyKeepaliveCount( | 354 int ExtensionProcessManager::IncrementLazyKeepaliveCount( |
| 317 const Extension* extension) { | 355 const Extension* extension) { |
| 318 if (extension->background_page_persists()) | 356 if (extension->background_page_persists()) |
| 319 return 0; | 357 return 0; |
| 320 | 358 |
| 321 // TODO(mpcomplete): Handle visible views changing. | |
| 322 int& count = ::GetLazyKeepaliveCount(GetProfile(), extension); | 359 int& count = ::GetLazyKeepaliveCount(GetProfile(), extension); |
| 323 if (++count == 1) | 360 if (++count == 1) |
| 324 OnLazyBackgroundPageActive(extension->id()); | 361 OnLazyBackgroundPageActive(extension->id()); |
| 325 | 362 |
| 326 return count; | 363 return count; |
| 327 } | 364 } |
| 328 | 365 |
| 329 int ExtensionProcessManager::DecrementLazyKeepaliveCount( | 366 int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
| 330 const Extension* extension) { | 367 const Extension* extension) { |
| 331 if (extension->background_page_persists()) | 368 if (extension->background_page_persists()) |
| 332 return 0; | 369 return 0; |
| 333 | 370 |
| 334 int& count = ::GetLazyKeepaliveCount(GetProfile(), extension); | 371 int& count = ::GetLazyKeepaliveCount(GetProfile(), extension); |
| 335 DCHECK(count > 0); | 372 DCHECK(count > 0); |
| 336 if (--count == 0) | 373 if (--count == 0) |
| 337 OnLazyBackgroundPageIdle(extension->id()); | 374 OnLazyBackgroundPageIdle(extension->id()); |
| 338 | 375 |
| 339 return count; | 376 return count; |
| 340 } | 377 } |
| 341 | 378 |
| 342 void ExtensionProcessManager::OnLazyBackgroundPageIdle( | 379 void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
| 343 const std::string& extension_id) { | 380 const std::string& extension_id) { |
| 344 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 381 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 345 if (host && !HasVisibleViews(extension_id)) | 382 if (host) |
| 346 host->SendShouldClose(); | 383 host->SendShouldClose(); |
| 347 } | 384 } |
| 348 | 385 |
| 349 void ExtensionProcessManager::OnLazyBackgroundPageActive( | 386 void ExtensionProcessManager::OnLazyBackgroundPageActive( |
| 350 const std::string& extension_id) { | 387 const std::string& extension_id) { |
| 351 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 388 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 352 if (host) | 389 if (host) |
| 353 host->CancelShouldClose(); | 390 host->CancelShouldClose(); |
| 354 } | 391 } |
| 355 | 392 |
| 356 void ExtensionProcessManager::OnShouldCloseAck( | 393 void ExtensionProcessManager::OnShouldCloseAck( |
| 357 const std::string& extension_id, int sequence_id) { | 394 const std::string& extension_id, int sequence_id) { |
| 358 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); | 395 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
| 359 if (host) | 396 if (host) |
| 360 host->OnShouldCloseAck(sequence_id); | 397 host->OnShouldCloseAck(sequence_id); |
| 361 } | 398 } |
| 362 | 399 |
| 363 bool ExtensionProcessManager::HasVisibleViews(const std::string& extension_id) { | 400 void ExtensionProcessManager::OnNetworkRequestStarted( |
| 364 const std::set<RenderViewHost*>& views = | 401 RenderViewHost* render_view_host) { |
| 365 GetRenderViewHostsForExtension(extension_id); | 402 ExtensionHost* host = GetBackgroundHostForExtension( |
| 366 for (std::set<RenderViewHost*>::const_iterator it = views.begin(); | 403 render_view_host->site_instance()->GetSite().host()); |
| 367 it != views.end(); ++it) { | 404 if (host) |
| 368 const RenderViewHost* host = *it; | 405 IncrementLazyKeepaliveCount(host->extension()); |
| 369 if (host->site_instance()->GetSite().host() == extension_id && | 406 } |
| 370 host->delegate()->GetRenderViewType() != | 407 |
| 371 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 408 void ExtensionProcessManager::OnNetworkRequestDone( |
| 372 return true; | 409 RenderViewHost* render_view_host) { |
| 373 } | 410 ExtensionHost* host = GetBackgroundHostForExtension( |
| 374 } | 411 render_view_host->site_instance()->GetSite().host()); |
| 375 return false; | 412 if (host) |
| 413 DecrementLazyKeepaliveCount(host->extension()); | |
| 376 } | 414 } |
| 377 | 415 |
| 378 void ExtensionProcessManager::Observe( | 416 void ExtensionProcessManager::Observe( |
| 379 int type, | 417 int type, |
| 380 const content::NotificationSource& source, | 418 const content::NotificationSource& source, |
| 381 const content::NotificationDetails& details) { | 419 const content::NotificationDetails& details) { |
| 382 switch (type) { | 420 switch (type) { |
| 383 case chrome::NOTIFICATION_EXTENSIONS_READY: { | 421 case chrome::NOTIFICATION_EXTENSIONS_READY: { |
| 384 CreateBackgroundHostsForProfileStartup(this, | 422 CreateBackgroundHostsForProfileStartup(this, |
| 385 content::Source<Profile>(source).ptr()-> | 423 content::Source<Profile>(source).ptr()-> |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 | 459 |
| 422 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: { | 460 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: { |
| 423 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); | 461 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
| 424 if (host->extension_host_type() == | 462 if (host->extension_host_type() == |
| 425 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | 463 chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
| 426 CloseBackgroundHost(host); | 464 CloseBackgroundHost(host); |
| 427 } | 465 } |
| 428 break; | 466 break; |
| 429 } | 467 } |
| 430 | 468 |
| 469 case content::NOTIFICATION_WEB_CONTENTS_CONNECTED: { | |
|
Yoyo Zhou
2012/03/02 03:10:46
Naively, it seems like this should be balanced wit
Matt Perry
2012/03/02 20:25:21
No need - UnregisterRenderViewHost cleans up our R
| |
| 470 content::WebContents* contents = | |
| 471 content::Source<content::WebContents>(source).ptr(); | |
| 472 UpdateRegisteredRenderView(contents->GetRenderViewHost()); | |
| 473 break; | |
| 474 } | |
| 475 | |
| 431 case content::NOTIFICATION_APP_TERMINATING: { | 476 case content::NOTIFICATION_APP_TERMINATING: { |
| 432 // Close background hosts when the last browser is closed so that they | 477 // Close background hosts when the last browser is closed so that they |
| 433 // have time to shutdown various objects on different threads. Our | 478 // have time to shutdown various objects on different threads. Our |
| 434 // destructor is called too late in the shutdown sequence. | 479 // destructor is called too late in the shutdown sequence. |
| 435 CloseBackgroundHosts(); | 480 CloseBackgroundHosts(); |
| 436 break; | 481 break; |
| 437 } | 482 } |
| 438 | 483 |
| 439 default: | 484 default: |
| 440 NOTREACHED(); | 485 NOTREACHED(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 if (service && service->is_ready()) | 599 if (service && service->is_ready()) |
| 555 CreateBackgroundHostsForProfileStartup(this, service->extensions()); | 600 CreateBackgroundHostsForProfileStartup(this, service->extensions()); |
| 556 } | 601 } |
| 557 break; | 602 break; |
| 558 } | 603 } |
| 559 default: | 604 default: |
| 560 ExtensionProcessManager::Observe(type, source, details); | 605 ExtensionProcessManager::Observe(type, source, details); |
| 561 break; | 606 break; |
| 562 } | 607 } |
| 563 } | 608 } |
| OLD | NEW |