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 15 class GURL; 16 17 namespace content { 18 class SiteInstance; 19 class 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 /////////////////////////////////////////////////////////////////////////////// 55 class 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