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 22namespace extensions { 23 24namespace { 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. 29ExtensionViewHost* 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. 52ExtensionViewHost* 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. 80const 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|. 93ExtensionViewHost* 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 115ExtensionViewHost* 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 123ExtensionViewHost* 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 132ExtensionViewHost* 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