1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_process_manager.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browsing_instance.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host_mac.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_action.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/extensions/extension_messages.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/url_constants.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace {
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Incognito profiles use this process manager. It is mostly a shim that decides
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// whether to fall back on the original profile's ExtensionProcessManager based
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// on whether a given extension uses "split" or "spanning" incognito behavior.
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass IncognitoExtensionProcessManager : public ExtensionProcessManager {
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit IncognitoExtensionProcessManager(Profile* profile);
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~IncognitoExtensionProcessManager() {}
35513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual ExtensionHost* CreateView(const Extension* extension,
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    const GURL& url,
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    Browser* browser,
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    ViewType::Type view_type);
39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void CreateBackgroundHost(const Extension* extension,
40513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                    const GURL& url);
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual SiteInstance* GetSiteInstanceForURL(const GURL& url);
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual RenderProcessHost* GetExtensionProcess(const GURL& url);
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // NotificationObserver:
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void Observe(NotificationType type,
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       const NotificationSource& source,
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                       const NotificationDetails& details);
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Returns the extension for an URL, which can either be a chrome-extension
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // URL or a web app URL.
52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* GetExtensionOrAppByURL(const GURL& url);
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Returns true if the extension is allowed to run in incognito mode.
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool IsIncognitoEnabled(const Extension* extension);
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExtensionProcessManager* original_manager_;
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void CreateBackgroundHost(
61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ExtensionProcessManager* manager, const Extension* extension) {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start the process for the master page, if it exists.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->background_url().is_valid())
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    manager->CreateBackgroundHost(extension, extension->background_url());
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void CreateBackgroundHosts(
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionProcessManager* manager, const ExtensionList* extensions) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::const_iterator extension = extensions->begin();
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension != extensions->end(); ++extension) {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateBackgroundHost(manager, *extension);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickextern bool g_log_bug53991;
78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// ExtensionProcessManager
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickExtensionProcessManager* ExtensionProcessManager::Create(Profile* profile) {
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return (profile->IsOffTheRecord()) ?
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new IncognitoExtensionProcessManager(profile) :
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new ExtensionProcessManager(profile);
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionProcessManager::ExtensionProcessManager(Profile* profile)
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : browsing_instance_(new BrowsingInstance(profile)) {
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Profile* original_profile = profile->GetOriginalProfile();
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSIONS_READY,
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 Source<Profile>(original_profile));
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 Source<Profile>(original_profile));
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 Source<Profile>(original_profile));
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Profile>(profile));
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED,
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED,
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::APP_TERMINATING,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionProcessManager::~ExtensionProcessManager() {
110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  VLOG_IF(1, g_log_bug53991) << "~ExtensionProcessManager: " << this;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseBackgroundHosts();
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(background_hosts_.empty());
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionHost* ExtensionProcessManager::CreateView(const Extension* extension,
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   const GURL& url,
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   Browser* browser,
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   ViewType::Type view_type) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A NULL browser may only be given for pop-up views.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(browser || (!browser && view_type == ViewType::EXTENSION_POPUP));
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host =
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           view_type);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionHost(extension, GetSiteInstanceForURL(url), url, view_type);
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host->CreateView(browser);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OnExtensionHostCreated(host, false);
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return host;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHost* ExtensionProcessManager::CreateView(const GURL& url,
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   Browser* browser,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   ViewType::Type view_type) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A NULL browser may only be given for pop-up views.
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(browser || (!browser && view_type == ViewType::EXTENSION_POPUP));
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service =
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      browsing_instance_->profile()->GetExtensionService();
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service) {
142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension = service->GetExtensionByURL(url);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension)
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return CreateView(extension, url, browser, view_type);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionHost* ExtensionProcessManager::CreatePopup(const Extension* extension,
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                    const GURL& url,
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                    Browser* browser) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return CreateView(extension, url, browser, ViewType::EXTENSION_POPUP);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHost* ExtensionProcessManager::CreatePopup(const GURL& url,
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                    Browser* browser) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return CreateView(url, browser, ViewType::EXTENSION_POPUP);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionHost* ExtensionProcessManager::CreateInfobar(
161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension, const GURL& url, Browser* browser) {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return CreateView(extension, url, browser, ViewType::EXTENSION_INFOBAR);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHost* ExtensionProcessManager::CreateInfobar(const GURL& url,
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      Browser* browser) {
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return CreateView(url, browser, ViewType::EXTENSION_INFOBAR);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionProcessManager::CreateBackgroundHost(
171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension, const GURL& url) {
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Hosted apps are taken care of from BackgroundContentsService. Ignore them
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // here.
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (extension->is_hosted_app())
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Don't create multiple background hosts for an extension.
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (GetBackgroundHostForExtension(extension))
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host =
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url,
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           ViewType::EXTENSION_BACKGROUND_PAGE);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        ViewType::EXTENSION_BACKGROUND_PAGE);
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host->CreateRenderViewSoon(NULL);  // create a RenderViewHost with no view
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OnExtensionHostCreated(host, true);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionProcessManager::OpenOptionsPage(const Extension* extension,
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              Browser* browser) {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!extension->options_url().is_empty());
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Force the options page to open in non-OTR window, because it won't be
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // able to save settings from OTR.
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!browser || browser->profile()->IsOffTheRecord()) {
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    browser = Browser::GetOrCreateTabbedBrowser(
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        browsing_instance_->profile()->GetOriginalProfile());
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->OpenURL(extension->options_url(), GURL(), SINGLETON_TAB,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   PageTransition::LINK);
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->GetSelectedTabContents()->Activate();
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHost* ExtensionProcessManager::GetBackgroundHostForExtension(
212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension) {
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionHostSet::iterator iter = background_hosts_.begin();
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != background_hosts_.end(); ++iter) {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionHost* host = *iter;
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (host->extension() == extension)
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return host;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionProcessManager::RegisterExtensionProcess(
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& extension_id, int process_id) {
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(mpcomplete): This is the only place we actually read process_ids_.
2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Is it necessary?
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessIDMap::const_iterator it = process_ids_.find(extension_id);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (it != process_ids_.end() && (*it).second == process_id)
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extension ids should get removed from the map before the process ids get
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reused from a dead renderer.
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(it == process_ids_.end());
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process_ids_[extension_id] = process_id;
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* extension_service =
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      browsing_instance_->profile()->GetExtensionService();
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> page_action_ids;
239513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension =
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_service->GetExtensionById(extension_id, false);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->page_action())
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    page_action_ids.push_back(extension->page_action()->id());
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  rph->Send(new ExtensionMsg_UpdatePageActions(extension_id, page_action_ids));
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionProcessManager::UnregisterExtensionProcess(int process_id) {
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessIDMap::iterator it = process_ids_.begin();
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (it != process_ids_.end()) {
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (it->second == process_id)
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      process_ids_.erase(it++);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++it;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderProcessHost* ExtensionProcessManager::GetExtensionProcess(
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url) {
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!browsing_instance_->HasSiteInstance(url))
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<SiteInstance> site(
263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      browsing_instance_->GetSiteInstanceForURL(url));
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (site->HasProcess())
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return site->GetProcess();
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderProcessHost* ExtensionProcessManager::GetExtensionProcess(
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& extension_id) {
2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return GetExtensionProcess(
2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Extension::GetBaseURLFromExtensionId(extension_id));
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browsing_instance_->GetSiteInstanceForURL(url);
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const {
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return all_hosts_.find(host) != all_hosts_.end();
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionProcessManager::Observe(NotificationType type,
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const NotificationSource& source,
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const NotificationDetails& details) {
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case NotificationType::EXTENSIONS_READY: {
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CreateBackgroundHosts(this,
28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Source<Profile>(source).ptr()->GetExtensionService()->extensions());
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_LOADED: {
29421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ExtensionService* service =
29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Source<Profile>(source).ptr()->GetExtensionService();
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (service->is_ready()) {
297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        const Extension* extension = Details<const Extension>(details).ptr();
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ::CreateBackgroundHost(this, extension);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UNLOADED: {
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const Extension* extension =
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Details<UnloadedExtensionInfo>(details)->extension;
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (ExtensionHostSet::iterator iter = background_hosts_.begin();
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           iter != background_hosts_.end(); ++iter) {
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ExtensionHost* host = *iter;
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (host->extension_id() == extension->id()) {
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          delete host;
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          // |host| should deregister itself from our structures.
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          DCHECK(background_hosts_.find(host) == background_hosts_.end());
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          break;
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_HOST_DESTROYED: {
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExtensionHost* host = Details<ExtensionHost>(details).ptr();
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      all_hosts_.erase(host);
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      background_hosts_.erase(host);
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RENDERER_PROCESS_TERMINATED:
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RENDERER_PROCESS_CLOSED: {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RenderProcessHost* host = Source<RenderProcessHost>(source).ptr();
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UnregisterExtensionProcess(host->id());
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::APP_TERMINATING: {
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Close background hosts when the last browser is closed so that they
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // have time to shutdown various objects on different threads. Our
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // destructor is called too late in the shutdown sequence.
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CloseBackgroundHosts();
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host,
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                     bool is_background) {
3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_EQ(browsing_instance_->profile(), host->profile());
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  all_hosts_.insert(host);
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_background)
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    background_hosts_.insert(host);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::EXTENSION_HOST_CREATED,
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<ExtensionProcessManager>(this),
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<ExtensionHost>(host));
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionProcessManager::CloseBackgroundHosts() {
360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  VLOG_IF(1, g_log_bug53991) << "CloseBackgroundHosts: " << this;
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionHostSet::iterator iter = background_hosts_.begin();
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != background_hosts_.end(); ) {
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionHostSet::iterator current = iter++;
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete *current;
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// IncognitoExtensionProcessManager
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick//
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIncognitoExtensionProcessManager::IncognitoExtensionProcessManager(
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    Profile* profile)
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : ExtensionProcessManager(profile),
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      original_manager_(profile->GetOriginalProfile()->
3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            GetExtensionProcessManager()) {
3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(profile->IsOffTheRecord());
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.Add(this, NotificationType::BROWSER_WINDOW_READY,
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                 NotificationService::AllSources());
3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickExtensionHost* IncognitoExtensionProcessManager::CreateView(
384513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension,
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const GURL& url,
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    Browser* browser,
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ViewType::Type view_type) {
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (extension->incognito_split_mode()) {
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (IsIncognitoEnabled(extension)) {
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return ExtensionProcessManager::CreateView(extension, url,
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                 browser, view_type);
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else {
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NOTREACHED() <<
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          "We shouldn't be trying to create an incognito extension view unless "
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          "it has been enabled for incognito.";
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return NULL;
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return original_manager_->CreateView(extension, url, browser, view_type);
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid IncognitoExtensionProcessManager::CreateBackgroundHost(
404513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension, const GURL& url) {
4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (extension->incognito_split_mode()) {
4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (IsIncognitoEnabled(extension))
4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ExtensionProcessManager::CreateBackgroundHost(extension, url);
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Do nothing. If an extension is spanning, then its original-profile
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // background page is shared with incognito, so we don't create another.
4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickSiteInstance* IncognitoExtensionProcessManager::GetSiteInstanceForURL(
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const GURL& url) {
416513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetExtensionOrAppByURL(url);
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!extension || extension->incognito_split_mode()) {
4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ExtensionProcessManager::GetSiteInstanceForURL(url);
4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return original_manager_->GetSiteInstanceForURL(url);
4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRenderProcessHost* IncognitoExtensionProcessManager::GetExtensionProcess(
4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const GURL& url) {
426513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = GetExtensionOrAppByURL(url);
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!extension || extension->incognito_split_mode()) {
4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ExtensionProcessManager::GetExtensionProcess(url);
4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else {
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return original_manager_->GetExtensionProcess(url);
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
434513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL(
4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const GURL& url) {
43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service =
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      browsing_instance_->profile()->GetExtensionService();
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!service)
4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return NULL;
4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return (url.SchemeIs(chrome::kExtensionScheme)) ?
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      service->GetExtensionByURL(url) : service->GetExtensionByWebExtent(url);
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool IncognitoExtensionProcessManager::IsIncognitoEnabled(
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const Extension* extension) {
44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service =
44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      browsing_instance_->profile()->GetExtensionService();
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return service && service->IsIncognitoEnabled(extension->id());
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid IncognitoExtensionProcessManager::Observe(
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NotificationType type,
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const NotificationSource& source,
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const NotificationDetails& details) {
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  switch (type.value) {
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case NotificationType::BROWSER_WINDOW_READY: {
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // We want to spawn our background hosts as soon as the user opens an
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // incognito window. Watch for new browsers and create the hosts if
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // it matches our profile.
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Browser* browser = Source<Browser>(source).ptr();
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (browser->profile() == browsing_instance_->profile()) {
462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        // On Chrome OS, a login screen is implemented as a browser.
463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        // This browser has no extension service.  In this case,
464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        // service will be NULL.
46521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        ExtensionService* service =
46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            browsing_instance_->profile()->GetExtensionService();
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (service && service->is_ready())
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          CreateBackgroundHosts(this, service->extensions());
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    default:
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ExtensionProcessManager::Observe(type, source, details);
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
477