Home | History | Annotate | Download | only in extensions
      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.
     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.
     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.
     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|.
     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
    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
    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
    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