1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_manager.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/browser_context.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_frame_host.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/site_instance.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h" 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/web_contents_user_data.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/renderer_preferences.h" 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/common/url_constants.h" 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_host.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/notification_types.h" 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/process_manager_delegate.h" 364ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "extensions/browser/process_manager_observer.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/browser/view_type_utils.h" 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/constants.h" 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h" 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h" 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/one_shot_event.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::BrowserContext; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::SiteInstance; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class RenderViewHostDestructionObserver; 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY( 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::RenderViewHostDestructionObserver); 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The time to delay between an extension becoming idle and 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// sending a ShouldSuspend message. 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Note: Must be sufficiently larger (e.g. 2x) than 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// kKeepaliveThrottleIntervalInSeconds in ppapi/proxy/plugin_globals. 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned g_event_page_idle_time_msec = 10000; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The time to delay between sending a ShouldSuspend message and 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// sending a Suspend message. 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned g_event_page_suspending_time_msec = 5000; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionID(RenderViewHost* render_view_host) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This works for both apps and extensions because the site has been 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // normalized to the extension URL for hosted apps. 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch content::SiteInstance* site_instance = render_view_host->GetSiteInstance(); 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!site_instance) 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return std::string(); 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const GURL& site_url = site_instance->GetSiteURL(); 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!site_url.SchemeIs(kExtensionScheme) && 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !site_url.SchemeIs(content::kGuestScheme)) 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return site_url.host(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string GetExtensionIDFromFrame( 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderFrameHost* render_frame_host) { 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This works for both apps and extensions because the site has been 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // normalized to the extension URL for apps. 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!render_frame_host->GetSiteInstance()) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return std::string(); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return render_frame_host->GetSiteInstance()->GetSiteURL().host(); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsFrameInExtensionHost(ExtensionHost* extension_host, 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderFrameHost* render_frame_host) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WebContents::FromRenderFrameHost(render_frame_host) == 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_host->host_contents(); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void OnRenderViewHostUnregistered(BrowserContext* context, 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RenderViewHost* render_view_host) { 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::NotificationService::current()->Notify( 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED, 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(context), 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::Details<RenderViewHost>(render_view_host)); 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incognito profiles use this process manager. It is mostly a shim that decides 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// whether to fall back on the original profile's ProcessManager based 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on whether a given extension uses "split" or "spanning" incognito behavior. 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class IncognitoProcessManager : public ProcessManager { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IncognitoProcessManager(BrowserContext* incognito_context, 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* original_context, 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessManager* original_manager, 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry); 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~IncognitoProcessManager() {} 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool CreateBackgroundHost(const Extension* extension, 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const GURL& url) OVERRIDE; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual SiteInstance* GetSiteInstanceForURL(const GURL& url) OVERRIDE; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ProcessManager* original_manager_; 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IncognitoProcessManager); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void CreateBackgroundHostForExtensionLoad( 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ProcessManager* manager, const Extension* extension) { 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "CreateBackgroundHostForExtensionLoad"; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BackgroundInfo::HasPersistentBackgroundPage(extension)) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager->CreateBackgroundHost(extension, 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BackgroundInfo::GetBackgroundURL(extension)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class RenderViewHostDestructionObserver 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : public content::WebContentsObserver, 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public content::WebContentsUserData<RenderViewHostDestructionObserver> { 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public: 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual ~RenderViewHostDestructionObserver() {} 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private: 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) explicit RenderViewHostDestructionObserver(WebContents* web_contents) 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : WebContentsObserver(web_contents) { 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* context = web_contents->GetBrowserContext(); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process_manager_ = ExtensionSystem::Get(context)->process_manager(); 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) friend class content::WebContentsUserData<RenderViewHostDestructionObserver>; 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // content::WebContentsObserver overrides. 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE { 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) process_manager_->UnregisterRenderViewHost(render_view_host); 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ProcessManager* process_manager_; 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver); 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct ProcessManager::BackgroundPageData { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The count of things keeping the lazy background page alive. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lazy_keepalive_count; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Tracks if an impulse event has occured since the last polling check. 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool keepalive_impulse; 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool previous_keepalive_impulse; 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // True if the page responded to the ShouldSuspend message and is currently 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatching the suspend event. During this time any events that arrive will 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cancel the suspend process and an onSuspendCanceled event will be 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dispatched to the page. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_closing; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Stores the value of the incremented 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // ProcessManager::last_background_close_sequence_id_ whenever the extension 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // is active. A copy of the ID is also passed in the callbacks and IPC 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // messages leading up to CloseLazyBackgroundPageNow. The process is aborted 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // if the IDs ever differ due to new activity. 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 close_sequence_id; 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keeps track of when this page was last suspended. Used for perf metrics. 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) linked_ptr<base::ElapsedTimer> since_suspended; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackgroundPageData() 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : lazy_keepalive_count(0), 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) keepalive_impulse(false), 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) previous_keepalive_impulse(false), 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch is_closing(false), 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch close_sequence_id(0) {} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ProcessManager 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProcessManager* ProcessManager::Create(BrowserContext* context) { 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get(); 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (client->IsGuestSession(context)) { 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // In the guest session, there is a single off-the-record context. Unlike 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // a regular incognito mode, background pages of extensions must be 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // created regardless of whether extensions use "spanning" or "split" 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // incognito behavior. 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* original_context = client->GetOriginalContext(context); 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new ProcessManager(context, original_context, extension_registry); 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (context->IsOffTheRecord()) { 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* original_context = client->GetOriginalContext(context); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ProcessManager* original_manager = 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ExtensionSystem::Get(original_context)->process_manager(); 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new IncognitoProcessManager( 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context, original_context, original_manager, extension_registry); 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new ProcessManager(context, context, extension_registry); 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ProcessManager* ProcessManager::CreateForTesting( 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserContext* context, 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry) { 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!context->IsOffTheRecord()); 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new ProcessManager(context, context, extension_registry); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ProcessManager* ProcessManager::CreateIncognitoForTesting( 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* incognito_context, 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* original_context, 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessManager* original_manager, 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry) { 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(incognito_context->IsOffTheRecord()); 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!original_context->IsOffTheRecord()); 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new IncognitoProcessManager(incognito_context, 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) original_context, 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) original_manager, 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry); 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProcessManager::ProcessManager(BrowserContext* context, 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserContext* original_context, 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry) 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : site_instance_(SiteInstance::Create(context)), 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_(extension_registry), 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch startup_background_hosts_created_(false), 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch devtools_callback_(base::Bind(&ProcessManager::OnDevToolsStateChanged, 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))), 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_background_close_sequence_id_(0), 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_(this) { 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // ExtensionRegistry is shared between incognito and regular contexts. 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(original_context, extension_registry_->browser_context()); 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registrar_.Add(this, 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context)); 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registrar_.Add(this, 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context)); 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registrar_.Add(this, 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context)); 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registrar_.Add(this, 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(context)); 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registrar_.Add(this, 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(context)); 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllSources()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_CONNECTED, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::DevToolsAgentHost::AddAgentStateCallback(devtools_callback_); 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnKeepaliveImpulseCheck(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ProcessManager::~ProcessManager() { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseBackgroundHosts(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(background_hosts_.empty()); 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::DevToolsAgentHost::RemoveAgentStateCallback(devtools_callback_); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const ProcessManager::ViewSet ProcessManager::GetAllViews() const { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewSet result; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionRenderViews::const_iterator iter = 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_extension_views_.begin(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != all_extension_views_.end(); ++iter) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.insert(iter->first); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3004ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid ProcessManager::AddObserver(ProcessManagerObserver* observer) { 3014ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch observer_list_.AddObserver(observer); 3024ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch} 3034ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 3044ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid ProcessManager::RemoveObserver(ProcessManagerObserver* observer) { 3054ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch observer_list_.RemoveObserver(observer); 3064ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch} 3074ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ProcessManager::CreateBackgroundHost(const Extension* extension, 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const GURL& url) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hosted apps are taken care of from BackgroundContentsService. Ignore them 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension->is_hosted_app()) 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Don't create hosts if the embedder doesn't allow it. 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessManagerDelegate* delegate = 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't create multiple background hosts for an extension. 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GetBackgroundHostForExtension(extension->id())) 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; // TODO(kalman): return false here? It might break things... 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionHost(extension, GetSiteInstanceForURL(url), url, 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->CreateRenderViewSoon(); 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnBackgroundHostCreated(host); 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ExtensionHost* ProcessManager::GetBackgroundHostForExtension( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionHostSet::iterator iter = background_hosts_.begin(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != background_hosts_.end(); ++iter) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = *iter; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host->extension_id() == extension_id) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::set<RenderViewHost*> ProcessManager::GetRenderViewHostsForExtension( 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extension_id) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<RenderViewHost*> result; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SiteInstance* site_instance = GetSiteInstanceForURL( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::GetBaseURLFromExtensionId(extension_id)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!site_instance) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gather up all the views for that site. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionRenderViews::iterator view = all_extension_views_.begin(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view != all_extension_views_.end(); ++view) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view->first->GetSiteInstance() == site_instance) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.insert(view->first); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const Extension* ProcessManager::GetExtensionForRenderViewHost( 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RenderViewHost* render_view_host) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!render_view_host->GetSiteInstance()) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return extension_registry_->enabled_extensions().GetByID( 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetExtensionID(render_view_host)); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::UnregisterRenderViewHost( 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionRenderViews::iterator view = 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_extension_views_.find(render_view_host); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (view == all_extension_views_.end()) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnRenderViewHostUnregistered(GetBrowserContext(), render_view_host); 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ViewType view_type = view->second; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_extension_views_.erase(view); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keepalive count, balanced in RegisterRenderViewHost. 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (view_type != VIEW_TYPE_INVALID && 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = GetExtensionForRenderViewHost( 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementLazyKeepaliveCount(extension); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ProcessManager::RegisterRenderViewHost(RenderViewHost* render_view_host) { 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = GetExtensionForRenderViewHost( 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_view_host); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) all_extension_views_[render_view_host] = GetViewType(web_contents); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep the lazy background page alive as long as any non-background-page 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension views are visible. Keepalive count balanced in 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnregisterRenderViewHost. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementLazyKeepaliveCountForView(render_view_host); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SiteInstance* ProcessManager::GetSiteInstanceForURL(const GURL& url) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return site_instance_->GetRelatedSiteInstance(url); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (host && background_page_data_[extension_id].is_closing); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ProcessManager::GetLazyKeepaliveCount(const Extension* extension) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return background_page_data_[extension->id()].lazy_keepalive_count; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProcessManager::IncrementLazyKeepaliveCount(const Extension* extension) { 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int& count = background_page_data_[extension->id()].lazy_keepalive_count; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (++count == 1) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnLazyBackgroundPageActive(extension->id()); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DecrementLazyKeepaliveCount(extension->id()); 438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProcessManager::DecrementLazyKeepaliveCount( 441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& extension_id) { 442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int& count = background_page_data_[extension_id].lazy_keepalive_count; 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(count > 0 || 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !extension_registry_->enabled_extensions().Contains(extension_id)); 4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If we reach a zero keepalive count when the lazy background page is about 4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // to be closed, incrementing close_sequence_id will cancel the close 4484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // sequence and cause the background page to linger. So check is_closing 4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // before initiating another close sequence. 450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (--count == 0 && !background_page_data_[extension_id].is_closing) { 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch background_page_data_[extension_id].close_sequence_id = 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++last_background_close_sequence_id_; 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, 456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_id, 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_background_close_sequence_id_), 4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::IncrementLazyKeepaliveCountForView( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents::FromRenderViewHost(render_view_host); 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ViewType view_type = GetViewType(web_contents); 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (view_type != VIEW_TYPE_INVALID && 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = GetExtensionForRenderViewHost( 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementLazyKeepaliveCount(extension); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This implementation layers on top of the keepalive count. An impulse sets 478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// a per extension flag. On a regular interval that flag is checked. Changes 479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// from the flag not being set to set cause an IncrementLazyKeepaliveCount. 480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProcessManager::KeepaliveImpulse(const Extension* extension) { 481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BackgroundPageData& bd = background_page_data_[extension->id()]; 485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!bd.keepalive_impulse) { 487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bd.keepalive_impulse = true; 488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!bd.previous_keepalive_impulse) { 489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IncrementLazyKeepaliveCount(extension); 490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!keepalive_impulse_callback_for_testing_.is_null()) { 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly = 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keepalive_impulse_callback_for_testing_; 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_may_clear_callbacks_reentrantly.Run(extension->id()); 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 50003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// static 50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ProcessManager::OnKeepaliveFromPlugin(int render_process_id, 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int render_frame_id, 50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& extension_id) { 50403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::RenderFrameHost* render_frame_host = 50503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::RenderFrameHost::FromID(render_process_id, render_frame_id); 50603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!render_frame_host) 50703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 50903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::SiteInstance* site_instance = render_frame_host->GetSiteInstance(); 51003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!site_instance) 51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 51203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 51303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BrowserContext* browser_context = site_instance->GetBrowserContext(); 51403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const Extension* extension = 51503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID( 51603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) extension_id); 51703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!extension) 51803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 51903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 52003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessManager* pm = ExtensionSystem::Get(browser_context)->process_manager(); 52103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!pm) 52203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 52303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 52403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) pm->KeepaliveImpulse(extension); 52503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 52603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// have been made for at least g_event_page_idle_time_msec. In the best case an 529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// impulse was made just before being cleared, and the decrement will occur 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// g_event_page_idle_time_msec later, causing a 2 * g_event_page_idle_time_msec 5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// total time for extension to be shut down based on impulses. Worst case is 5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// an impulse just after a clear, adding one check cycle and resulting in 3x 5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// total time. 534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ProcessManager::OnKeepaliveImpulseCheck() { 535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (BackgroundPageDataMap::iterator i = background_page_data_.begin(); 536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i != background_page_data_.end(); 537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ++i) { 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i->second.previous_keepalive_impulse && !i->second.keepalive_impulse) { 539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DecrementLazyKeepaliveCount(i->first); 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!keepalive_impulse_decrement_callback_for_testing_.is_null()) { 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly = 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keepalive_impulse_decrement_callback_for_testing_; 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_may_clear_callbacks_reentrantly.Run(i->first); 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i->second.previous_keepalive_impulse = i->second.keepalive_impulse; 548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i->second.keepalive_impulse = false; 549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // OnKeepaliveImpulseCheck() is always called in constructor, but in unit 552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // tests there will be no message loop. In that event don't schedule tasks. 553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (base::MessageLoop::current()) { 554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FROM_HERE, 556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&ProcessManager::OnKeepaliveImpulseCheck, 557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); 559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 sequence_id) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host && !background_page_data_[extension_id].is_closing && 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sequence_id == background_page_data_[extension_id].close_sequence_id) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the renderer we are about to close. This is a simple ping that the 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer will respond to. The purpose is to control sequencing: if the 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension remains idle until the renderer responds with an ACK, then we 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know that the extension process is ready to shut down. If our 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // close_sequence_id has already changed, then we would ignore the 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ShouldSuspendAck, so we don't send the ping. 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host->render_view_host()->Send(new ExtensionMsg_ShouldSuspend( 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id, sequence_id)); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnLazyBackgroundPageActive( 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!background_page_data_[extension_id].is_closing) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the current close sequence by changing the close_sequence_id, 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which causes us to ignore the next ShouldSuspendAck. 583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch background_page_data_[extension_id].close_sequence_id = 584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++last_background_close_sequence_id_; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnShouldSuspendAck(const std::string& extension_id, 589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 sequence_id) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host && 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sequence_id == background_page_data_[extension_id].close_sequence_id) { 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host->render_view_host()->Send(new ExtensionMsg_Suspend(extension_id)); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnSuspendAck(const std::string& extension_id) { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) background_page_data_[extension_id].is_closing = true; 599116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 sequence_id = background_page_data_[extension_id].close_sequence_id; 60090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&ProcessManager::CloseLazyBackgroundPageNow, 6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_id, 6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sequence_id), 6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta::FromMilliseconds(g_event_page_suspending_time_msec)); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id, 610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 sequence_id) { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host && 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sequence_id == background_page_data_[extension_id].close_sequence_id) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseBackgroundHost(host); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProcessManager::OnNetworkRequestStarted( 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderFrameHost* render_frame_host) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension( 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetExtensionIDFromFrame(render_frame_host)); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (host && IsFrameInExtensionHost(host, render_frame_host)) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementLazyKeepaliveCount(host->extension()); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProcessManager::OnNetworkRequestDone( 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderFrameHost* render_frame_host) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension( 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetExtensionIDFromFrame(render_frame_host)); 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (host && IsFrameInExtensionHost(host, render_frame_host)) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementLazyKeepaliveCount(host->extension()); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::CancelSuspend(const Extension* extension) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool& is_closing = background_page_data_[extension->id()].is_closing; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = GetBackgroundHostForExtension(extension->id()); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host && is_closing) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_closing = false; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->render_view_host()->Send( 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ExtensionMsg_CancelSuspend(extension->id())); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This increment / decrement is to simulate an instantaneous event. This 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has the effect of invalidating close_sequence_id, preventing any in 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // progress closes from completing and starting a new close process if 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementLazyKeepaliveCount(extension); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecrementLazyKeepaliveCount(extension); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProcessManager::CloseBackgroundHosts() { 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (ExtensionHostSet::iterator iter = background_hosts_.begin(); 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) iter != background_hosts_.end();) { 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionHostSet::iterator current = iter++; 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete *current; 6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)content::BrowserContext* ProcessManager::GetBrowserContext() const { 661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return site_instance_->GetBrowserContext(); 662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProcessManager::SetKeepaliveImpulseCallbackForTesting( 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ImpulseCallbackForTesting& callback) { 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keepalive_impulse_callback_for_testing_ = callback; 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting( 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ImpulseCallbackForTesting& callback) { 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keepalive_impulse_decrement_callback_for_testing_ = callback; 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProcessManager::SetEventPageIdleTimeForTesting(unsigned idle_time_msec) { 6761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK_GT(idle_time_msec, 0u); // OnKeepaliveImpulseCheck requires non zero. 6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_event_page_idle_time_msec = idle_time_msec; 6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 6811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ProcessManager::SetEventPageSuspendingTimeForTesting( 6821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned suspending_time_msec) { 6831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_event_page_suspending_time_msec = suspending_time_msec; 6841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::Observe(int type, 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationSource& source, 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationDetails& details) { 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (type) { 6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED: { 6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(jamescook): Convert this to use ExtensionSystem::ready() instead 6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // of a notification. 6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MaybeCreateStartupBackgroundHosts(); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* context = content::Source<BrowserContext>(source).ptr(); 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(context); 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (system->ready().is_signaled()) { 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The extension system is ready, so create the background host. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const Extension>(details).ptr(); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBackgroundHostForExtensionLoad(this, extension); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Details<UnloadedExtensionInfo>(details)->extension; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionHostSet::iterator iter = background_hosts_.begin(); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != background_hosts_.end(); ++iter) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = *iter; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host->extension_id() == extension->id()) { 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseBackgroundHost(host); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 72068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UnregisterExtension(extension->id()); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (background_hosts_.erase(host)) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClearBackgroundPageData(host->extension()->id()); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) background_page_data_[host->extension()->id()].since_suspended.reset( 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new base::ElapsedTimer()); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (host->extension_host_type() == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseBackgroundHost(host); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We get this notification both for new WebContents and when one 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has its RenderViewHost replaced (e.g. when a user does a cross-site 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // navigation away from an extension URL). For the replaced case, we must 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unregister the old RVH so it doesn't count as an active view that would 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // keep the event page alive. 7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebContents* contents = content::Source<WebContents>(source).ptr(); 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (contents->GetBrowserContext() != GetBrowserContext()) 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) typedef std::pair<RenderViewHost*, RenderViewHost*> RVHPair; 7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RVHPair* switched_details = content::Details<RVHPair>(details).ptr(); 7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (switched_details->first) 7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UnregisterRenderViewHost(switched_details->first); 7568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The above will unregister a RVH when it gets swapped out with a new 7588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // one. However we need to watch the WebContents to know when a RVH is 7598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // deleted because the WebContents has gone away. 7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (RegisterRenderViewHost(switched_details->second)) { 7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RenderViewHostDestructionObserver::CreateForWebContents(contents); 7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_WEB_CONTENTS_CONNECTED: { 7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebContents* contents = content::Source<WebContents>(source).ptr(); 768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (contents->GetBrowserContext() != GetBrowserContext()) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = GetExtensionForRenderViewHost( 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents->GetRenderViewHost()); 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RegisterRenderViewHost is called too early (before the process is 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // available), so we need to wait until now to notify. 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::current()->Notify( 7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSION_VIEW_REGISTERED, 779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(GetBrowserContext()), 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<RenderViewHost>(contents->GetRenderViewHost())); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 789f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnDevToolsStateChanged( 790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::DevToolsAgentHost* agent_host, 791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool attached) { 7926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) WebContents* web_contents = agent_host->GetWebContents(); 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Ignore unrelated notifications. 7946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!web_contents || web_contents->GetBrowserContext() != GetBrowserContext()) 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 7966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (GetViewType(web_contents) != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 7986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const Extension* extension = 7996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetExtensionForRenderViewHost(web_contents->GetRenderViewHost()); 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!extension) 801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (attached) { 803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Keep the lazy background page alive while it's being inspected. 804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CancelSuspend(extension); 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IncrementLazyKeepaliveCount(extension); 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DecrementLazyKeepaliveCount(extension); 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProcessManager::MaybeCreateStartupBackgroundHosts() { 8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (startup_background_hosts_created_) 813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The embedder might disallow background pages entirely. 8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessManagerDelegate* delegate = 8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionsBrowserClient::Get()->GetProcessManagerDelegate(); 8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (delegate && !delegate->IsBackgroundPageAllowed(GetBrowserContext())) 8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The embedder might want to defer background page loading. For example, 8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Chrome defers background page loading when it is launched to show the app 8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // list, then triggers a load later when a browser window opens. 8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (delegate && 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate->DeferCreatingStartupBackgroundHosts(GetBrowserContext())) 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CreateStartupBackgroundHosts(); 829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) startup_background_hosts_created_ = true; 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Background pages should only be loaded once. To prevent any further loads 832b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // occurring, we remove the notification listeners. 833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* original_context = 834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionsBrowserClient::Get()->GetOriginalContext(GetBrowserContext()); 835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (registrar_.IsRegistered( 836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this, 8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context))) { 839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) registrar_.Remove(this, 8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context)); 842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ProcessManager::CreateStartupBackgroundHosts() { 8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!startup_background_hosts_created_); 8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ExtensionSet& enabled_extensions = 8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_->enabled_extensions(); 8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (ExtensionSet::const_iterator extension = enabled_extensions.begin(); 8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension != enabled_extensions.end(); 8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++extension) { 8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CreateBackgroundHostForExtensionLoad(this, extension->get()); 8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FOR_EACH_OBSERVER(ProcessManagerObserver, 8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) observer_list_, 8561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnBackgroundHostStartup(extension->get())); 857f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 858f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) { 861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(GetBrowserContext(), host->browser_context()); 862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) background_hosts_.insert(host); 863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) { 865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) linked_ptr<base::ElapsedTimer> since_suspended( 866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) background_page_data_[host->extension()->id()]. 867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) since_suspended.release()); 868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (since_suspended.get()) { 869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime", 870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) since_suspended->Elapsed()); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::CloseBackgroundHost(ExtensionHost* host) { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(host->extension_host_type() == 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete host; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |host| should deregister itself from our structures. 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(background_hosts_.find(host) == background_hosts_.end()); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::UnregisterExtension(const std::string& extension_id) { 88468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // The lazy_keepalive_count may be greater than zero at this point because 88568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // RenderViewHosts are still alive. During extension reloading, they will 88668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // decrement the lazy_keepalive_count to negative for the new extension 88768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // instance when they are destroyed. Since we are erasing the background page 88868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // data for the unloaded extension, unregister the RenderViewHosts too. 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* context = GetBrowserContext(); 89068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (ExtensionRenderViews::iterator it = all_extension_views_.begin(); 89168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != all_extension_views_.end(); ) { 89268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (GetExtensionID(it->first) == extension_id) { 893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnRenderViewHostUnregistered(context, it->first); 89468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) all_extension_views_.erase(it++); 89568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 89668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++it; 89768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 89868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 89968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 90068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) background_page_data_.erase(extension_id); 90168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 90268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) { 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) background_page_data_.erase(extension_id); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Re-register all RenderViews for this extension. We do this to restore 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the lazy_keepalive_count (if any) to properly reflect the number of open 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views. 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionRenderViews::const_iterator it = all_extension_views_.begin(); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != all_extension_views_.end(); ++it) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetExtensionID(it->first) == extension_id) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementLazyKeepaliveCountForView(it->first); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// IncognitoProcessManager 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IncognitoProcessManager::IncognitoProcessManager( 921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserContext* incognito_context, 922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContext* original_context, 9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProcessManager* original_manager, 9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionRegistry* extension_registry) 9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : ProcessManager(incognito_context, original_context, extension_registry), 926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) original_manager_(original_manager) { 927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(incognito_context->IsOffTheRecord()); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 929f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The original profile will have its own ProcessManager to 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // load the background pages of the spanning extensions. This process 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // manager need only worry about the split mode extensions, which is handled 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the NOTIFICATION_BROWSER_WINDOW_READY notification handler. 9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registrar_.Remove(this, 9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Source<BrowserContext>(original_context)); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension, 939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const GURL& url) { 940f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IncognitoInfo::IsSplitMode(extension)) { 9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled( 9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension->id(), GetBrowserContext())) 943f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ProcessManager::CreateBackgroundHost(extension, url); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing. If an extension is spanning, then its original-profile 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // background page is shared with incognito, so we don't create another. 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SiteInstance* IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) { 9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension = 9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url); 9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension && !IncognitoInfo::IsSplitMode(extension)) 9555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return original_manager_->GetSiteInstanceForURL(url); 9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ProcessManager::GetSiteInstanceForURL(url); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 961