process_manager.cc 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/browser/process_manager.h"
  5. #include <memory>
  6. #include <unordered_set>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/feature_list.h"
  10. #include "base/guid.h"
  11. #include "base/location.h"
  12. #include "base/logging.h"
  13. #include "base/metrics/field_trial_params.h"
  14. #include "base/metrics/histogram_macros.h"
  15. #include "base/observer_list.h"
  16. #include "base/one_shot_event.h"
  17. #include "base/strings/string_number_conversions.h"
  18. #include "base/task/single_thread_task_runner.h"
  19. #include "base/threading/thread_task_runner_handle.h"
  20. #include "base/time/time.h"
  21. #include "content/public/browser/browser_context.h"
  22. #include "content/public/browser/browser_task_traits.h"
  23. #include "content/public/browser/browser_thread.h"
  24. #include "content/public/browser/devtools_agent_host.h"
  25. #include "content/public/browser/navigation_controller.h"
  26. #include "content/public/browser/navigation_entry.h"
  27. #include "content/public/browser/notification_service.h"
  28. #include "content/public/browser/render_frame_host.h"
  29. #include "content/public/browser/render_view_host.h"
  30. #include "content/public/browser/service_worker_context.h"
  31. #include "content/public/browser/service_worker_external_request_result.h"
  32. #include "content/public/browser/site_instance.h"
  33. #include "content/public/browser/storage_partition.h"
  34. #include "content/public/browser/web_contents.h"
  35. #include "content/public/common/url_constants.h"
  36. #include "extensions/browser/extension_host.h"
  37. #include "extensions/browser/extension_registry.h"
  38. #include "extensions/browser/extension_system.h"
  39. #include "extensions/browser/extension_util.h"
  40. #include "extensions/browser/extensions_browser_client.h"
  41. #include "extensions/browser/lazy_context_id.h"
  42. #include "extensions/browser/lazy_context_task_queue.h"
  43. #include "extensions/browser/notification_types.h"
  44. #include "extensions/browser/process_manager_delegate.h"
  45. #include "extensions/browser/process_manager_factory.h"
  46. #include "extensions/browser/process_manager_observer.h"
  47. #include "extensions/browser/renderer_startup_helper.h"
  48. #include "extensions/browser/view_type_utils.h"
  49. #include "extensions/common/constants.h"
  50. #include "extensions/common/extension.h"
  51. #include "extensions/common/extension_messages.h"
  52. #include "extensions/common/manifest_handlers/background_info.h"
  53. #include "extensions/common/manifest_handlers/incognito_info.h"
  54. #include "extensions/common/mojom/renderer.mojom.h"
  55. #include "extensions/common/mojom/view_type.mojom.h"
  56. using content::BrowserContext;
  57. namespace extensions {
  58. namespace {
  59. // Feature to control the delay between an extension becoming idle and sending a
  60. // ShouldSuspend message.
  61. const base::Feature kChangeExtensionEventPageSuspendDelay{
  62. "ChangeExtensionEventPageSuspendDelay", base::FEATURE_DISABLED_BY_DEFAULT};
  63. // The delay between an extension becoming idle and sending a ShouldSuspend
  64. // message. The default value is used when the
  65. // |kChangeExtensionEventPageSuspendDelay| feature is disabled.
  66. //
  67. // TODO(crbug.com/1144166): Cleanup the feature param after experiments with a
  68. // longer delay are complete.
  69. const base::FeatureParam<int> kEventPageSuspendDelayMs{
  70. &kChangeExtensionEventPageSuspendDelay, "event-page-suspend-delay-ms",
  71. 10000};
  72. // Overrides |kEventPageSuspendDelayMs| if not -1. For testing.
  73. constexpr int kInvalidSuspendDelay = -1;
  74. int g_event_page_suspend_delay_ms_for_testing = kInvalidSuspendDelay;
  75. // The time to delay between sending a ShouldSuspend message and
  76. // sending a Suspend message.
  77. unsigned g_event_page_suspending_time_msec = 5000;
  78. // Returns the delay between an extension becoming idle and sending a
  79. // ShouldSuspend message, taking into account experiments and testing overrides.
  80. base::TimeDelta GetEventPageSuspendDelay() {
  81. if (g_event_page_suspend_delay_ms_for_testing != kInvalidSuspendDelay) {
  82. return base::Milliseconds(g_event_page_suspend_delay_ms_for_testing);
  83. }
  84. return base::Milliseconds(kEventPageSuspendDelayMs.Get());
  85. }
  86. std::string GetExtensionID(content::RenderFrameHost* render_frame_host) {
  87. CHECK(render_frame_host);
  88. return util::GetExtensionIdForSiteInstance(
  89. *render_frame_host->GetSiteInstance());
  90. }
  91. bool IsFrameInExtensionHost(ExtensionHost* extension_host,
  92. content::RenderFrameHost* render_frame_host) {
  93. return content::WebContents::FromRenderFrameHost(render_frame_host) ==
  94. extension_host->host_contents();
  95. }
  96. // Incognito profiles use this process manager. It is mostly a shim that decides
  97. // whether to fall back on the original profile's ProcessManager based
  98. // on whether a given extension uses "split" or "spanning" incognito behavior.
  99. // TODO(devlin): Given how little this does and the amount of cruft it adds to
  100. // the .h file (in the form of protected members), we should consider just
  101. // moving the incognito logic into the base class.
  102. class IncognitoProcessManager : public ProcessManager {
  103. public:
  104. IncognitoProcessManager(BrowserContext* incognito_context,
  105. BrowserContext* original_context,
  106. ExtensionRegistry* extension_registry);
  107. IncognitoProcessManager(const IncognitoProcessManager&) = delete;
  108. IncognitoProcessManager& operator=(const IncognitoProcessManager&) = delete;
  109. ~IncognitoProcessManager() override {}
  110. bool CreateBackgroundHost(const Extension* extension,
  111. const GURL& url) override;
  112. scoped_refptr<content::SiteInstance> GetSiteInstanceForURL(const GURL& url)
  113. override;
  114. };
  115. static void CreateBackgroundHostForExtensionLoad(
  116. ProcessManager* manager, const Extension* extension) {
  117. if (BackgroundInfo::HasPersistentBackgroundPage(extension))
  118. manager->CreateBackgroundHost(extension,
  119. BackgroundInfo::GetBackgroundURL(extension));
  120. }
  121. void PropagateExtensionWakeResult(
  122. base::OnceCallback<void(bool)> callback,
  123. std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
  124. std::move(callback).Run(context_info != nullptr);
  125. }
  126. } // namespace
  127. struct ProcessManager::BackgroundPageData {
  128. // The count of things keeping the lazy background page alive.
  129. // TODO(crbug.com://695711): Work on a plan to remove this and rely
  130. // on activities.size() instead.
  131. int lazy_keepalive_count = 0;
  132. // True if the page responded to the ShouldSuspend message and is currently
  133. // dispatching the suspend event. During this time any events that arrive will
  134. // cancel the suspend process and an onSuspendCanceled event will be
  135. // dispatched to the page.
  136. bool is_closing = false;
  137. // Stores the value of the incremented
  138. // ProcessManager::last_background_close_sequence_id_ whenever the extension
  139. // is active. A copy of the ID is also passed in the callbacks and IPC
  140. // messages leading up to CloseLazyBackgroundPageNow. The process is aborted
  141. // if the IDs ever differ due to new activity.
  142. uint64_t close_sequence_id = 0ull;
  143. // Keeps track of when this page was last suspended. Used for perf metrics.
  144. std::unique_ptr<base::ElapsedTimer> since_suspended;
  145. ActivitiesMultiset activities;
  146. };
  147. // Data of a RenderFrameHost associated with an extension.
  148. struct ProcessManager::ExtensionRenderFrameData {
  149. // The type of the view.
  150. extensions::mojom::ViewType view_type = extensions::mojom::ViewType::kInvalid;
  151. // Whether the view is keeping the lazy background page alive or not.
  152. bool has_keepalive = false;
  153. // Returns whether the view can keep the lazy background page alive or not.
  154. bool CanKeepalive() const {
  155. switch (view_type) {
  156. case extensions::mojom::ViewType::kAppWindow:
  157. case extensions::mojom::ViewType::kBackgroundContents:
  158. case extensions::mojom::ViewType::kComponent:
  159. case extensions::mojom::ViewType::kExtensionDialog:
  160. case extensions::mojom::ViewType::kExtensionGuest:
  161. case extensions::mojom::ViewType::kExtensionPopup:
  162. case extensions::mojom::ViewType::kTabContents:
  163. return true;
  164. case extensions::mojom::ViewType::kInvalid:
  165. case extensions::mojom::ViewType::kExtensionBackgroundPage:
  166. case extensions::mojom::ViewType::kOffscreenDocument:
  167. return false;
  168. }
  169. NOTREACHED();
  170. return false;
  171. }
  172. };
  173. //
  174. // ProcessManager
  175. //
  176. // static
  177. ProcessManager* ProcessManager::Get(BrowserContext* context) {
  178. return ProcessManagerFactory::GetForBrowserContext(context);
  179. }
  180. // static
  181. ProcessManager* ProcessManager::Create(BrowserContext* context) {
  182. ExtensionRegistry* extension_registry = ExtensionRegistry::Get(context);
  183. ExtensionsBrowserClient* client = ExtensionsBrowserClient::Get();
  184. if (client->IsGuestSession(context)) {
  185. // In the guest session, there is a single off-the-record context. Unlike
  186. // a regular incognito mode, background pages of extensions must be
  187. // created regardless of whether extensions use "spanning" or "split"
  188. // incognito behavior.
  189. BrowserContext* original_context = client->GetOriginalContext(context);
  190. return new ProcessManager(context, original_context, extension_registry);
  191. }
  192. if (context->IsOffTheRecord()) {
  193. BrowserContext* original_context = client->GetOriginalContext(context);
  194. return new IncognitoProcessManager(
  195. context, original_context, extension_registry);
  196. }
  197. return new ProcessManager(context, context, extension_registry);
  198. }
  199. // static
  200. ProcessManager* ProcessManager::CreateForTesting(
  201. BrowserContext* context,
  202. ExtensionRegistry* extension_registry) {
  203. DCHECK(!context->IsOffTheRecord());
  204. return new ProcessManager(context, context, extension_registry);
  205. }
  206. // static
  207. ProcessManager* ProcessManager::CreateIncognitoForTesting(
  208. BrowserContext* incognito_context,
  209. BrowserContext* original_context,
  210. ExtensionRegistry* extension_registry) {
  211. DCHECK(incognito_context->IsOffTheRecord());
  212. DCHECK(!original_context->IsOffTheRecord());
  213. return new IncognitoProcessManager(incognito_context,
  214. original_context,
  215. extension_registry);
  216. }
  217. ProcessManager::ProcessManager(BrowserContext* context,
  218. BrowserContext* original_context,
  219. ExtensionRegistry* extension_registry)
  220. : extension_registry_(extension_registry),
  221. site_instance_(content::SiteInstance::Create(context)),
  222. browser_context_(context),
  223. worker_task_runner_(content::GetIOThreadTaskRunner({})),
  224. startup_background_hosts_created_(false),
  225. last_background_close_sequence_id_(0) {
  226. // ExtensionRegistry is shared between incognito and regular contexts.
  227. DCHECK_EQ(original_context, extension_registry_->browser_context());
  228. extension_registry_->AddObserver(this);
  229. // Only the original profile needs to listen for ready to create background
  230. // pages for all spanning extensions.
  231. if (!context->IsOffTheRecord()) {
  232. ExtensionSystem::Get(context)->ready().Post(
  233. FROM_HERE,
  234. base::BindOnce(&ProcessManager::MaybeCreateStartupBackgroundHosts,
  235. weak_ptr_factory_.GetWeakPtr()));
  236. }
  237. content::DevToolsAgentHost::AddObserver(this);
  238. }
  239. ProcessManager::~ProcessManager() {
  240. content::DevToolsAgentHost::RemoveObserver(this);
  241. }
  242. void ProcessManager::Shutdown() {
  243. extension_registry_->RemoveObserver(this);
  244. CloseBackgroundHosts();
  245. DCHECK(background_hosts_.empty());
  246. content::DevToolsAgentHost::RemoveObserver(this);
  247. site_instance_ = nullptr;
  248. for (auto& observer : observer_list_)
  249. observer.OnProcessManagerShutdown(this);
  250. }
  251. void ProcessManager::RegisterRenderFrameHost(
  252. content::WebContents* web_contents,
  253. content::RenderFrameHost* render_frame_host,
  254. const Extension* extension) {
  255. DCHECK(render_frame_host->IsRenderFrameLive());
  256. ExtensionRenderFrameData* data = &all_extension_frames_[render_frame_host];
  257. data->view_type = GetViewType(web_contents);
  258. // Keep the lazy background page alive as long as any non-background-page
  259. // extension views are visible. Keepalive count balanced in
  260. // UnregisterRenderFrame.
  261. AcquireLazyKeepaliveCountForFrame(render_frame_host);
  262. for (auto& observer : observer_list_)
  263. observer.OnExtensionFrameRegistered(extension->id(), render_frame_host);
  264. }
  265. void ProcessManager::UnregisterRenderFrameHost(
  266. content::RenderFrameHost* render_frame_host) {
  267. auto frame = all_extension_frames_.find(render_frame_host);
  268. if (frame != all_extension_frames_.end()) {
  269. std::string extension_id = GetExtensionID(render_frame_host);
  270. // Keepalive count, balanced in RegisterRenderFrame.
  271. ReleaseLazyKeepaliveCountForFrame(render_frame_host);
  272. all_extension_frames_.erase(frame);
  273. for (auto& observer : observer_list_)
  274. observer.OnExtensionFrameUnregistered(extension_id, render_frame_host);
  275. }
  276. }
  277. scoped_refptr<content::SiteInstance> ProcessManager::GetSiteInstanceForURL(
  278. const GURL& url) {
  279. return site_instance_->GetRelatedSiteInstance(url);
  280. }
  281. const ProcessManager::FrameSet ProcessManager::GetAllFrames() const {
  282. FrameSet result;
  283. for (const auto& key_value : all_extension_frames_)
  284. result.insert(key_value.first);
  285. return result;
  286. }
  287. ProcessManager::FrameSet ProcessManager::GetRenderFrameHostsForExtension(
  288. const std::string& extension_id) {
  289. FrameSet result;
  290. for (const auto& key_value : all_extension_frames_) {
  291. if (GetExtensionID(key_value.first) == extension_id)
  292. result.insert(key_value.first);
  293. }
  294. return result;
  295. }
  296. bool ProcessManager::IsRenderFrameHostRegistered(
  297. content::RenderFrameHost* render_frame_host) {
  298. return all_extension_frames_.find(render_frame_host) !=
  299. all_extension_frames_.end();
  300. }
  301. void ProcessManager::AddObserver(ProcessManagerObserver* observer) {
  302. observer_list_.AddObserver(observer);
  303. }
  304. void ProcessManager::RemoveObserver(ProcessManagerObserver* observer) {
  305. observer_list_.RemoveObserver(observer);
  306. }
  307. bool ProcessManager::CreateBackgroundHost(const Extension* extension,
  308. const GURL& url) {
  309. DCHECK(!BackgroundInfo::IsServiceWorkerBased(extension))
  310. << "CreateBackgroundHostForExtensionLoad called for service worker based"
  311. "background page";
  312. // Hosted apps are taken care of from BackgroundContentsService. Ignore them
  313. // here.
  314. if (extension->is_hosted_app())
  315. return false;
  316. // Don't create hosts if the embedder doesn't allow it.
  317. ProcessManagerDelegate* delegate =
  318. ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
  319. if (delegate &&
  320. !delegate->IsExtensionBackgroundPageAllowed(browser_context_, *extension))
  321. return false;
  322. // Don't create multiple background hosts for an extension.
  323. if (GetBackgroundHostForExtension(extension->id()))
  324. return true; // TODO(kalman): return false here? It might break things...
  325. DVLOG(1) << "CreateBackgroundHost " << extension->id();
  326. ExtensionHost* host =
  327. new ExtensionHost(extension, GetSiteInstanceForURL(url).get(), url,
  328. mojom::ViewType::kExtensionBackgroundPage);
  329. host->SetCloseHandler(
  330. base::BindOnce(&ProcessManager::HandleCloseExtensionHost,
  331. weak_ptr_factory_.GetWeakPtr()));
  332. host->CreateRendererSoon();
  333. OnBackgroundHostCreated(host);
  334. return true;
  335. }
  336. void ProcessManager::MaybeCreateStartupBackgroundHosts() {
  337. if (startup_background_hosts_created_)
  338. return;
  339. if (!ExtensionSystem::Get(browser_context_)->ready().is_signaled())
  340. return;
  341. // The embedder might disallow background pages entirely.
  342. ProcessManagerDelegate* delegate =
  343. ExtensionsBrowserClient::Get()->GetProcessManagerDelegate();
  344. if (delegate &&
  345. !delegate->AreBackgroundPagesAllowedForContext(browser_context_))
  346. return;
  347. // The embedder might want to defer background page loading. For example,
  348. // Chrome defers background page loading when it is launched to show the app
  349. // list, then triggers a load later when a browser window opens.
  350. if (delegate &&
  351. delegate->DeferCreatingStartupBackgroundHosts(browser_context_))
  352. return;
  353. CreateStartupBackgroundHosts();
  354. startup_background_hosts_created_ = true;
  355. }
  356. ExtensionHost* ProcessManager::GetBackgroundHostForExtension(
  357. const std::string& extension_id) {
  358. for (ExtensionHost* host : background_hosts_) {
  359. if (host->extension_id() == extension_id)
  360. return host;
  361. }
  362. return nullptr;
  363. }
  364. ExtensionHost* ProcessManager::GetExtensionHostForRenderFrameHost(
  365. content::RenderFrameHost* render_frame_host) {
  366. content::WebContents* web_contents =
  367. content::WebContents::FromRenderFrameHost(render_frame_host);
  368. for (ExtensionHost* extension_host : background_hosts_) {
  369. if (extension_host->host_contents() == web_contents)
  370. return extension_host;
  371. }
  372. return nullptr;
  373. }
  374. bool ProcessManager::IsEventPageSuspended(const std::string& extension_id) {
  375. return GetBackgroundHostForExtension(extension_id) == nullptr;
  376. }
  377. bool ProcessManager::WakeEventPage(const std::string& extension_id,
  378. base::OnceCallback<void(bool)> callback) {
  379. if (GetBackgroundHostForExtension(extension_id)) {
  380. // The extension is already awake.
  381. return false;
  382. }
  383. const LazyContextId context_id(browser_context_, extension_id);
  384. context_id.GetTaskQueue()->AddPendingTask(
  385. context_id,
  386. base::BindOnce(&PropagateExtensionWakeResult, std::move(callback)));
  387. return true;
  388. }
  389. bool ProcessManager::IsBackgroundHostClosing(const std::string& extension_id) {
  390. ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
  391. return (host && background_page_data_[extension_id].is_closing);
  392. }
  393. const Extension* ProcessManager::GetExtensionForRenderFrameHost(
  394. content::RenderFrameHost* render_frame_host) {
  395. return extension_registry_->enabled_extensions().GetByID(
  396. GetExtensionID(render_frame_host));
  397. }
  398. const Extension* ProcessManager::GetExtensionForWebContents(
  399. content::WebContents* web_contents) {
  400. if (!web_contents->GetSiteInstance())
  401. return nullptr;
  402. const Extension* extension =
  403. extension_registry_->enabled_extensions().GetByID(
  404. util::GetExtensionIdForSiteInstance(
  405. *web_contents->GetSiteInstance()));
  406. if (extension && extension->is_hosted_app()) {
  407. // For hosted apps, be sure to exclude URLs outside of the app that might
  408. // be loaded in the same SiteInstance (extensions guarantee that only
  409. // extension urls are loaded in that SiteInstance).
  410. content::NavigationController& controller = web_contents->GetController();
  411. content::NavigationEntry* entry = controller.GetLastCommittedEntry();
  412. // If the "last committed" entry is the initial entry, check the pending
  413. // entry. This can happen in cases where we query this before any entry is
  414. // fully committed, such as when attributing a WebContents for the
  415. // TaskManager. If there is a committed navigation, use that instead.
  416. if (!entry || entry->IsInitialEntry())
  417. entry = controller.GetPendingEntry();
  418. if (!entry ||
  419. extension_registry_->enabled_extensions().GetExtensionOrAppByURL(
  420. entry->GetURL()) != extension) {
  421. return nullptr;
  422. }
  423. }
  424. return extension;
  425. }
  426. int ProcessManager::GetLazyKeepaliveCount(const Extension* extension) {
  427. if (!BackgroundInfo::HasLazyBackgroundPage(extension))
  428. return -1;
  429. return background_page_data_[extension->id()].lazy_keepalive_count;
  430. }
  431. void ProcessManager::IncrementLazyKeepaliveCount(
  432. const Extension* extension,
  433. Activity::Type activity_type,
  434. const std::string& extra_data) {
  435. if (BackgroundInfo::HasLazyBackgroundPage(extension)) {
  436. BackgroundPageData& data = background_page_data_[extension->id()];
  437. if (++data.lazy_keepalive_count == 1)
  438. OnLazyBackgroundPageActive(extension->id());
  439. data.activities.insert(std::make_pair(activity_type, extra_data));
  440. }
  441. }
  442. void ProcessManager::DecrementLazyKeepaliveCount(
  443. const Extension* extension,
  444. Activity::Type activity_type,
  445. const std::string& extra_data) {
  446. if (BackgroundInfo::HasLazyBackgroundPage(extension))
  447. DecrementLazyKeepaliveCount(extension->id(), activity_type, extra_data);
  448. }
  449. void ProcessManager::NotifyExtensionProcessTerminated(
  450. const Extension* extension) {
  451. DCHECK(extension);
  452. for (auto& observer : observer_list_)
  453. observer.OnExtensionProcessTerminated(extension);
  454. }
  455. ProcessManager::ActivitiesMultiset ProcessManager::GetLazyKeepaliveActivities(
  456. const Extension* extension) {
  457. ProcessManager::ActivitiesMultiset result;
  458. if (BackgroundInfo::HasLazyBackgroundPage(extension))
  459. result = background_page_data_[extension->id()].activities;
  460. return result;
  461. }
  462. void ProcessManager::OnShouldSuspendAck(const std::string& extension_id,
  463. uint64_t sequence_id) {
  464. ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
  465. if (host &&
  466. sequence_id == background_page_data_[extension_id].close_sequence_id) {
  467. mojom::Renderer* renderer =
  468. RendererStartupHelperFactory::GetForBrowserContext(browser_context_)
  469. ->GetRenderer(host->render_process_host());
  470. if (renderer) {
  471. renderer->SuspendExtension(
  472. extension_id,
  473. base::BindOnce(&ProcessManager::OnSuspendAck,
  474. weak_ptr_factory_.GetWeakPtr(), extension_id));
  475. }
  476. }
  477. }
  478. void ProcessManager::OnSuspendAck(const std::string& extension_id) {
  479. background_page_data_[extension_id].is_closing = true;
  480. uint64_t sequence_id = background_page_data_[extension_id].close_sequence_id;
  481. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  482. FROM_HERE,
  483. base::BindOnce(&ProcessManager::CloseLazyBackgroundPageNow,
  484. weak_ptr_factory_.GetWeakPtr(), extension_id, sequence_id),
  485. base::Milliseconds(g_event_page_suspending_time_msec));
  486. }
  487. void ProcessManager::NetworkRequestStarted(
  488. content::RenderFrameHost* render_frame_host,
  489. uint64_t request_id) {
  490. ExtensionHost* host = GetBackgroundHostForExtension(
  491. GetExtensionID(render_frame_host));
  492. if (!host || !IsFrameInExtensionHost(host, render_frame_host))
  493. return;
  494. auto result =
  495. pending_network_requests_.insert(std::make_pair(request_id, host));
  496. DCHECK(result.second) << "Duplicate network request IDs.";
  497. IncrementLazyKeepaliveCount(host->extension(), Activity::NETWORK,
  498. base::NumberToString(request_id));
  499. host->OnNetworkRequestStarted(request_id);
  500. }
  501. void ProcessManager::NetworkRequestDone(
  502. content::RenderFrameHost* render_frame_host,
  503. uint64_t request_id) {
  504. auto result = pending_network_requests_.find(request_id);
  505. if (result == pending_network_requests_.end())
  506. return;
  507. // The cached |host| can be invalid, if it was deleted between the time it
  508. // was inserted in the map and the look up. It is checked to ensure it is in
  509. // the list of existing background_hosts_.
  510. ExtensionHost* host = result->second;
  511. pending_network_requests_.erase(result);
  512. if (background_hosts_.find(host) == background_hosts_.end())
  513. return;
  514. DCHECK(IsFrameInExtensionHost(host, render_frame_host));
  515. host->OnNetworkRequestDone(request_id);
  516. DecrementLazyKeepaliveCount(host->extension(), Activity::NETWORK,
  517. base::NumberToString(request_id));
  518. }
  519. void ProcessManager::CancelSuspend(const Extension* extension) {
  520. bool& is_closing = background_page_data_[extension->id()].is_closing;
  521. ExtensionHost* host = GetBackgroundHostForExtension(extension->id());
  522. if (host && is_closing) {
  523. is_closing = false;
  524. mojom::Renderer* renderer =
  525. RendererStartupHelperFactory::GetForBrowserContext(browser_context_)
  526. ->GetRenderer(host->render_process_host());
  527. if (renderer)
  528. renderer->CancelSuspendExtension(extension->id());
  529. // This increment / decrement is to simulate an instantaneous event. This
  530. // has the effect of invalidating close_sequence_id, preventing any in
  531. // progress closes from completing and starting a new close process if
  532. // necessary.
  533. IncrementLazyKeepaliveCount(extension, Activity::PROCESS_MANAGER,
  534. Activity::kCancelSuspend);
  535. DecrementLazyKeepaliveCount(extension, Activity::PROCESS_MANAGER,
  536. Activity::kCancelSuspend);
  537. }
  538. }
  539. void ProcessManager::CloseBackgroundHosts() {
  540. // Delete from a copy because deletion of the ExtensionHosts will trigger
  541. // callbacks to modify the |background_hosts_| set.
  542. ExtensionHostSet hosts_copy = background_hosts_;
  543. for (auto* host : hosts_copy) {
  544. // Deleting the host will cause a OnExtensionHostDestroyed which will cause
  545. // the removal of the host from the |background_hosts_| set in the
  546. // OnExtensionHostDestroyed() method below.
  547. delete host;
  548. DCHECK_EQ(0u, background_hosts_.count(host));
  549. }
  550. // At this point there should be nothing left in |background_hosts_|.
  551. DCHECK(background_hosts_.empty());
  552. }
  553. // static
  554. void ProcessManager::SetEventPageIdleTimeForTesting(unsigned idle_time_msec) {
  555. CHECK_GT(idle_time_msec, 0u);
  556. g_event_page_suspend_delay_ms_for_testing = idle_time_msec;
  557. }
  558. // static
  559. void ProcessManager::SetEventPageSuspendingTimeForTesting(
  560. unsigned suspending_time_msec) {
  561. g_event_page_suspending_time_msec = suspending_time_msec;
  562. }
  563. ////////////////////////////////////////////////////////////////////////////////
  564. // Private
  565. void ProcessManager::OnExtensionLoaded(BrowserContext* browser_context,
  566. const Extension* extension) {
  567. if (ExtensionSystem::Get(browser_context)->ready().is_signaled()) {
  568. // The extension system is ready, so create the background host.
  569. CreateBackgroundHostForExtensionLoad(this, extension);
  570. }
  571. }
  572. void ProcessManager::OnExtensionUnloaded(BrowserContext* browser_context,
  573. const Extension* extension,
  574. UnloadedExtensionReason reason) {
  575. ExtensionHost* host = GetBackgroundHostForExtension(extension->id());
  576. if (host != nullptr)
  577. CloseBackgroundHost(host);
  578. UnregisterExtension(extension->id());
  579. }
  580. void ProcessManager::CreateStartupBackgroundHosts() {
  581. SCOPED_UMA_HISTOGRAM_TIMER("Extensions.ProcessManagerStartupHostsTime2");
  582. DCHECK(!startup_background_hosts_created_);
  583. for (const scoped_refptr<const Extension>& extension :
  584. extension_registry_->enabled_extensions()) {
  585. CreateBackgroundHostForExtensionLoad(this, extension.get());
  586. for (auto& observer : observer_list_)
  587. observer.OnBackgroundHostStartup(extension.get());
  588. }
  589. }
  590. void ProcessManager::OnBackgroundHostCreated(ExtensionHost* host) {
  591. DCHECK_EQ(browser_context_, host->browser_context());
  592. background_hosts_.insert(host);
  593. host->AddObserver(this);
  594. if (BackgroundInfo::HasLazyBackgroundPage(host->extension())) {
  595. std::unique_ptr<base::ElapsedTimer> since_suspended = std::move(
  596. background_page_data_[host->extension()->id()].since_suspended);
  597. if (since_suspended.get()) {
  598. UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageIdleTime",
  599. since_suspended->Elapsed());
  600. }
  601. }
  602. for (auto& observer : observer_list_)
  603. observer.OnBackgroundHostCreated(host);
  604. }
  605. void ProcessManager::CloseBackgroundHost(ExtensionHost* host) {
  606. ExtensionId extension_id = host->extension_id();
  607. CHECK(host->extension_host_type() ==
  608. mojom::ViewType::kExtensionBackgroundPage);
  609. delete host;
  610. // |host| should deregister itself from our structures.
  611. CHECK(background_hosts_.find(host) == background_hosts_.end());
  612. for (auto& observer : observer_list_)
  613. observer.OnBackgroundHostClose(extension_id);
  614. }
  615. void ProcessManager::AcquireLazyKeepaliveCountForFrame(
  616. content::RenderFrameHost* render_frame_host) {
  617. auto it = all_extension_frames_.find(render_frame_host);
  618. if (it == all_extension_frames_.end())
  619. return;
  620. ExtensionRenderFrameData& data = it->second;
  621. if (data.CanKeepalive() && !data.has_keepalive) {
  622. const Extension* extension =
  623. GetExtensionForRenderFrameHost(render_frame_host);
  624. if (extension) {
  625. IncrementLazyKeepaliveCount(extension, Activity::PROCESS_MANAGER,
  626. Activity::kRenderFrame);
  627. data.has_keepalive = true;
  628. }
  629. }
  630. }
  631. void ProcessManager::ReleaseLazyKeepaliveCountForFrame(
  632. content::RenderFrameHost* render_frame_host) {
  633. auto iter = all_extension_frames_.find(render_frame_host);
  634. if (iter == all_extension_frames_.end())
  635. return;
  636. ExtensionRenderFrameData& data = iter->second;
  637. if (data.CanKeepalive() && data.has_keepalive) {
  638. const Extension* extension =
  639. GetExtensionForRenderFrameHost(render_frame_host);
  640. if (extension) {
  641. DecrementLazyKeepaliveCount(extension, Activity::PROCESS_MANAGER,
  642. Activity::kRenderFrame);
  643. data.has_keepalive = false;
  644. }
  645. }
  646. }
  647. std::string ProcessManager::IncrementServiceWorkerKeepaliveCount(
  648. const WorkerId& worker_id,
  649. content::ServiceWorkerExternalRequestTimeoutType timeout_type,
  650. Activity::Type activity_type,
  651. const std::string& extra_data) {
  652. // TODO(lazyboy): Use |activity_type| and |extra_data|.
  653. int64_t service_worker_version_id = worker_id.version_id;
  654. DCHECK(!worker_id.extension_id.empty());
  655. const Extension* extension =
  656. extension_registry_->enabled_extensions().GetByID(worker_id.extension_id);
  657. DCHECK(extension);
  658. DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
  659. std::string request_uuid = base::GenerateGUID();
  660. content::ServiceWorkerContext* service_worker_context =
  661. util::GetStoragePartitionForExtensionId(extension->id(), browser_context_)
  662. ->GetServiceWorkerContext();
  663. service_worker_context->StartingExternalRequest(service_worker_version_id,
  664. timeout_type, request_uuid);
  665. return request_uuid;
  666. }
  667. void ProcessManager::DecrementLazyKeepaliveCount(
  668. const std::string& extension_id,
  669. Activity::Type activity_type,
  670. const std::string& extra_data) {
  671. BackgroundPageData& data = background_page_data_[extension_id];
  672. DCHECK(data.lazy_keepalive_count > 0 ||
  673. !extension_registry_->enabled_extensions().Contains(extension_id));
  674. --data.lazy_keepalive_count;
  675. const auto it =
  676. data.activities.find(std::make_pair(activity_type, extra_data));
  677. if (it != data.activities.end()) {
  678. data.activities.erase(it);
  679. }
  680. // If we reach a zero keepalive count when the lazy background page is about
  681. // to be closed, incrementing close_sequence_id will cancel the close
  682. // sequence and cause the background page to linger. So check is_closing
  683. // before initiating another close sequence.
  684. if (data.lazy_keepalive_count == 0) {
  685. // Clear any leftover activities.
  686. data.activities.clear();
  687. if (!background_page_data_[extension_id].is_closing) {
  688. data.close_sequence_id = ++last_background_close_sequence_id_;
  689. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  690. FROM_HERE,
  691. base::BindOnce(&ProcessManager::OnLazyBackgroundPageIdle,
  692. weak_ptr_factory_.GetWeakPtr(), extension_id,
  693. last_background_close_sequence_id_),
  694. GetEventPageSuspendDelay());
  695. }
  696. }
  697. }
  698. void ProcessManager::DecrementServiceWorkerKeepaliveCount(
  699. const WorkerId& worker_id,
  700. const std::string& request_uuid,
  701. Activity::Type activity_type,
  702. const std::string& extra_data) {
  703. DCHECK(!worker_id.extension_id.empty());
  704. const Extension* extension =
  705. extension_registry_->enabled_extensions().GetByID(worker_id.extension_id);
  706. if (!extension)
  707. return;
  708. DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
  709. int64_t service_worker_version_id = worker_id.version_id;
  710. content::ServiceWorkerContext* service_worker_context =
  711. util::GetStoragePartitionForExtensionId(extension->id(), browser_context_)
  712. ->GetServiceWorkerContext();
  713. content::ServiceWorkerExternalRequestResult result =
  714. service_worker_context->FinishedExternalRequest(service_worker_version_id,
  715. request_uuid);
  716. DCHECK_EQ(result, content::ServiceWorkerExternalRequestResult::kOk);
  717. }
  718. void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id,
  719. uint64_t sequence_id) {
  720. ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
  721. if (host && !background_page_data_[extension_id].is_closing &&
  722. sequence_id == background_page_data_[extension_id].close_sequence_id) {
  723. // Tell the renderer we are about to close. This is a simple ping that the
  724. // renderer will respond to. The purpose is to control sequencing: if the
  725. // extension remains idle until the renderer responds, then we know that the
  726. // extension process is ready to shut down. If our close_sequence_id has
  727. // already changed, then we would ignore the reply to this message, so we
  728. // don't send the ping.
  729. mojom::Renderer* renderer =
  730. RendererStartupHelperFactory::GetForBrowserContext(browser_context())
  731. ->GetRenderer(host->render_process_host());
  732. if (renderer) {
  733. renderer->ShouldSuspend(base::BindOnce(
  734. &ProcessManager::OnShouldSuspendAck, weak_ptr_factory_.GetWeakPtr(),
  735. extension_id, sequence_id));
  736. }
  737. }
  738. }
  739. void ProcessManager::OnLazyBackgroundPageActive(
  740. const std::string& extension_id) {
  741. if (!background_page_data_[extension_id].is_closing) {
  742. // Cancel the current close sequence by changing the close_sequence_id,
  743. // which causes us to ignore the next ShouldSuspendAck.
  744. background_page_data_[extension_id].close_sequence_id =
  745. ++last_background_close_sequence_id_;
  746. }
  747. }
  748. void ProcessManager::CloseLazyBackgroundPageNow(const std::string& extension_id,
  749. uint64_t sequence_id) {
  750. ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
  751. if (host &&
  752. sequence_id == background_page_data_[extension_id].close_sequence_id) {
  753. // Handle the case where the keepalive count was increased after the
  754. // OnSuspend event was sent.
  755. if (background_page_data_[extension_id].lazy_keepalive_count > 0) {
  756. CancelSuspend(host->extension());
  757. return;
  758. }
  759. // Close remaining views.
  760. std::vector<content::RenderFrameHost*> frames_to_close;
  761. for (const auto& key_value : all_extension_frames_) {
  762. if (key_value.second.CanKeepalive() &&
  763. GetExtensionID(key_value.first) == extension_id) {
  764. DCHECK(!key_value.second.has_keepalive);
  765. frames_to_close.push_back(key_value.first);
  766. }
  767. }
  768. for (content::RenderFrameHost* frame : frames_to_close) {
  769. content::WebContents::FromRenderFrameHost(frame)->ClosePage();
  770. // WebContents::ClosePage() may result in calling
  771. // UnregisterRenderFrameHost() asynchronously and may cause race
  772. // conditions when the background page is reloaded.
  773. // To avoid this, unregister the view now.
  774. UnregisterRenderFrameHost(frame);
  775. }
  776. host = GetBackgroundHostForExtension(extension_id);
  777. if (host)
  778. CloseBackgroundHost(host);
  779. }
  780. }
  781. const Extension* ProcessManager::GetExtensionForAgentHost(
  782. content::DevToolsAgentHost* agent_host) {
  783. content::WebContents* web_contents = agent_host->GetWebContents();
  784. // Ignore unrelated notifications.
  785. if (!web_contents || web_contents->GetBrowserContext() != browser_context_)
  786. return nullptr;
  787. if (GetViewType(web_contents) != mojom::ViewType::kExtensionBackgroundPage)
  788. return nullptr;
  789. return GetExtensionForWebContents(web_contents);
  790. }
  791. void ProcessManager::DevToolsAgentHostAttached(
  792. content::DevToolsAgentHost* agent_host) {
  793. if (const Extension* extension = GetExtensionForAgentHost(agent_host)) {
  794. // Keep the lazy background page alive while it's being inspected.
  795. CancelSuspend(extension);
  796. IncrementLazyKeepaliveCount(extension, Activity::DEV_TOOLS, std::string());
  797. }
  798. }
  799. void ProcessManager::DevToolsAgentHostDetached(
  800. content::DevToolsAgentHost* agent_host) {
  801. if (const Extension* extension = GetExtensionForAgentHost(agent_host))
  802. DecrementLazyKeepaliveCount(extension, Activity::DEV_TOOLS, "");
  803. }
  804. void ProcessManager::UnregisterExtension(const std::string& extension_id) {
  805. // The lazy_keepalive_count may be greater than zero at this point because
  806. // RenderFrameHosts are still alive. During extension reloading, they will
  807. // decrement the lazy_keepalive_count to negative for the new extension
  808. // instance when they are destroyed. Since we are erasing the background page
  809. // data for the unloaded extension, unregister the RenderFrameHosts too.
  810. for (auto it = all_extension_frames_.begin();
  811. it != all_extension_frames_.end();) {
  812. content::RenderFrameHost* host = it->first;
  813. if (GetExtensionID(host) == extension_id) {
  814. all_extension_frames_.erase(it++);
  815. for (auto& observer : observer_list_)
  816. observer.OnExtensionFrameUnregistered(extension_id, host);
  817. } else {
  818. ++it;
  819. }
  820. }
  821. background_page_data_.erase(extension_id);
  822. for (const WorkerId& worker_id :
  823. all_extension_workers_.GetAllForExtension(extension_id)) {
  824. UnregisterServiceWorker(worker_id);
  825. }
  826. #if DCHECK_IS_ON()
  827. // Sanity check: No worker entry should exist for |extension_id|.
  828. DCHECK(all_extension_workers_.GetAllForExtension(extension_id).empty());
  829. #endif
  830. }
  831. void ProcessManager::RegisterServiceWorker(const WorkerId& worker_id) {
  832. all_extension_workers_.Add(worker_id);
  833. // Observe the RenderProcessHost for cleaning up on process shutdown.
  834. int render_process_id = worker_id.render_process_id;
  835. bool inserted = worker_process_to_extension_ids_[render_process_id]
  836. .insert(worker_id.extension_id)
  837. .second;
  838. if (inserted) {
  839. content::RenderProcessHost* render_process_host =
  840. content::RenderProcessHost::FromID(render_process_id);
  841. DCHECK(render_process_host);
  842. if (!process_observations_.IsObservingSource(render_process_host)) {
  843. // These will be cleaned up in RenderProcessExited().
  844. process_observations_.AddObservation(render_process_host);
  845. }
  846. for (auto& observer : observer_list_)
  847. observer.OnServiceWorkerRegistered(worker_id);
  848. }
  849. }
  850. void ProcessManager::RenderProcessExited(
  851. content::RenderProcessHost* host,
  852. const content::ChildProcessTerminationInfo& info) {
  853. DCHECK(process_observations_.IsObservingSource(host));
  854. process_observations_.RemoveObservation(host);
  855. const int render_process_id = host->GetID();
  856. // Look up and then clean up the entries that are affected by
  857. // |render_process_id| destruction.
  858. //
  859. // TODO(lazyboy): Revisit this once incognito is tested for extension SWs, as
  860. // the cleanup below only works because regular and OTR ProcessManagers are
  861. // separate. The conclusive approach would be to have a
  862. // all_extension_workers_.RemoveAllForProcess(render_process_id) method:
  863. // Pros: We won't need worker_process_to_extension_ids_ anymore.
  864. // Cons: We would require traversing all workers within
  865. // |all_extension_workers_| (slow) as things stand right now.
  866. auto iter = worker_process_to_extension_ids_.find(render_process_id);
  867. if (iter == worker_process_to_extension_ids_.end())
  868. return;
  869. for (const ExtensionId& extension_id : iter->second) {
  870. for (const WorkerId& worker_id : all_extension_workers_.GetAllForExtension(
  871. extension_id, render_process_id)) {
  872. UnregisterServiceWorker(worker_id);
  873. }
  874. }
  875. #if DCHECK_IS_ON()
  876. // Sanity check: No worker entry should exist for any |extension_id| running
  877. // inside the RenderProcessHost that died.
  878. for (const ExtensionId& extension_id : iter->second)
  879. DCHECK(all_extension_workers_.GetAllForExtension(extension_id).empty());
  880. #endif
  881. worker_process_to_extension_ids_.erase(iter);
  882. }
  883. void ProcessManager::OnExtensionHostDestroyed(ExtensionHost* host) {
  884. TRACE_EVENT0("browser,startup", "ProcessManager::OnExtensionHostDestroyed");
  885. host->RemoveObserver(this);
  886. DCHECK(background_hosts_.find(host) != background_hosts_.end());
  887. background_hosts_.erase(host);
  888. // Note: |host->extension()| may be null at this point.
  889. ClearBackgroundPageData(host->extension_id());
  890. background_page_data_[host->extension_id()].since_suspended =
  891. std::make_unique<base::ElapsedTimer>();
  892. }
  893. void ProcessManager::HandleCloseExtensionHost(ExtensionHost* host) {
  894. TRACE_EVENT0("browser,startup", "ProcessManager::OnExtensionHostShouldClose");
  895. DCHECK_EQ(mojom::ViewType::kExtensionBackgroundPage,
  896. host->extension_host_type());
  897. CloseBackgroundHost(host);
  898. // WARNING: `host` is deleted at this point!
  899. }
  900. void ProcessManager::UnregisterServiceWorker(const WorkerId& worker_id) {
  901. // TODO(lazyboy): DCHECK that |worker_id| exists in |all_extension_workers_|.
  902. all_extension_workers_.Remove(worker_id);
  903. for (auto& observer : observer_list_)
  904. observer.OnServiceWorkerUnregistered(worker_id);
  905. }
  906. bool ProcessManager::HasServiceWorker(const WorkerId& worker_id) const {
  907. return all_extension_workers_.Contains(worker_id);
  908. }
  909. std::vector<WorkerId> ProcessManager::GetServiceWorkersForExtension(
  910. const ExtensionId& extension_id) const {
  911. return all_extension_workers_.GetAllForExtension(extension_id);
  912. }
  913. std::vector<WorkerId> ProcessManager::GetAllWorkersIdsForTesting() {
  914. return all_extension_workers_.GetAllForTesting();
  915. }
  916. void ProcessManager::ClearBackgroundPageData(const std::string& extension_id) {
  917. background_page_data_.erase(extension_id);
  918. // Re-register all RenderFrames for this extension. We do this to restore
  919. // the lazy_keepalive_count (if any) to properly reflect the number of open
  920. // views.
  921. for (const auto& key_value : all_extension_frames_) {
  922. // Do not increment the count when |has_keepalive| is false
  923. // (i.e. ReleaseLazyKeepaliveCountForView() was called).
  924. if (GetExtensionID(key_value.first) == extension_id &&
  925. key_value.second.has_keepalive) {
  926. const Extension* extension =
  927. GetExtensionForRenderFrameHost(key_value.first);
  928. if (extension)
  929. IncrementLazyKeepaliveCount(extension, Activity::PROCESS_MANAGER,
  930. Activity::kRenderFrame);
  931. }
  932. }
  933. }
  934. //
  935. // IncognitoProcessManager
  936. //
  937. IncognitoProcessManager::IncognitoProcessManager(
  938. BrowserContext* incognito_context,
  939. BrowserContext* original_context,
  940. ExtensionRegistry* extension_registry)
  941. : ProcessManager(incognito_context, original_context, extension_registry) {
  942. DCHECK(incognito_context->IsOffTheRecord());
  943. }
  944. bool IncognitoProcessManager::CreateBackgroundHost(const Extension* extension,
  945. const GURL& url) {
  946. if (IncognitoInfo::IsSplitMode(extension)) {
  947. if (ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled(
  948. extension->id(), browser_context()))
  949. return ProcessManager::CreateBackgroundHost(extension, url);
  950. } else {
  951. // Do nothing. If an extension is spanning, then its original-profile
  952. // background page is shared with incognito, so we don't create another.
  953. }
  954. return false;
  955. }
  956. scoped_refptr<content::SiteInstance>
  957. IncognitoProcessManager::GetSiteInstanceForURL(const GURL& url) {
  958. const Extension* extension =
  959. extension_registry_->enabled_extensions().GetExtensionOrAppByURL(url);
  960. if (extension && !IncognitoInfo::IsSplitMode(extension)) {
  961. BrowserContext* original_context =
  962. ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context());
  963. return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url);
  964. }
  965. return ProcessManager::GetSiteInstanceForURL(url);
  966. }
  967. } // namespace extensions