Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 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 #ifndef CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
      6 #define CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "content/common/content_export.h"
     11 #include "url/gurl.h"
     12 
     13 namespace content {
     14 class BrowserContext;
     15 class BrowsingInstance;
     16 class RenderProcessHost;
     17 
     18 ///////////////////////////////////////////////////////////////////////////////
     19 // SiteInstance interface.
     20 //
     21 // A SiteInstance represents a group of web pages that may be able to
     22 // synchronously script each other, and thus must live in the same renderer
     23 // process.
     24 //
     25 // We identify this group using a combination of where the page comes from
     26 // (the site) and which tabs have references to each other (the instance).
     27 // Here, a "site" is similar to the page's origin, but it only includes the
     28 // registered domain name and scheme, not the port or subdomains.  This accounts
     29 // for the fact that changes to document.domain allow similar origin pages with
     30 // different ports or subdomains to script each other.  An "instance" includes
     31 // all tabs that might be able to script each other because of how they were
     32 // created (e.g., window.open or targeted links).  We represent instances using
     33 // the BrowsingInstance class.
     34 //
     35 // Process models:
     36 //
     37 // In process-per-site-instance (the current default process model),
     38 // SiteInstances are created (1) when the user manually creates a new tab
     39 // (which also creates a new BrowsingInstance), and (2) when the user navigates
     40 // across site boundaries (which uses the same BrowsingInstance).  If the user
     41 // navigates within a site, the same SiteInstance is used.
     42 // (Caveat: we currently allow renderer-initiated cross-site navigations to
     43 // stay in the same SiteInstance, to preserve compatibility in cases like
     44 // cross-site iframes that open popups.)
     45 //
     46 // In --process-per-tab, SiteInstances are created when the user manually
     47 // creates a new tab, but not when navigating across site boundaries (unless
     48 // a process swap is required for security reasons, such as navigating from
     49 // a privileged WebUI page to a normal web page).  This corresponds to one
     50 // process per BrowsingInstance.
     51 //
     52 // In --process-per-site, we consolidate all SiteInstances for a given site into
     53 // the same process, throughout the entire browser context.  This ensures that
     54 // only one process will be used for each site.
     55 //
     56 // Each NavigationEntry for a WebContents points to the SiteInstance that
     57 // rendered it.  Each RenderViewHost also points to the SiteInstance that it is
     58 // associated with.  A SiteInstance keeps track of the number of these
     59 // references and deletes itself when the count goes to zero.  This means that
     60 // a SiteInstance is only live as long as it is accessible, either from new
     61 // tabs with no NavigationEntries or in NavigationEntries in the history.
     62 //
     63 ///////////////////////////////////////////////////////////////////////////////
     64 class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
     65  public:
     66   // Returns a unique ID for this SiteInstance.
     67   virtual int32 GetId() = 0;
     68 
     69   // Whether this SiteInstance has a running process associated with it.
     70   // This may return true before the first call to GetProcess(), in cases where
     71   // we use process-per-site and there is an existing process available.
     72   virtual bool HasProcess() const = 0;
     73 
     74   // Returns the current process being used to render pages in this
     75   // SiteInstance.  If the process has not yet been created or has cleanly
     76   // exited (e.g., when it is not actively being used), then this method will
     77   // create a new process with a new ID.  Note that renderer process crashes
     78   // leave the current RenderProcessHost (and ID) in place.
     79   //
     80   // For sites that require process-per-site mode (e.g., WebUI), this will
     81   // ensure only one RenderProcessHost for the site exists/ within the
     82   // BrowserContext.
     83   virtual content::RenderProcessHost* GetProcess() = 0;
     84 
     85   // Browser context to which this SiteInstance (and all related
     86   // SiteInstances) belongs.
     87   virtual content::BrowserContext* GetBrowserContext() const = 0;
     88 
     89   // Get the web site that this SiteInstance is rendering pages for.
     90   // This includes the scheme and registered domain, but not the port.
     91   virtual const GURL& GetSiteURL() const = 0;
     92 
     93   // Gets a SiteInstance for the given URL that shares the current
     94   // BrowsingInstance, creating a new SiteInstance if necessary.  This ensures
     95   // that a BrowsingInstance only has one SiteInstance per site, so that pages
     96   // in a BrowsingInstance have the ability to script each other.  Callers
     97   // should ensure that this SiteInstance becomes ref counted, by storing it in
     98   // a scoped_refptr.  (By having this method, we can hide the BrowsingInstance
     99   // class from the rest of the codebase.)
    100   // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
    101   // Darin suggests.
    102   virtual SiteInstance* GetRelatedSiteInstance(const GURL& url) = 0;
    103 
    104   // Returns whether the given SiteInstance is in the same BrowsingInstance as
    105   // this one.  If so, JavaScript interactions that are permitted across
    106   // origins (e.g., postMessage) should be supported.
    107   virtual bool IsRelatedSiteInstance(const SiteInstance* instance) = 0;
    108 
    109   // Factory method to create a new SiteInstance.  This will create a new
    110   // new BrowsingInstance, so it should only be used when creating a new tab
    111   // from scratch (or similar circumstances).  Callers should ensure that
    112   // this SiteInstance becomes ref counted, by storing it in a scoped_refptr.
    113   //
    114   // The render process host factory may be NULL. See SiteInstance constructor.
    115   //
    116   // TODO(creis): This may be an argument to build a pass_refptr<T> class, as
    117   // Darin suggests.
    118   static SiteInstance* Create(content::BrowserContext* browser_context);
    119 
    120   // Factory method to get the appropriate SiteInstance for the given URL, in
    121   // a new BrowsingInstance.  Use this instead of Create when you know the URL,
    122   // since it allows special site grouping rules to be applied (for example,
    123   // to group chrome-ui pages into the same instance).
    124   static SiteInstance* CreateForURL(
    125       content::BrowserContext* browser_context, const GURL& url);
    126 
    127   // Return whether both URLs are part of the same web site, for the purpose of
    128   // assigning them to processes accordingly.  The decision is currently based
    129   // on the registered domain of the URLs (google.com, bbc.co.uk), as well as
    130   // the scheme (https, http).  This ensures that two pages will be in
    131   // the same process if they can communicate with other via JavaScript.
    132   // (e.g., docs.google.com and mail.google.com have DOM access to each other
    133   // if they both set their document.domain properties to google.com.)
    134   static bool IsSameWebSite(content::BrowserContext* browser_context,
    135                             const GURL& url1, const GURL& url2);
    136 
    137   // Returns the site for the given URL, which includes only the scheme and
    138   // registered domain.  Returns an empty GURL if the URL has no host.
    139   static GURL GetSiteForURL(BrowserContext* context, const GURL& url);
    140 
    141  protected:
    142   friend class base::RefCounted<SiteInstance>;
    143 
    144   SiteInstance() {}
    145   virtual ~SiteInstance() {}
    146 };
    147 
    148 }  // namespace content.
    149 
    150 #endif  // CONTENT_PUBLIC_BROWSER_SITE_INSTANCE_H_
    151