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_BROWSER_BROWSING_INSTANCE_H_ 6#define CONTENT_BROWSER_BROWSING_INSTANCE_H_ 7 8#include "base/containers/hash_tables.h" 9#include "base/lazy_instance.h" 10#include "base/logging.h" 11#include "base/memory/ref_counted.h" 12#include "content/common/content_export.h" 13#include "content/public/browser/browser_context.h" 14 15class GURL; 16 17namespace content { 18class SiteInstance; 19class SiteInstanceImpl; 20 21/////////////////////////////////////////////////////////////////////////////// 22// 23// BrowsingInstance class 24// 25// A browsing instance corresponds to the notion of a "unit of related browsing 26// contexts" in the HTML 5 spec. Intuitively, it represents a collection of 27// tabs and frames that can have script connections to each other. In that 28// sense, it reflects the user interface, and not the contents of the tabs and 29// frames. 30// 31// We further subdivide a BrowsingInstance into SiteInstances, which represent 32// the documents within each BrowsingInstance that are from the same site and 33// thus can have script access to each other. Different SiteInstances can 34// safely run in different processes, because their documents cannot access 35// each other's contents (due to the same origin policy). 36// 37// It is important to only have one SiteInstance per site within a given 38// BrowsingInstance. This is because any two documents from the same site 39// might be able to script each other if they are in the same BrowsingInstance. 40// Thus, they must be rendered in the same process. 41// 42// A BrowsingInstance is live as long as any SiteInstance has a reference to 43// it. A SiteInstance is live as long as any NavigationEntry or RenderViewHost 44// have references to it. Because both classes are RefCounted, they do not 45// need to be manually deleted. 46// 47// BrowsingInstance has no public members, as it is designed to be 48// visible only from the SiteInstance class. To get a new 49// SiteInstance that is part of the same BrowsingInstance, use 50// SiteInstance::GetRelatedSiteInstance. Because of this, 51// BrowsingInstances and SiteInstances are tested together in 52// site_instance_unittest.cc. 53// 54/////////////////////////////////////////////////////////////////////////////// 55class CONTENT_EXPORT BrowsingInstance 56 : public base::RefCounted<BrowsingInstance> { 57 protected: 58 // Create a new BrowsingInstance. 59 explicit BrowsingInstance(BrowserContext* context); 60 61 // Get the browser context to which this BrowsingInstance belongs. 62 BrowserContext* browser_context() const { return browser_context_; } 63 64 // Returns whether this BrowsingInstance has registered a SiteInstance for 65 // the site of the given URL. 66 bool HasSiteInstance(const GURL& url); 67 68 // Get the SiteInstance responsible for rendering the given URL. Should 69 // create a new one if necessary, but should not create more than one 70 // SiteInstance per site. 71 SiteInstance* GetSiteInstanceForURL(const GURL& url); 72 73 // Adds the given SiteInstance to our map, to ensure that we do not create 74 // another SiteInstance for the same site. 75 void RegisterSiteInstance(SiteInstance* site_instance); 76 77 // Removes the given SiteInstance from our map, after all references to it 78 // have been deleted. This means it is safe to create a new SiteInstance 79 // if the user later visits a page from this site, within this 80 // BrowsingInstance. 81 void UnregisterSiteInstance(SiteInstance* site_instance); 82 83 // Tracks the number of WebContents currently in this BrowsingInstance. 84 size_t active_contents_count() const { return active_contents_count_; } 85 void increment_active_contents_count() { active_contents_count_++; } 86 void decrement_active_contents_count() { 87 DCHECK_LT(0u, active_contents_count_); 88 active_contents_count_--; 89 } 90 91 friend class SiteInstanceImpl; 92 friend class SiteInstance; 93 94 friend class base::RefCounted<BrowsingInstance>; 95 96 // Virtual to allow tests to extend it. 97 virtual ~BrowsingInstance(); 98 99 private: 100 // Map of site to SiteInstance, to ensure we only have one SiteInstance per 101 // site. 102 typedef base::hash_map<std::string, SiteInstance*> SiteInstanceMap; 103 104 // Common browser context to which all SiteInstances in this BrowsingInstance 105 // must belong. 106 BrowserContext* const browser_context_; 107 108 // Map of site to SiteInstance, to ensure we only have one SiteInstance per 109 // site. The site string should be the possibly_invalid_spec() of a GURL 110 // obtained with SiteInstanceImpl::GetSiteForURL. Note that this map may not 111 // contain every active SiteInstance, because a race exists where two 112 // SiteInstances can be assigned to the same site. This is ok in rare cases. 113 // It also does not contain SiteInstances which have not yet been assigned a 114 // site, such as about:blank. See NavigatorImpl::ShouldAssignSiteForURL. 115 SiteInstanceMap site_instance_map_; 116 117 // Number of WebContentses currently using this BrowsingInstance. 118 size_t active_contents_count_; 119 120 DISALLOW_COPY_AND_ASSIGN(BrowsingInstance); 121}; 122 123} // namespace content 124 125#endif // CONTENT_BROWSER_BROWSING_INSTANCE_H_ 126