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 |