1 // Copyright (c) 2011 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 CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_IMPL_H_ 6 #define CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_IMPL_H_ 7 #pragma once 8 9 #include <set> 10 #include <vector> 11 12 #include "include/cef_request_context_handler.h" 13 #include "libcef/browser/iothread_state.h" 14 #include "libcef/browser/request_context_handler_map.h" 15 16 #include "base/callback.h" 17 #include "base/files/file_path.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/optional.h" 20 #include "chrome/common/plugin.mojom.h" 21 #include "services/network/public/mojom/network_context.mojom.h" 22 #include "url/origin.h" 23 24 /* 25 // Classes used in request processing (network, storage, service, etc.): 26 // 27 // WC = WebContents 28 // Content API representation of a browser. Created by BHI or the system (for 29 // popups) and owned by BHI. Keeps a pointer to the content::BrowserContext. 30 // 31 // BHI = AlloyBrowserHostImpl 32 // Implements the CefBrowser and CefBrowserHost interfaces which are exposed 33 // to clients. References an RCI instance. Owns a WC. Lifespan is controlled 34 // by client references and CefBrowserInfoManager (until the browser has 35 // closed). 36 // 37 // RCI = CefRequestContextImpl 38 // Implements the CefRequestContext interface which is exposed to clients. 39 // Creates or references a BC. Lifespan is controlled by client references and 40 // BrowserMainParts (for the global RCI). 41 // 42 // BC = CefBrowserContext 43 // Is/owns the content::BrowserContext which is the entry point from WC. 44 // Owns the IOTS and creates the SPI indirectly. Potentially shared by 45 // multiple RCI. Deletes itself when no longer needed by RCI. 46 // 47 // SPI = content::StoragePartitionImpl 48 // Owns storage-related objects like Quota, IndexedDB, Cache, etc. Created by 49 // StoragePartitionImplMap::Get(). Life span is controlled indirectly by BC. 50 // 51 // IOTS = CefIOThreadState 52 // Stores state for access on the IO thread. Life span is controlled by BC. 53 // 54 // 55 // Relationship diagram: 56 // ref = reference (CefRefPtr/scoped_refptr) 57 // own = ownership (std::unique_ptr) 58 // ptr = raw pointer 59 // 60 // BHI -ref-> RCI -ptr-> BC -own-> SPI, IOTS 61 // ^ 62 // BHI -own-> WC -ptr--/ 63 // 64 // 65 // How shutdown works: 66 // 1. AlloyBrowserHostImpl::DestroyBrowser is called on the UI thread after the 67 // browser is closed and deletes the WebContents. 68 // 1. AlloyBrowserHostImpl is destroyed on any thread when the last reference 69 // is released. 70 // 2. CefRequestContextImpl is destroyed (possibly asynchronously) on the UI 71 // thread when the last reference is released. 72 // 3. CefBrowserContext is destroyed on the UI thread when no longer needed 73 // by any CefRequestContextImpl (via RemoveCefRequestContext). 74 // 4. CefIOThreadState is destroyed asynchronously on the IO thread after 75 // the owning CefBrowserContext is destroyed. 76 */ 77 78 namespace content { 79 class BrowserContext; 80 } 81 82 class CefMediaRouterManager; 83 class CefRequestContextImpl; 84 class Profile; 85 86 // Main entry point for configuring behavior on a per-RequestContext basis. The 87 // content::BrowserContext represented by this class is passed to 88 // WebContents::Create in AlloyBrowserHostImpl::CreateInternal. Only accessed on 89 // the UI thread unless otherwise indicated. 90 class CefBrowserContext { 91 public: 92 // Returns the existing instance, if any, associated with the specified 93 // |cache_path|. 94 static CefBrowserContext* FromCachePath(const base::FilePath& cache_path); 95 96 // Returns the existing instance, if any, associated with the specified IDs. 97 // See comments on IsAssociatedContext() for usage. 98 static CefBrowserContext* FromIDs(int render_process_id, 99 int render_frame_id, 100 int frame_tree_node_id, 101 bool require_frame_match); 102 103 // Returns the underlying CefBrowserContext if any. 104 static CefBrowserContext* FromBrowserContext( 105 const content::BrowserContext* context); 106 static CefBrowserContext* FromProfile(const Profile* profile); 107 108 // Returns all existing CefBrowserContext. 109 static std::vector<CefBrowserContext*> GetAll(); 110 111 // Returns the content and chrome layer representations of the context. 112 virtual content::BrowserContext* AsBrowserContext() = 0; 113 virtual Profile* AsProfile() = 0; 114 115 // Returns true if the context is fully initialized. 116 virtual bool IsInitialized() const = 0; 117 118 // If the context is fully initialized execute |callback|, otherwise 119 // store it until the context is fully initialized. 120 virtual void StoreOrTriggerInitCallback(base::OnceClosure callback) = 0; 121 122 // Called from CefRequestContextImpl to track associated objects. This 123 // object will delete itself when the count reaches zero. 124 void AddCefRequestContext(CefRequestContextImpl* context); 125 virtual void RemoveCefRequestContext(CefRequestContextImpl* context); 126 127 // Called from CefRequestContextImpl::OnRenderFrameCreated. 128 void OnRenderFrameCreated(CefRequestContextImpl* request_context, 129 int render_process_id, 130 int render_frame_id, 131 int frame_tree_node_id, 132 bool is_main_frame, 133 bool is_guest_view); 134 135 // Called from CefRequestContextImpl::OnRenderFrameDeleted. 136 void OnRenderFrameDeleted(CefRequestContextImpl* request_context, 137 int render_process_id, 138 int render_frame_id, 139 int frame_tree_node_id, 140 bool is_main_frame, 141 bool is_guest_view); 142 143 // Returns the handler that matches the specified IDs. Pass -1 for unknown 144 // values. If |require_frame_match| is true only exact matches will be 145 // returned. If |require_frame_match| is false, and there is not an exact 146 // match, then the first handler for the same |render_process_id| will be 147 // returned. 148 CefRefPtr<CefRequestContextHandler> GetHandler( 149 int render_process_id, 150 int render_frame_id, 151 int frame_tree_node_id, 152 bool require_frame_match) const; 153 154 // Returns true if this context is associated with the specified IDs. Pass -1 155 // for unknown values. If |require_frame_match| is true only exact matches 156 // will qualify. If |require_frame_match| is false, and there is not an exact 157 // match, then any match for |render_process_id| will qualify. 158 bool IsAssociatedContext(int render_process_id, 159 int render_frame_id, 160 int frame_tree_node_id, 161 bool require_frame_match) const; 162 163 // Remember the plugin load decision for plugin status requests that arrive 164 // via CefPluginServiceFilter::IsPluginAvailable. 165 void AddPluginLoadDecision(int render_process_id, 166 const base::FilePath& plugin_path, 167 bool is_main_frame, 168 const url::Origin& main_frame_origin, 169 chrome::mojom::PluginStatus status); 170 bool HasPluginLoadDecision(int render_process_id, 171 const base::FilePath& plugin_path, 172 bool is_main_frame, 173 const url::Origin& main_frame_origin, 174 chrome::mojom::PluginStatus* status) const; 175 176 // Clear the plugin load decisions associated with |render_process_id|, or all 177 // plugin load decisions if |render_process_id| is -1. 178 void ClearPluginLoadDecision(int render_process_id); 179 180 // Called from CefRequestContextImpl methods of the same name. 181 void RegisterSchemeHandlerFactory(const CefString& scheme_name, 182 const CefString& domain_name, 183 CefRefPtr<CefSchemeHandlerFactory> factory); 184 void ClearSchemeHandlerFactories(); 185 // TODO(chrome-runtime): Make these extension methods pure virtual. 186 virtual void LoadExtension(const CefString& root_directory, 187 CefRefPtr<CefDictionaryValue> manifest, 188 CefRefPtr<CefExtensionHandler> handler, 189 CefRefPtr<CefRequestContext> loader_context); 190 virtual bool GetExtensions(std::vector<CefString>& extension_ids); 191 virtual CefRefPtr<CefExtension> GetExtension(const CefString& extension_id); 192 193 // Called from CefExtensionImpl::Unload(). 194 virtual bool UnloadExtension(const CefString& extension_id); 195 196 // Returns true if this context supports print preview. 197 virtual bool IsPrintPreviewSupported() const; 198 199 network::mojom::NetworkContext* GetNetworkContext(); 200 201 CefMediaRouterManager* GetMediaRouterManager(); 202 203 using CookieableSchemes = base::Optional<std::vector<std::string>>; 204 205 // Returns the schemes associated with this context specifically, or the 206 // global configuration if unset. 207 CookieableSchemes GetCookieableSchemes() const; 208 static CookieableSchemes GetGlobalCookieableSchemes(); 209 210 // These accessors are safe to call from any thread because the values don't 211 // change during this object's lifespan. settings()212 const CefRequestContextSettings& settings() const { return settings_; } cache_path()213 base::FilePath cache_path() const { return cache_path_; } iothread_state()214 scoped_refptr<CefIOThreadState> iothread_state() const { 215 return iothread_state_; 216 } 217 218 // Used to hold a WeakPtr reference to this this object. The Getter returns 219 // nullptr if this object has already been destroyed. 220 using Getter = base::RepeatingCallback<CefBrowserContext*()>; getter()221 Getter getter() const { return getter_; } 222 223 protected: 224 explicit CefBrowserContext(const CefRequestContextSettings& settings); 225 virtual ~CefBrowserContext(); 226 227 // Will be called immediately after this object is created. 228 virtual void Initialize(); 229 230 // Will be called immediately before this object is deleted. 231 virtual void Shutdown(); 232 233 // Members initialized during construction or Initialize() are safe to access 234 // from any thread. 235 const CefRequestContextSettings settings_; 236 base::FilePath cache_path_; 237 238 private: 239 scoped_refptr<CefIOThreadState> iothread_state_; 240 CookieableSchemes cookieable_schemes_; 241 std::unique_ptr<CefMediaRouterManager> media_router_manager_; 242 243 // CefRequestContextImpl objects referencing this object. 244 std::set<CefRequestContextImpl*> request_context_set_; 245 246 // Map IDs to CefRequestContextHandler objects. 247 CefRequestContextHandlerMap handler_map_; 248 249 // Map (render_process_id, plugin_path, is_main_frame, main_frame_origin) to 250 // plugin load decision. 251 typedef std::map< 252 std::pair<std::pair<int, base::FilePath>, std::pair<bool, url::Origin>>, 253 chrome::mojom::PluginStatus> 254 PluginLoadDecisionMap; 255 PluginLoadDecisionMap plugin_load_decision_map_; 256 257 // Set of (render_process_id, render_frame_id) associated with this context. 258 typedef std::set<std::pair<int, int>> RenderIdSet; 259 RenderIdSet render_id_set_; 260 261 // Set of frame_tree_node_id associated with this context. Keeping this list 262 // is necessary because, when navigating the main frame, a new (pre-commit) 263 // network request will be created before the RenderFrameHost. Consequently we 264 // can't rely on valid render IDs. See https://crbug.com/776884 for 265 // background. 266 typedef std::set<int> NodeIdSet; 267 NodeIdSet node_id_set_; 268 269 #if DCHECK_IS_ON() 270 bool is_shutdown_ = false; 271 #endif 272 273 Getter getter_; 274 base::WeakPtrFactory<CefBrowserContext> weak_ptr_factory_; 275 276 DISALLOW_COPY_AND_ASSIGN(CefBrowserContext); 277 }; 278 279 #endif // CEF_LIBCEF_BROWSER_BROWSER_CONTEXT_IMPL_H_ 280