• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #include "chrome/browser/extensions/extension_view_host_factory.h"
6 
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/extensions/extension_util.h"
9 #include "chrome/browser/extensions/extension_view_host.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/common/url_constants.h"
13 #include "extensions/browser/extension_system.h"
14 #include "extensions/browser/process_manager.h"
15 #include "extensions/common/manifest_handlers/incognito_info.h"
16 #include "extensions/common/view_type.h"
17 
18 #if defined(OS_MACOSX)
19 #include "chrome/browser/extensions/extension_view_host_mac.h"
20 #endif
21 
22 namespace extensions {
23 
24 namespace {
25 
26 // Creates a new ExtensionHost with its associated view, grouping it in the
27 // appropriate SiteInstance (and therefore process) based on the URL and
28 // profile.
CreateViewHostForExtension(const Extension * extension,const GURL & url,Profile * profile,Browser * browser,ViewType view_type)29 ExtensionViewHost* CreateViewHostForExtension(const Extension* extension,
30                                               const GURL& url,
31                                               Profile* profile,
32                                               Browser* browser,
33                                               ViewType view_type) {
34   DCHECK(profile);
35   // A NULL browser may only be given for dialogs.
36   DCHECK(browser || view_type == VIEW_TYPE_EXTENSION_DIALOG);
37   ProcessManager* pm =
38       ExtensionSystem::Get(profile)->process_manager();
39   content::SiteInstance* site_instance = pm->GetSiteInstanceForURL(url);
40   ExtensionViewHost* host =
41 #if defined(OS_MACOSX)
42       new ExtensionViewHostMac(extension, site_instance, url, view_type);
43 #else
44       new ExtensionViewHost(extension, site_instance, url, view_type);
45 #endif
46   host->CreateView(browser);
47   return host;
48 }
49 
50 // Creates a view host for an extension in an incognito window. Returns NULL
51 // if the extension is not allowed to run in incognito.
CreateViewHostForIncognito(const Extension * extension,const GURL & url,Profile * profile,Browser * browser,ViewType view_type)52 ExtensionViewHost* CreateViewHostForIncognito(const Extension* extension,
53                                               const GURL& url,
54                                               Profile* profile,
55                                               Browser* browser,
56                                               ViewType view_type) {
57   DCHECK(extension);
58   DCHECK(profile->IsOffTheRecord());
59 
60   if (!IncognitoInfo::IsSplitMode(extension)) {
61     // If it's not split-mode the host is associated with the original profile.
62     Profile* original_profile = profile->GetOriginalProfile();
63     return CreateViewHostForExtension(
64         extension, url, original_profile, browser, view_type);
65   }
66 
67   // Create the host if the extension can run in incognito.
68   if (util::IsIncognitoEnabled(extension->id(), profile)) {
69     return CreateViewHostForExtension(
70         extension, url, profile, browser, view_type);
71   }
72   NOTREACHED() <<
73       "We shouldn't be trying to create an incognito extension view unless "
74       "it has been enabled for incognito.";
75   return NULL;
76 }
77 
78 // Returns the extension associated with |url| in |profile|. Returns NULL if
79 // the extension does not exist.
GetExtensionForUrl(Profile * profile,const GURL & url)80 const Extension* GetExtensionForUrl(Profile* profile, const GURL& url) {
81   ExtensionService* service =
82       ExtensionSystem::Get(profile)->extension_service();
83   if (!service)
84     return NULL;
85   std::string extension_id = url.host();
86   if (url.SchemeIs(content::kChromeUIScheme) &&
87       url.host() == chrome::kChromeUIExtensionInfoHost)
88     extension_id = url.path().substr(1);
89   return service->extensions()->GetByID(extension_id);
90 }
91 
92 // Creates and initializes an ExtensionViewHost for the extension with |url|.
CreateViewHost(const GURL & url,Profile * profile,Browser * browser,extensions::ViewType view_type)93 ExtensionViewHost* CreateViewHost(const GURL& url,
94                                   Profile* profile,
95                                   Browser* browser,
96                                   extensions::ViewType view_type) {
97   DCHECK(profile);
98   // A NULL browser may only be given for dialogs.
99   DCHECK(browser || view_type == VIEW_TYPE_EXTENSION_DIALOG);
100 
101   const Extension* extension = GetExtensionForUrl(profile, url);
102   if (!extension)
103     return NULL;
104   if (profile->IsOffTheRecord()) {
105     return CreateViewHostForIncognito(
106         extension, url, profile, browser, view_type);
107   }
108   return CreateViewHostForExtension(
109       extension, url, profile, browser, view_type);
110 }
111 
112 }  // namespace
113 
114 // static
CreatePopupHost(const GURL & url,Browser * browser)115 ExtensionViewHost* ExtensionViewHostFactory::CreatePopupHost(const GURL& url,
116                                                              Browser* browser) {
117   DCHECK(browser);
118   return CreateViewHost(
119       url, browser->profile(), browser, VIEW_TYPE_EXTENSION_POPUP);
120 }
121 
122 // static
CreateInfobarHost(const GURL & url,Browser * browser)123 ExtensionViewHost* ExtensionViewHostFactory::CreateInfobarHost(
124     const GURL& url,
125     Browser* browser) {
126   DCHECK(browser);
127   return CreateViewHost(
128       url, browser->profile(), browser, VIEW_TYPE_EXTENSION_INFOBAR);
129 }
130 
131 // static
CreateDialogHost(const GURL & url,Profile * profile)132 ExtensionViewHost* ExtensionViewHostFactory::CreateDialogHost(
133     const GURL& url,
134     Profile* profile) {
135   DCHECK(profile);
136   return CreateViewHost(url, profile, NULL, VIEW_TYPE_EXTENSION_DIALOG);
137 }
138 
139 }  // namespace extensions
140