mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Simplify ownership of CefBrowserContext objects (issue #2083)
This commit is contained in:
		| @@ -15,25 +15,14 @@ | |||||||
| #include "content/public/browser/browser_thread.h" | #include "content/public/browser/browser_thread.h" | ||||||
| #include "content/public/browser/storage_partition.h" | #include "content/public/browser/storage_partition.h" | ||||||
|  |  | ||||||
| #if DCHECK_IS_ON() |  | ||||||
| base::AtomicRefCount CefBrowserContext::DebugObjCt = 0; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| CefBrowserContext::CefBrowserContext(bool is_proxy) | CefBrowserContext::CefBrowserContext(bool is_proxy) | ||||||
|     : is_proxy_(is_proxy), |     : is_proxy_(is_proxy), | ||||||
|       extension_system_(NULL) { |       extension_system_(NULL) { | ||||||
| #if DCHECK_IS_ON() |  | ||||||
|   base::AtomicRefCountInc(&DebugObjCt); |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| CefBrowserContext::~CefBrowserContext() { | CefBrowserContext::~CefBrowserContext() { | ||||||
|   // Should be cleared in Shutdown(). |   // Should be cleared in Shutdown(). | ||||||
|   DCHECK(!resource_context_.get()); |   DCHECK(!resource_context_.get()); | ||||||
|  |  | ||||||
| #if DCHECK_IS_ON() |  | ||||||
|   base::AtomicRefCountDec(&DebugObjCt); |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserContext::Initialize() { | void CefBrowserContext::Initialize() { | ||||||
| @@ -129,28 +118,27 @@ void CefBrowserContext::OnRenderFrameDeleted(int render_process_id, | |||||||
|                                              int render_frame_id, |                                              int render_frame_id, | ||||||
|                                              bool is_main_frame, |                                              bool is_main_frame, | ||||||
|                                              bool is_guest_view) { |                                              bool is_guest_view) { | ||||||
|   CEF_POST_TASK(CEF_IOT, |   CEF_REQUIRE_UIT(); | ||||||
|       base::Bind(&CefBrowserContext::RenderFrameDeletedOnIOThread, this, |  | ||||||
|                  render_process_id, render_frame_id, is_main_frame, |  | ||||||
|                  is_guest_view)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void CefBrowserContext::OnPurgePluginListCache() { |  | ||||||
|   CEF_POST_TASK(CEF_IOT, |  | ||||||
|       base::Bind(&CefBrowserContext::PurgePluginListCacheOnIOThread, this)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void CefBrowserContext::RenderFrameDeletedOnIOThread(int render_process_id, |  | ||||||
|                                                      int render_frame_id, |  | ||||||
|                                                      bool is_main_frame, |  | ||||||
|                                                      bool is_guest_view) { |  | ||||||
|   if (resource_context_ && is_main_frame) { |   if (resource_context_ && is_main_frame) { | ||||||
|     DCHECK_GE(render_process_id, 0); |     DCHECK_GE(render_process_id, 0); | ||||||
|     resource_context_->ClearPluginLoadDecision(render_process_id); |     // Using base::Unretained() is safe because both this callback and possible | ||||||
|  |     // deletion of |resource_context_| will execute on the IO thread, and this | ||||||
|  |     // callback will be executed first. | ||||||
|  |     CEF_POST_TASK(CEF_IOT, | ||||||
|  |         base::Bind(&CefResourceContext::ClearPluginLoadDecision, | ||||||
|  |                    base::Unretained(resource_context_.get()), | ||||||
|  |                    render_process_id)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserContext::PurgePluginListCacheOnIOThread() { | void CefBrowserContext::OnPurgePluginListCache() { | ||||||
|   if (resource_context_) |   CEF_REQUIRE_UIT(); | ||||||
|     resource_context_->ClearPluginLoadDecision(-1); |   if (resource_context_) { | ||||||
|  |     // Using base::Unretained() is safe because both this callback and possible | ||||||
|  |     // deletion of |resource_context_| will execute on the IO thread, and this | ||||||
|  |     // callback will be executed first. | ||||||
|  |     CEF_POST_TASK(CEF_IOT, | ||||||
|  |         base::Bind(&CefResourceContext::ClearPluginLoadDecision, | ||||||
|  |                    base::Unretained(resource_context_.get()), -1)); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,12 +33,12 @@ | |||||||
| // | // | ||||||
| // BCI = CefBrowserContextImpl | // BCI = CefBrowserContextImpl | ||||||
| //   Entry point from WC when using an isolated RCI. Owns the RC and creates the | //   Entry point from WC when using an isolated RCI. Owns the RC and creates the | ||||||
| //   SPI indirectly. Life span controlled by RCI and (for the global context) | //   SPI indirectly. Owned by CefBrowserMainParts for the global context or RCI | ||||||
| //   CefBrowserMainParts. | //   for non-global contexts. | ||||||
| // | // | ||||||
| // BCP = CefBrowserContextProxy | // BCP = CefBrowserContextProxy | ||||||
| //   Entry point from WC when using a custom RCI. Owns the RC and creates the | //   Entry point from WC when using a custom RCI. Owns the RC and creates the | ||||||
| //   URCGP and SPP. Life span controlled by RCI. | //   URCGP and SPP. Owned by RCI. | ||||||
| // | // | ||||||
| // SPI = content::StoragePartitionImpl | // SPI = content::StoragePartitionImpl | ||||||
| //   Owns storage-related objects like Quota, IndexedDB, Cache, etc. Created by | //   Owns storage-related objects like Quota, IndexedDB, Cache, etc. Created by | ||||||
| @@ -83,29 +83,29 @@ | |||||||
| // | // | ||||||
| // Relationship diagram: | // Relationship diagram: | ||||||
| //   ref = reference (CefRefPtr/scoped_refptr) | //   ref = reference (CefRefPtr/scoped_refptr) | ||||||
| //   own = ownership (scoped_ptr) | //   own = ownership (std::unique_ptr) | ||||||
| //   ptr = raw pointer | //   ptr = raw pointer | ||||||
| // | // | ||||||
| //                     CefBrowserMainParts----\   isolated cookie manager, etc. | //                     CefBrowserMainParts----\   isolated cookie manager, etc. | ||||||
| //                       |                     \             ^ | //                       |                     \             ^ | ||||||
| //                      ref                    ref        ref/own | //                      own                    ref        ref/own | ||||||
| //                       v                      v            | | //                       v                      v            | | ||||||
| //                /---> BCI -own-> SPI -ref-> URCGI --own-> URCI <-ptr-- CSP | //                /---> BCI -own-> SPI -ref-> URCGI --own-> URCI <-ptr-- CSP | ||||||
| //               /       ^          ^           ^                        ^ | //               /       ^          ^           ^                        ^ | ||||||
| //             ptr      ref        ptr         ref                      / | //             ptr      ptr        ptr         ref                      / | ||||||
| //             /         |          |           |                      / | //             /         |          |           |                      / | ||||||
| // BHI -own-> WC -ptr-> BCP -own-> SPP -ref-> URCGP -own-> URCP --ref-/ | // BHI -own-> WC -ptr-> BCP -own-> SPP -ref-> URCGP -own-> URCP --ref-/ | ||||||
| // | // | ||||||
| // BHI -ref-> RCI -ref-> BCI/BCP -own-> RC -ref-> URCGI/URCGP | // BHI -ref-> RCI -own-> BCI/BCP -own-> RC -ref-> URCGI/URCGP | ||||||
| // | // | ||||||
| // | // | ||||||
| // How shutdown works: | // How shutdown works: | ||||||
| // 1. CefBrowserHostImpl is destroyed on any thread due to browser close, | // 1. CefBrowserHostImpl is destroyed on any thread due to browser close, | ||||||
| //    ref release, etc. | //    ref release, etc. | ||||||
| // 2. CefRequestContextImpl is destroyed on any thread due to | // 2. CefRequestContextImpl is destroyed (possibly asynchronously) on the UI | ||||||
| //    CefBrowserHostImpl destruction, ref release, etc. | //    thread due to CefBrowserHostImpl destruction, ref release, etc. | ||||||
| // 3. CefBrowserContext* is destroyed on the UI thread due to | // 3. CefBrowserContext* is destroyed on the UI thread due to | ||||||
| //    CefRequestContextImpl destruction (*Impl, *Proxy) or ref release in | //    CefRequestContextImpl destruction (*Impl, *Proxy) or deletion in | ||||||
| //    CefBrowserMainParts::PostMainMessageLoopRun() (*Impl). | //    CefBrowserMainParts::PostMainMessageLoopRun() (*Impl). | ||||||
| // 4. CefResourceContext is destroyed asynchronously on the IO thread due to | // 4. CefResourceContext is destroyed asynchronously on the IO thread due to | ||||||
| //    CefBrowserContext* destruction. This cancels/destroys any pending | //    CefBrowserContext* destruction. This cancels/destroys any pending | ||||||
| @@ -128,10 +128,7 @@ class CefExtensionSystem; | |||||||
| // Main entry point for configuring behavior on a per-browser basis. An instance | // Main entry point for configuring behavior on a per-browser basis. An instance | ||||||
| // of this class is passed to WebContents::Create in CefBrowserHostImpl:: | // of this class is passed to WebContents::Create in CefBrowserHostImpl:: | ||||||
| // CreateInternal. Only accessed on the UI thread unless otherwise indicated. | // CreateInternal. Only accessed on the UI thread unless otherwise indicated. | ||||||
| class CefBrowserContext | class CefBrowserContext : public ChromeProfileStub { | ||||||
|     : public ChromeProfileStub, |  | ||||||
|       public base::RefCountedThreadSafe< |  | ||||||
|           CefBrowserContext, content::BrowserThread::DeleteOnUIThread> { |  | ||||||
|  public: |  public: | ||||||
|   explicit CefBrowserContext(bool is_proxy); |   explicit CefBrowserContext(bool is_proxy); | ||||||
|  |  | ||||||
| @@ -183,10 +180,9 @@ class CefBrowserContext | |||||||
|     return extension_system_; |     return extension_system_; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #if DCHECK_IS_ON() |   bool is_proxy() const { | ||||||
|   // Simple tracking of allocated objects. |     return is_proxy_; | ||||||
|   static base::AtomicRefCount DebugObjCt;  // NOLINT(runtime/int) |   } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   ~CefBrowserContext() override; |   ~CefBrowserContext() override; | ||||||
| @@ -195,17 +191,6 @@ class CefBrowserContext | |||||||
|   void Shutdown(); |   void Shutdown(); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // Only allow deletion via scoped_refptr(). |  | ||||||
|   friend struct content::BrowserThread::DeleteOnThread< |  | ||||||
|       content::BrowserThread::UI>; |  | ||||||
|   friend class base::DeleteHelper<CefBrowserContext>; |  | ||||||
|  |  | ||||||
|   void RenderFrameDeletedOnIOThread(int render_process_id, |  | ||||||
|                                     int render_frame_id, |  | ||||||
|                                     bool is_main_frame, |  | ||||||
|                                     bool is_guest_view); |  | ||||||
|   void PurgePluginListCacheOnIOThread(); |  | ||||||
|  |  | ||||||
|   // True if this CefBrowserContext is a CefBrowserContextProxy. |   // True if this CefBrowserContext is a CefBrowserContextProxy. | ||||||
|   const bool is_proxy_; |   const bool is_proxy_; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #include <utility> | #include <utility> | ||||||
|  |  | ||||||
| #include "libcef/browser/browser_context_proxy.h" | #include "libcef/browser/browser_context_proxy.h" | ||||||
|  | #include "libcef/browser/content_browser_client.h" | ||||||
| #include "libcef/browser/context.h" | #include "libcef/browser/context.h" | ||||||
| #include "libcef/browser/download_manager_delegate.h" | #include "libcef/browser/download_manager_delegate.h" | ||||||
| #include "libcef/browser/extensions/extension_system.h" | #include "libcef/browser/extensions/extension_system.h" | ||||||
| @@ -85,9 +86,19 @@ class ImplManager { | |||||||
|       const content::BrowserContext* context) { |       const content::BrowserContext* context) { | ||||||
|     CEF_REQUIRE_UIT(); |     CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|  |     const CefBrowserContext* cef_context = | ||||||
|  |         static_cast<const CefBrowserContext*>(context); | ||||||
|  |     const CefBrowserContextImpl* cef_context_impl = nullptr; | ||||||
|  |     if (cef_context->is_proxy()) { | ||||||
|  |       cef_context_impl = | ||||||
|  |           static_cast<const CefBrowserContextProxy*>(cef_context)->parent(); | ||||||
|  |     } else { | ||||||
|  |       cef_context_impl = static_cast<const CefBrowserContextImpl*>(cef_context); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Vector::iterator it = all_.begin(); |     Vector::iterator it = all_.begin(); | ||||||
|     for (; it != all_.end(); ++it) { |     for (; it != all_.end(); ++it) { | ||||||
|       if (*it == context || (*it)->HasProxy(context)) |       if (*it == cef_context_impl) | ||||||
|         return *it; |         return *it; | ||||||
|     } |     } | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -139,6 +150,7 @@ base::LazyInstance<ImplManager> g_manager = LAZY_INSTANCE_INITIALIZER; | |||||||
| class CefVisitedLinkListener : public visitedlink::VisitedLinkMaster::Listener { | class CefVisitedLinkListener : public visitedlink::VisitedLinkMaster::Listener { | ||||||
|  public: |  public: | ||||||
|   CefVisitedLinkListener() { |   CefVisitedLinkListener() { | ||||||
|  |     DCHECK(listener_map_.empty()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void CreateListenerForContext(const CefBrowserContext* context) { |   void CreateListenerForContext(const CefBrowserContext* context) { | ||||||
| @@ -196,11 +208,18 @@ CefBrowserContextImpl::CefBrowserContextImpl( | |||||||
| } | } | ||||||
|  |  | ||||||
| CefBrowserContextImpl::~CefBrowserContextImpl() { | CefBrowserContextImpl::~CefBrowserContextImpl() { | ||||||
|  |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|  |   // No CefRequestContextImpl should be referencing this object any longer. | ||||||
|  |   DCHECK_EQ(request_context_count_, 0); | ||||||
|  |  | ||||||
|   // Unregister the context first to avoid re-entrancy during shutdown. |   // Unregister the context first to avoid re-entrancy during shutdown. | ||||||
|   g_manager.Get().RemoveImpl(this, cache_path_); |   g_manager.Get().RemoveImpl(this, cache_path_); | ||||||
|  |  | ||||||
|   Shutdown(); |   Shutdown(); | ||||||
|  |  | ||||||
|  |   visitedlink_listener_->RemoveListenerForContext(this); | ||||||
|  |  | ||||||
|   // The FontFamilyCache references the ProxyService so delete it before the |   // The FontFamilyCache references the ProxyService so delete it before the | ||||||
|   // ProxyService is deleted. |   // ProxyService is deleted. | ||||||
|   SetUserData(&kFontFamilyCacheKey, NULL); |   SetUserData(&kFontFamilyCacheKey, NULL); | ||||||
| @@ -281,48 +300,39 @@ void CefBrowserContextImpl::Initialize() { | |||||||
|  |  | ||||||
| void CefBrowserContextImpl::AddProxy(const CefBrowserContextProxy* proxy) { | void CefBrowserContextImpl::AddProxy(const CefBrowserContextProxy* proxy) { | ||||||
|   CEF_REQUIRE_UIT(); |   CEF_REQUIRE_UIT(); | ||||||
|   DCHECK(!HasProxy(proxy)); |  | ||||||
|   proxy_list_.push_back(proxy); |  | ||||||
|  |  | ||||||
|   visitedlink_listener_->CreateListenerForContext(proxy); |   visitedlink_listener_->CreateListenerForContext(proxy); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserContextImpl::RemoveProxy(const CefBrowserContextProxy* proxy) { | void CefBrowserContextImpl::RemoveProxy(const CefBrowserContextProxy* proxy) { | ||||||
|   CEF_REQUIRE_UIT(); |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|   visitedlink_listener_->RemoveListenerForContext(proxy); |   visitedlink_listener_->RemoveListenerForContext(proxy); | ||||||
|  |  | ||||||
|   bool found = false; |  | ||||||
|   ProxyList::iterator it = proxy_list_.begin(); |  | ||||||
|   for (; it != proxy_list_.end(); ++it) { |  | ||||||
|     if (*it == proxy) { |  | ||||||
|       proxy_list_.erase(it); |  | ||||||
|       found = true; |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   DCHECK(found); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefBrowserContextImpl::HasProxy( | void CefBrowserContextImpl::AddRequestContext() { | ||||||
|     const content::BrowserContext* context) const { |  | ||||||
|   CEF_REQUIRE_UIT(); |   CEF_REQUIRE_UIT(); | ||||||
|   ProxyList::const_iterator it = proxy_list_.begin(); |   request_context_count_++; | ||||||
|   for (; it != proxy_list_.end(); ++it) { | } | ||||||
|     if (*it == context) |  | ||||||
|       return true; | void CefBrowserContextImpl::RemoveRequestContext() { | ||||||
|  |   CEF_REQUIRE_UIT(); | ||||||
|  |   request_context_count_--; | ||||||
|  |   DCHECK_GE(request_context_count_, 0); | ||||||
|  |  | ||||||
|  |   // Delete non-global contexts when the reference count reaches zero. | ||||||
|  |   if (request_context_count_ == 0 && | ||||||
|  |       this != CefContentBrowserClient::Get()->browser_context()) { | ||||||
|  |     delete this; | ||||||
|   } |   } | ||||||
|   return false; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| scoped_refptr<CefBrowserContextImpl> CefBrowserContextImpl::GetForCachePath( | CefBrowserContextImpl* CefBrowserContextImpl::GetForCachePath( | ||||||
|     const base::FilePath& cache_path) { |     const base::FilePath& cache_path) { | ||||||
|   return g_manager.Get().GetImplForPath(cache_path); |   return g_manager.Get().GetImplForPath(cache_path); | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| CefRefPtr<CefBrowserContextImpl> CefBrowserContextImpl::GetForContext( | CefBrowserContextImpl* CefBrowserContextImpl::GetForContext( | ||||||
|     content::BrowserContext* context) { |     content::BrowserContext* context) { | ||||||
|   return g_manager.Get().GetImplForContext(context); |   return g_manager.Get().GetImplForContext(context); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,9 +25,9 @@ class VisitedLinkMaster; | |||||||
| } | } | ||||||
|  |  | ||||||
| // Isolated BrowserContext implementation. Life span is controlled by | // Isolated BrowserContext implementation. Life span is controlled by | ||||||
| // CefRequestContextImpl and (for the main context) CefBrowserMainParts. Only | // CefBrowserMainParts for the global context and CefRequestContextImpl | ||||||
| // accessed on the UI thread unless otherwise indicated. See browser_context.h | // for non-global contexts. Only accessed on the UI thread unless otherwise | ||||||
| // for an object relationship diagram. | // indicated. See browser_context.h for an object relationship diagram. | ||||||
| class CefBrowserContextImpl : public CefBrowserContext, | class CefBrowserContextImpl : public CefBrowserContext, | ||||||
|                               public visitedlink::VisitedLinkDelegate { |                               public visitedlink::VisitedLinkDelegate { | ||||||
|  public: |  public: | ||||||
| @@ -35,11 +35,11 @@ class CefBrowserContextImpl : public CefBrowserContext, | |||||||
|  |  | ||||||
|   // Returns the existing instance, if any, associated with the specified |   // Returns the existing instance, if any, associated with the specified | ||||||
|   // |cache_path|. |   // |cache_path|. | ||||||
|   static scoped_refptr<CefBrowserContextImpl> GetForCachePath( |   static CefBrowserContextImpl* GetForCachePath( | ||||||
|       const base::FilePath& cache_path); |       const base::FilePath& cache_path); | ||||||
|  |  | ||||||
|   // Returns the underlying CefBrowserContextImpl if any. |   // Returns the underlying CefBrowserContextImpl if any. | ||||||
|   static CefRefPtr<CefBrowserContextImpl> GetForContext( |   static CefBrowserContextImpl* GetForContext( | ||||||
|       content::BrowserContext* context); |       content::BrowserContext* context); | ||||||
|  |  | ||||||
|   // Returns all existing CefBrowserContextImpl. |   // Returns all existing CefBrowserContextImpl. | ||||||
| @@ -48,10 +48,14 @@ class CefBrowserContextImpl : public CefBrowserContext, | |||||||
|   // Must be called immediately after this object is created. |   // Must be called immediately after this object is created. | ||||||
|   void Initialize() override; |   void Initialize() override; | ||||||
|  |  | ||||||
|   // Track associated proxy objects. |   // Track associated CefBrowserContextProxy objects. | ||||||
|   void AddProxy(const CefBrowserContextProxy* proxy); |   void AddProxy(const CefBrowserContextProxy* proxy); | ||||||
|   void RemoveProxy(const CefBrowserContextProxy* proxy); |   void RemoveProxy(const CefBrowserContextProxy* proxy); | ||||||
|   bool HasProxy(const content::BrowserContext* context) const; |  | ||||||
|  |   // Track associated CefRequestContextImpl objects. If this object is a non- | ||||||
|  |   // global context then it will delete itself when the count reaches zero. | ||||||
|  |   void AddRequestContext(); | ||||||
|  |   void RemoveRequestContext(); | ||||||
|  |  | ||||||
|   // BrowserContext methods. |   // BrowserContext methods. | ||||||
|   base::FilePath GetPath() const override; |   base::FilePath GetPath() const override; | ||||||
| @@ -98,10 +102,8 @@ class CefBrowserContextImpl : public CefBrowserContext, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // Only allow deletion via scoped_refptr(). |   // Allow deletion via std::unique_ptr(). | ||||||
|   friend struct content::BrowserThread::DeleteOnThread< |   friend std::default_delete<CefBrowserContextImpl>; | ||||||
|       content::BrowserThread::UI>; |  | ||||||
|   friend class base::DeleteHelper<CefBrowserContextImpl>; |  | ||||||
|  |  | ||||||
|   ~CefBrowserContextImpl() override; |   ~CefBrowserContextImpl() override; | ||||||
|  |  | ||||||
| @@ -109,9 +111,8 @@ class CefBrowserContextImpl : public CefBrowserContext, | |||||||
|   CefRequestContextSettings settings_; |   CefRequestContextSettings settings_; | ||||||
|   base::FilePath cache_path_; |   base::FilePath cache_path_; | ||||||
|  |  | ||||||
|   // Not owned by this class. |   // Number of CefRequestContextImpl objects referencing this object. | ||||||
|   typedef std::vector<const CefBrowserContextProxy*> ProxyList; |   int request_context_count_ = 0; | ||||||
|   ProxyList proxy_list_; |  | ||||||
|  |  | ||||||
|   std::unique_ptr<PrefService> pref_service_; |   std::unique_ptr<PrefService> pref_service_; | ||||||
|   std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; |   std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; | ||||||
|   | |||||||
| @@ -59,16 +59,18 @@ bool ShouldProxyUserData(const void* key) { | |||||||
|  |  | ||||||
| CefBrowserContextProxy::CefBrowserContextProxy( | CefBrowserContextProxy::CefBrowserContextProxy( | ||||||
|     CefRefPtr<CefRequestContextHandler> handler, |     CefRefPtr<CefRequestContextHandler> handler, | ||||||
|     scoped_refptr<CefBrowserContextImpl> parent) |     CefBrowserContextImpl* parent) | ||||||
|     : CefBrowserContext(true), |     : CefBrowserContext(true), | ||||||
|       handler_(handler), |       handler_(handler), | ||||||
|       parent_(parent) { |       parent_(parent) { | ||||||
|   DCHECK(handler_.get()); |   DCHECK(handler_.get()); | ||||||
|   DCHECK(parent_.get()); |   DCHECK(parent_); | ||||||
|   parent_->AddProxy(this); |   parent_->AddProxy(this); | ||||||
| } | } | ||||||
|  |  | ||||||
| CefBrowserContextProxy::~CefBrowserContextProxy() { | CefBrowserContextProxy::~CefBrowserContextProxy() { | ||||||
|  |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|   Shutdown(); |   Shutdown(); | ||||||
|  |  | ||||||
|   parent_->RemoveProxy(this); |   parent_->RemoveProxy(this); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ class CefStoragePartitionProxy; | |||||||
| class CefBrowserContextProxy : public CefBrowserContext { | class CefBrowserContextProxy : public CefBrowserContext { | ||||||
|  public: |  public: | ||||||
|   CefBrowserContextProxy(CefRefPtr<CefRequestContextHandler> handler, |   CefBrowserContextProxy(CefRefPtr<CefRequestContextHandler> handler, | ||||||
|                          scoped_refptr<CefBrowserContextImpl> parent); |                          CefBrowserContextImpl* parent); | ||||||
|  |  | ||||||
|   // Must be called immediately after this object is created. |   // Must be called immediately after this object is created. | ||||||
|   void Initialize() override; |   void Initialize() override; | ||||||
| @@ -67,21 +67,19 @@ class CefBrowserContextProxy : public CefBrowserContext { | |||||||
|   content::StoragePartition* GetOrCreateStoragePartitionProxy( |   content::StoragePartition* GetOrCreateStoragePartitionProxy( | ||||||
|     content::StoragePartition* partition_impl); |     content::StoragePartition* partition_impl); | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContextImpl> parent() const { |   CefBrowserContextImpl* parent() const { | ||||||
|     return parent_; |     return parent_; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   // Only allow deletion via scoped_refptr(). |   // Allow deletion via std::unique_ptr() only. | ||||||
|   friend struct content::BrowserThread::DeleteOnThread< |   friend std::default_delete<CefBrowserContextProxy>; | ||||||
|       content::BrowserThread::UI>; |  | ||||||
|   friend class base::DeleteHelper<CefBrowserContextProxy>; |  | ||||||
|  |  | ||||||
|   ~CefBrowserContextProxy() override; |   ~CefBrowserContextProxy() override; | ||||||
|  |  | ||||||
|   // Members initialized during construction are safe to access from any thread. |   // Members initialized during construction are safe to access from any thread. | ||||||
|   CefRefPtr<CefRequestContextHandler> handler_; |   CefRefPtr<CefRequestContextHandler> handler_; | ||||||
|   scoped_refptr<CefBrowserContextImpl> parent_; |   CefBrowserContextImpl* parent_;  // Guaranteed to outlive this object. | ||||||
|  |  | ||||||
|   std::unique_ptr<CefDownloadManagerDelegate> download_manager_delegate_; |   std::unique_ptr<CefDownloadManagerDelegate> download_manager_delegate_; | ||||||
|   std::unique_ptr<CefStoragePartitionProxy> storage_partition_proxy_; |   std::unique_ptr<CefStoragePartitionProxy> storage_partition_proxy_; | ||||||
|   | |||||||
| @@ -281,10 +281,10 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create( | |||||||
|  |  | ||||||
|   // Get or create the request context and browser context. |   // Get or create the request context and browser context. | ||||||
|   CefRefPtr<CefRequestContextImpl> request_context_impl = |   CefRefPtr<CefRequestContextImpl> request_context_impl = | ||||||
|       CefRequestContextImpl::GetForRequestContext( |       CefRequestContextImpl::GetOrCreateForRequestContext( | ||||||
|           create_params.request_context); |           create_params.request_context); | ||||||
|   DCHECK(request_context_impl); |   DCHECK(request_context_impl); | ||||||
|   scoped_refptr<CefBrowserContext> browser_context = |   CefBrowserContext* browser_context = | ||||||
|       request_context_impl->GetBrowserContext(); |       request_context_impl->GetBrowserContext(); | ||||||
|   DCHECK(browser_context); |   DCHECK(browser_context); | ||||||
|  |  | ||||||
| @@ -298,8 +298,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create( | |||||||
|     create_params.request_context = request_context_impl.get(); |     create_params.request_context = request_context_impl.get(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   content::WebContents::CreateParams wc_create_params( |   content::WebContents::CreateParams wc_create_params(browser_context); | ||||||
|       browser_context.get()); |  | ||||||
|  |  | ||||||
|   if (platform_delegate->IsWindowless()) { |   if (platform_delegate->IsWindowless()) { | ||||||
|     // Create the OSR view for the WebContents. |     // Create the OSR view for the WebContents. | ||||||
| @@ -692,13 +691,13 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) { | |||||||
|   if (!web_contents()) |   if (!web_contents()) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContext> context = |   CefBrowserContext* context = | ||||||
|       static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); |       static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); | ||||||
|   if (!context.get()) |   if (!context) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   content::DownloadManager* manager = |   content::DownloadManager* manager = | ||||||
|       content::BrowserContext::GetDownloadManager(context.get()); |       content::BrowserContext::GetDownloadManager(context); | ||||||
|   if (!manager) |   if (!manager) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
| @@ -2272,11 +2271,11 @@ void CefBrowserHostImpl::WebContentsCreated( | |||||||
|   CefRefPtr<CefBrowserHostImpl> opener = GetBrowserForContents(source_contents); |   CefRefPtr<CefBrowserHostImpl> opener = GetBrowserForContents(source_contents); | ||||||
|   DCHECK(opener.get()); |   DCHECK(opener.get()); | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContext> browser_context = |   CefBrowserContext* browser_context = | ||||||
|       static_cast<CefBrowserContext*>(new_contents->GetBrowserContext()); |       static_cast<CefBrowserContext*>(new_contents->GetBrowserContext()); | ||||||
|   DCHECK(browser_context.get()); |   DCHECK(browser_context); | ||||||
|   CefRefPtr<CefRequestContext> request_context = |   CefRefPtr<CefRequestContext> request_context = | ||||||
|       CefRequestContextImpl::GetForBrowserContext(browser_context).get(); |       CefRequestContextImpl::CreateForBrowserContext(browser_context).get(); | ||||||
|   DCHECK(request_context.get()); |   DCHECK(request_context.get()); | ||||||
|  |  | ||||||
|   CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::CreateInternal( |   CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::CreateInternal( | ||||||
| @@ -2406,7 +2405,7 @@ void CefBrowserHostImpl::RenderFrameDeleted( | |||||||
|  |  | ||||||
|   if (web_contents()) { |   if (web_contents()) { | ||||||
|     const bool is_main_frame = (render_frame_host->GetParent() == nullptr); |     const bool is_main_frame = (render_frame_host->GetParent() == nullptr); | ||||||
|     scoped_refptr<CefBrowserContext> context = |     CefBrowserContext* context = | ||||||
|         static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); |         static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); | ||||||
|     if (context) { |     if (context) { | ||||||
|       context->OnRenderFrameDeleted(render_process_id, render_routing_id, |       context->OnRenderFrameDeleted(render_process_id, render_routing_id, | ||||||
| @@ -2578,9 +2577,9 @@ void CefBrowserHostImpl::DidNavigateAnyFrame( | |||||||
|   if (!web_contents()) |   if (!web_contents()) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContext> context = |   CefBrowserContext* context = | ||||||
|       static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); |       static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext()); | ||||||
|   if (!context.get()) |   if (!context) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   context->AddVisitedURLs(params.redirects); |   context->AddVisitedURLs(params.redirects); | ||||||
|   | |||||||
| @@ -193,7 +193,7 @@ void CefBrowserMainParts::PreMainMessageLoopRun() { | |||||||
|   CefContext::Get()->PopulateRequestContextSettings(&settings); |   CefContext::Get()->PopulateRequestContextSettings(&settings); | ||||||
|  |  | ||||||
|   // Create the global BrowserContext. |   // Create the global BrowserContext. | ||||||
|   global_browser_context_ = new CefBrowserContextImpl(settings); |   global_browser_context_.reset(new CefBrowserContextImpl(settings)); | ||||||
|   global_browser_context_->Initialize(); |   global_browser_context_->Initialize(); | ||||||
|  |  | ||||||
|   CefDevToolsManagerDelegate::StartHttpHandler(global_browser_context_.get()); |   CefDevToolsManagerDelegate::StartHttpHandler(global_browser_context_.get()); | ||||||
| @@ -212,7 +212,7 @@ void CefBrowserMainParts::PostMainMessageLoopRun() { | |||||||
|   // NOTE: Destroy objects in reverse order of creation. |   // NOTE: Destroy objects in reverse order of creation. | ||||||
|   CefDevToolsManagerDelegate::StopHttpHandler(); |   CefDevToolsManagerDelegate::StopHttpHandler(); | ||||||
|  |  | ||||||
|   global_browser_context_ = NULL; |   global_browser_context_.reset(nullptr); | ||||||
|  |  | ||||||
|   if (extensions::ExtensionsEnabled()) { |   if (extensions::ExtensionsEnabled()) { | ||||||
|     extensions::ExtensionsBrowserClient::Set(NULL); |     extensions::ExtensionsBrowserClient::Set(NULL); | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
| #define CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_ | #define CEF_LIBCEF_BROWSER_BROWSER_MAIN_H_ | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "libcef/browser/browser_context_impl.h" |  | ||||||
| #include "libcef/browser/net/url_request_context_getter_impl.h" | #include "libcef/browser/net/url_request_context_getter_impl.h" | ||||||
|  |  | ||||||
| #include "base/macros.h" | #include "base/macros.h" | ||||||
| @@ -31,6 +30,7 @@ class ExtensionsBrowserClient; | |||||||
| class ExtensionsClient; | class ExtensionsClient; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | class CefBrowserContextImpl; | ||||||
| class CefDevToolsDelegate; | class CefDevToolsDelegate; | ||||||
|  |  | ||||||
| class CefBrowserMainParts : public content::BrowserMainParts { | class CefBrowserMainParts : public content::BrowserMainParts { | ||||||
| @@ -47,8 +47,8 @@ class CefBrowserMainParts : public content::BrowserMainParts { | |||||||
|   void PostMainMessageLoopRun() override; |   void PostMainMessageLoopRun() override; | ||||||
|   void PostDestroyThreads() override; |   void PostDestroyThreads() override; | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContextImpl> browser_context() const { |   CefBrowserContextImpl* browser_context() const { | ||||||
|     return global_browser_context_; |     return global_browser_context_.get(); | ||||||
|   } |   } | ||||||
|   CefDevToolsDelegate* devtools_delegate() const { |   CefDevToolsDelegate* devtools_delegate() const { | ||||||
|     return devtools_delegate_; |     return devtools_delegate_; | ||||||
| @@ -59,7 +59,7 @@ class CefBrowserMainParts : public content::BrowserMainParts { | |||||||
|   void PlatformInitialize(); |   void PlatformInitialize(); | ||||||
| #endif  // defined(OS_WIN) | #endif  // defined(OS_WIN) | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContextImpl> global_browser_context_; |   std::unique_ptr<CefBrowserContextImpl> global_browser_context_; | ||||||
|   CefDevToolsDelegate* devtools_delegate_;  // Deletes itself. |   CefDevToolsDelegate* devtools_delegate_;  // Deletes itself. | ||||||
|   std::unique_ptr<base::MessageLoop> message_loop_; |   std::unique_ptr<base::MessageLoop> message_loop_; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -190,11 +190,11 @@ class CefBrowserURLRequest::Context | |||||||
|  |  | ||||||
|     // Get or create the request context and browser context. |     // Get or create the request context and browser context. | ||||||
|     CefRefPtr<CefRequestContextImpl> request_context_impl = |     CefRefPtr<CefRequestContextImpl> request_context_impl = | ||||||
|         CefRequestContextImpl::GetForRequestContext(request_context_); |         CefRequestContextImpl::GetOrCreateForRequestContext(request_context_); | ||||||
|     DCHECK(request_context_impl.get()); |     DCHECK(request_context_impl.get()); | ||||||
|     scoped_refptr<CefBrowserContext> browser_context = |     CefBrowserContext* browser_context = | ||||||
|         request_context_impl->GetBrowserContext(); |         request_context_impl->GetBrowserContext(); | ||||||
|     DCHECK(browser_context.get()); |     DCHECK(browser_context); | ||||||
|  |  | ||||||
|     if (!request_context_.get()) |     if (!request_context_.get()) | ||||||
|       request_context_ = request_context_impl.get(); |       request_context_ = request_context_impl.get(); | ||||||
|   | |||||||
| @@ -360,7 +360,7 @@ ChromeBrowserProcessStub::GetPhysicalWebDataSource() { | |||||||
| content::BrowserContext* | content::BrowserContext* | ||||||
| ChromeBrowserProcessStub::GetBrowserContextRedirectedInIncognito( | ChromeBrowserProcessStub::GetBrowserContextRedirectedInIncognito( | ||||||
|     content::BrowserContext* context) { |     content::BrowserContext* context) { | ||||||
|   return CefBrowserContextImpl::GetForContext(context).get(); |   return CefBrowserContextImpl::GetForContext(context); | ||||||
| } | } | ||||||
|  |  | ||||||
| content::BrowserContext* | content::BrowserContext* | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ namespace { | |||||||
| // Return the main context for now since we don't currently have a good way to | // Return the main context for now since we don't currently have a good way to | ||||||
| // determine that. | // determine that. | ||||||
| CefBrowserContextImpl* GetActiveBrowserContext() { | CefBrowserContextImpl* GetActiveBrowserContext() { | ||||||
|   return CefContentBrowserClient::Get()->browser_context().get(); |   return CefContentBrowserClient::Get()->browser_context(); | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace | }  // namespace | ||||||
| @@ -35,7 +35,7 @@ ChromeProfileManagerStub::~ChromeProfileManagerStub() { | |||||||
|  |  | ||||||
| Profile* ChromeProfileManagerStub::GetProfile( | Profile* ChromeProfileManagerStub::GetProfile( | ||||||
|     const base::FilePath& profile_dir) { |     const base::FilePath& profile_dir) { | ||||||
|   scoped_refptr<CefBrowserContextImpl> browser_context = |   CefBrowserContextImpl* browser_context = | ||||||
|       CefBrowserContextImpl::GetForCachePath(profile_dir); |       CefBrowserContextImpl::GetForCachePath(profile_dir); | ||||||
|   if (!browser_context) { |   if (!browser_context) { | ||||||
|     // ProfileManager makes assumptions about profile directory paths that do |     // ProfileManager makes assumptions about profile directory paths that do | ||||||
| @@ -46,7 +46,7 @@ Profile* ChromeProfileManagerStub::GetProfile( | |||||||
|     // asking for. |     // asking for. | ||||||
|     browser_context = GetActiveBrowserContext(); |     browser_context = GetActiveBrowserContext(); | ||||||
|   } |   } | ||||||
|   return browser_context.get(); |   return browser_context; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool ChromeProfileManagerStub::IsValidProfile(const void* profile) { | bool ChromeProfileManagerStub::IsValidProfile(const void* profile) { | ||||||
| @@ -54,7 +54,7 @@ bool ChromeProfileManagerStub::IsValidProfile(const void* profile) { | |||||||
|     return false; |     return false; | ||||||
|   return !!CefBrowserContextImpl::GetForContext( |   return !!CefBrowserContextImpl::GetForContext( | ||||||
|       reinterpret_cast<content::BrowserContext*>( |       reinterpret_cast<content::BrowserContext*>( | ||||||
|           const_cast<void*>(profile))).get(); |           const_cast<void*>(profile))); | ||||||
| } | } | ||||||
|  |  | ||||||
| Profile* ChromeProfileManagerStub::GetLastUsedProfile( | Profile* ChromeProfileManagerStub::GetLastUsedProfile( | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <utility> | #include <utility> | ||||||
|  |  | ||||||
|  | #include "libcef/browser/browser_context.h" | ||||||
| #include "libcef/browser/browser_info.h" | #include "libcef/browser/browser_info.h" | ||||||
| #include "libcef/browser/browser_info_manager.h" | #include "libcef/browser/browser_info_manager.h" | ||||||
| #include "libcef/browser/browser_host_impl.h" | #include "libcef/browser/browser_host_impl.h" | ||||||
| @@ -42,6 +43,7 @@ | |||||||
| #include "base/json/json_reader.h" | #include "base/json/json_reader.h" | ||||||
| #include "base/path_service.h" | #include "base/path_service.h" | ||||||
| #include "cef/grit/cef_resources.h" | #include "cef/grit/cef_resources.h" | ||||||
|  | #include "chrome/browser/profiles/profile.h" | ||||||
| #include "chrome/browser/spellchecker/spellcheck_message_filter.h" | #include "chrome/browser/spellchecker/spellcheck_message_filter.h" | ||||||
| #include "chrome/common/chrome_switches.h" | #include "chrome/common/chrome_switches.h" | ||||||
| #include "components/navigation_interception/intercept_navigation_throttle.h" | #include "components/navigation_interception/intercept_navigation_throttle.h" | ||||||
| @@ -979,8 +981,7 @@ void CefContentBrowserClient::RegisterCustomScheme(const std::string& scheme) { | |||||||
|     policy->RegisterWebSafeScheme(scheme); |     policy->RegisterWebSafeScheme(scheme); | ||||||
| } | } | ||||||
|  |  | ||||||
| scoped_refptr<CefBrowserContextImpl> | CefBrowserContextImpl* CefContentBrowserClient::browser_context() const { | ||||||
| CefContentBrowserClient::browser_context() const { |  | ||||||
|   return browser_main_parts_->browser_context(); |   return browser_main_parts_->browser_context(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ | |||||||
| #include <utility> | #include <utility> | ||||||
|  |  | ||||||
| #include "include/cef_request_context_handler.h" | #include "include/cef_request_context_handler.h" | ||||||
| #include "libcef/browser/browser_context_impl.h" |  | ||||||
| #include "libcef/browser/net/url_request_context_getter_impl.h" | #include "libcef/browser/net/url_request_context_getter_impl.h" | ||||||
|  |  | ||||||
| #include "base/macros.h" | #include "base/macros.h" | ||||||
| @@ -20,6 +19,7 @@ | |||||||
| #include "third_party/skia/include/core/SkColor.h" | #include "third_party/skia/include/core/SkColor.h" | ||||||
|  |  | ||||||
| class CefBrowserMainParts; | class CefBrowserMainParts; | ||||||
|  | class CefBrowserContextImpl; | ||||||
| class CefDevToolsDelegate; | class CefDevToolsDelegate; | ||||||
| class CefResourceDispatcherHostDelegate; | class CefResourceDispatcherHostDelegate; | ||||||
|  |  | ||||||
| @@ -28,6 +28,10 @@ class PluginServiceFilter; | |||||||
| class SiteInstance; | class SiteInstance; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | namespace extensions { | ||||||
|  | class Extension; | ||||||
|  | } | ||||||
|  |  | ||||||
| class CefContentBrowserClient : public content::ContentBrowserClient { | class CefContentBrowserClient : public content::ContentBrowserClient { | ||||||
|  public: |  public: | ||||||
|   CefContentBrowserClient(); |   CefContentBrowserClient(); | ||||||
| @@ -113,7 +117,7 @@ class CefContentBrowserClient : public content::ContentBrowserClient { | |||||||
|   // Perform browser process registration for the custom scheme. |   // Perform browser process registration for the custom scheme. | ||||||
|   void RegisterCustomScheme(const std::string& scheme); |   void RegisterCustomScheme(const std::string& scheme); | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContextImpl> browser_context() const; |   CefBrowserContextImpl* browser_context() const; | ||||||
|   CefDevToolsDelegate* devtools_delegate() const; |   CefDevToolsDelegate* devtools_delegate() const; | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   | |||||||
| @@ -57,10 +57,10 @@ bool GetTabById(int tab_id, | |||||||
|     if (!request_context) |     if (!request_context) | ||||||
|       continue; |       continue; | ||||||
|     CefRefPtr<CefRequestContextImpl> request_context_impl = |     CefRefPtr<CefRequestContextImpl> request_context_impl = | ||||||
|         CefRequestContextImpl::GetForRequestContext(request_context); |         CefRequestContextImpl::GetOrCreateForRequestContext(request_context); | ||||||
|     if (!request_context_impl) |     if (!request_context_impl) | ||||||
|       continue; |       continue; | ||||||
|     scoped_refptr<CefBrowserContext> browser_context = |     CefBrowserContext* browser_context = | ||||||
|         request_context_impl->GetBrowserContext(); |         request_context_impl->GetBrowserContext(); | ||||||
|     if (!browser_context) |     if (!browser_context) | ||||||
|       continue; |       continue; | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ CefExtensionsAPIClient::CreateGuestViewManagerDelegate( | |||||||
|   // *Proxy object that has already been deleted. |   // *Proxy object that has already been deleted. | ||||||
|   return base::WrapUnique( |   return base::WrapUnique( | ||||||
|       new extensions::ExtensionsGuestViewManagerDelegate( |       new extensions::ExtensionsGuestViewManagerDelegate( | ||||||
|           CefBrowserContextImpl::GetForContext(context).get())); |           CefBrowserContextImpl::GetForContext(context))); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::unique_ptr<MimeHandlerViewGuestDelegate> | std::unique_ptr<MimeHandlerViewGuestDelegate> | ||||||
|   | |||||||
| @@ -64,8 +64,8 @@ bool CefExtensionsBrowserClient::IsSameContext(BrowserContext* first, | |||||||
|                                                BrowserContext* second) { |                                                BrowserContext* second) { | ||||||
|   // Returns true if |first| and |second| share the same underlying |   // Returns true if |first| and |second| share the same underlying | ||||||
|   // CefBrowserContextImpl. |   // CefBrowserContextImpl. | ||||||
|   return CefBrowserContextImpl::GetForContext(first).get() == |   return CefBrowserContextImpl::GetForContext(first) == | ||||||
|          CefBrowserContextImpl::GetForContext(second).get(); |          CefBrowserContextImpl::GetForContext(second); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefExtensionsBrowserClient::HasOffTheRecordContext( | bool CefExtensionsBrowserClient::HasOffTheRecordContext( | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
|  |  | ||||||
| #include "libcef/browser/extensions/mime_handler_view_guest_delegate.h" | #include "libcef/browser/extensions/mime_handler_view_guest_delegate.h" | ||||||
|  |  | ||||||
|  | #include "libcef/browser/browser_context.h" | ||||||
| #include "libcef/browser/browser_host_impl.h" | #include "libcef/browser/browser_host_impl.h" | ||||||
| #include "libcef/browser/browser_info.h" | #include "libcef/browser/browser_info.h" | ||||||
| #include "libcef/browser/content_browser_client.h" | #include "libcef/browser/content_browser_client.h" | ||||||
| @@ -91,7 +92,7 @@ void CefMimeHandlerViewGuestDelegate::OnGuestDetached( | |||||||
|   info->guest_render_id_manager()->remove_render_frame_id( |   info->guest_render_id_manager()->remove_render_frame_id( | ||||||
|       render_process_id, render_frame_id); |       render_process_id, render_frame_id); | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContext> context = |   CefBrowserContext* context = | ||||||
|       static_cast<CefBrowserContext*>(web_contents->GetBrowserContext()); |       static_cast<CefBrowserContext*>(web_contents->GetBrowserContext()); | ||||||
|   if (context) { |   if (context) { | ||||||
|     context->OnRenderFrameDeleted(render_process_id, render_frame_id, |     context->OnRenderFrameDeleted(render_process_id, render_frame_id, | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ struct ResolveHostHelper { | |||||||
|       resolved_ips.push_back(iter->ToStringWithoutPort()); |       resolved_ips.push_back(iter->ToStringWithoutPort()); | ||||||
|  |  | ||||||
|     CEF_POST_TASK(CEF_UIT, |     CEF_POST_TASK(CEF_UIT, | ||||||
|         base::Bind(&CefResolveCallback::OnResolveCompleted, callback_.get(), |         base::Bind(&CefResolveCallback::OnResolveCompleted, callback_, | ||||||
|                    static_cast<cef_errorcode_t>(result), resolved_ips)); |                    static_cast<cef_errorcode_t>(result), resolved_ips)); | ||||||
|  |  | ||||||
|     delete this; |     delete this; | ||||||
| @@ -88,8 +88,9 @@ CefRefPtr<CefRequestContext> CefRequestContext::GetGlobalContext() { | |||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return CefRequestContextImpl::GetForBrowserContext( |   CefRequestContextImpl::Config config; | ||||||
|       CefContentBrowserClient::Get()->browser_context()); |   config.is_global = true; | ||||||
|  |   return new CefRequestContextImpl(config); | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| @@ -102,7 +103,11 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext( | |||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return new CefRequestContextImpl(settings, handler); |   CefRequestContextImpl::Config config; | ||||||
|  |   config.settings = settings; | ||||||
|  |   config.handler = handler; | ||||||
|  |   config.unique_id = g_next_id.GetNext(); | ||||||
|  |   return new CefRequestContextImpl(config); | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| @@ -118,18 +123,31 @@ CefRefPtr<CefRequestContext> CefRequestContext::CreateContext( | |||||||
|   if (!other.get()) |   if (!other.get()) | ||||||
|     return NULL; |     return NULL; | ||||||
|  |  | ||||||
|   return new CefRequestContextImpl( |   CefRequestContextImpl::Config config; | ||||||
|       static_cast<CefRequestContextImpl*>(other.get()), handler); |   config.other = static_cast<CefRequestContextImpl*>(other.get()); | ||||||
|  |   config.handler = handler; | ||||||
|  |   config.unique_id = g_next_id.GetNext(); | ||||||
|  |   return new CefRequestContextImpl(config); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // CefBrowserContextImpl | // CefRequestContextImpl | ||||||
|  |  | ||||||
| CefRequestContextImpl::~CefRequestContextImpl() { | CefRequestContextImpl::~CefRequestContextImpl() { | ||||||
|  |   // Delete the proxy first because it also references |browser_context_impl_|. | ||||||
|  |   if (browser_context_proxy_) | ||||||
|  |     browser_context_proxy_.reset(nullptr); | ||||||
|  |  | ||||||
|  |   if (browser_context_impl_) { | ||||||
|  |     // May result in |browser_context_impl_| being deleted if it's not the | ||||||
|  |     // global context and no other CefRequestContextImpl are referencing it. | ||||||
|  |     browser_context_impl_->RemoveRequestContext(); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForRequestContext( | CefRefPtr<CefRequestContextImpl> | ||||||
|  | CefRequestContextImpl::GetOrCreateForRequestContext( | ||||||
|       CefRefPtr<CefRequestContext> request_context) { |       CefRefPtr<CefRequestContext> request_context) { | ||||||
|    if (request_context.get()) { |    if (request_context.get()) { | ||||||
|     // Use the context from the provided CefRequestContext. |     // Use the context from the provided CefRequestContext. | ||||||
| @@ -137,87 +155,27 @@ CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForRequestContext( | |||||||
|   } |   } | ||||||
|    |    | ||||||
|   // Use the global context. |   // Use the global context. | ||||||
|   scoped_refptr<CefBrowserContext> browser_context = |   CefRequestContextImpl::Config config; | ||||||
|       CefContentBrowserClient::Get()->browser_context(); |   config.is_global = true; | ||||||
|   return GetForBrowserContext(browser_context); |   return new CefRequestContextImpl(config); | ||||||
| } | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::GetForBrowserContext( | CefRefPtr<CefRequestContextImpl> CefRequestContextImpl::CreateForBrowserContext( | ||||||
|       scoped_refptr<CefBrowserContext> browser_context) { |       CefBrowserContext* browser_context) { | ||||||
|   DCHECK(browser_context.get()); |   DCHECK(browser_context); | ||||||
|   return new CefRequestContextImpl(browser_context); |   CefRequestContextImpl::Config config; | ||||||
|  |   config.handler = browser_context->GetHandler(); | ||||||
|  |   CefRefPtr<CefRequestContextImpl> impl = new CefRequestContextImpl(config); | ||||||
|  |   // Force immediate initialization because it's not safe to keep a raw pointer | ||||||
|  |   // to |browser_context|. | ||||||
|  |   impl->Initialize(browser_context); | ||||||
|  |   return impl; | ||||||
| } | } | ||||||
|  |  | ||||||
| scoped_refptr<CefBrowserContext> CefRequestContextImpl::GetBrowserContext() { | CefBrowserContext* CefRequestContextImpl::GetBrowserContext() { | ||||||
|   CEF_REQUIRE_UIT(); |   EnsureBrowserContext(); | ||||||
|  |   return browser_context(); | ||||||
|   if (!browser_context_) { |  | ||||||
|     scoped_refptr<CefBrowserContextImpl> parent; |  | ||||||
|  |  | ||||||
|     if (other_.get()) { |  | ||||||
|       // Share storage with |other_|. |  | ||||||
|       parent = CefBrowserContextImpl::GetForContext( |  | ||||||
|           other_->GetBrowserContext().get()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!parent.get()) { |  | ||||||
|       const base::FilePath& cache_path = |  | ||||||
|           base::FilePath(CefString(&settings_.cache_path)); |  | ||||||
|       if (!cache_path.empty()) { |  | ||||||
|         // Check if a CefBrowserContextImpl is already globally registered for |  | ||||||
|         // the specified cache path. If so then use it. |  | ||||||
|         parent = CefBrowserContextImpl::GetForCachePath(cache_path); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!parent.get()) { |  | ||||||
|       // Create a new CefBrowserContextImpl instance. If the cache path is non- |  | ||||||
|       // empty then this new instance will become the globally registered |  | ||||||
|       // CefBrowserContextImpl for that path. Otherwise, this new instance will |  | ||||||
|       // be a completely isolated "incongento mode" context. |  | ||||||
|       parent = new CefBrowserContextImpl(settings_); |  | ||||||
|       parent->Initialize(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // The parent's settings may be different. Force our settings to match the |  | ||||||
|     // parent. |  | ||||||
|     settings_ = parent->GetSettings(); |  | ||||||
|  |  | ||||||
|     if (handler_.get()) { |  | ||||||
|       // Use a proxy that will execute handler callbacks where appropriate and |  | ||||||
|       // otherwise forward all requests to the parent implementation. |  | ||||||
|       browser_context_ = new CefBrowserContextProxy(handler_, parent); |  | ||||||
|       browser_context_->Initialize(); |  | ||||||
|     } else { |  | ||||||
|       // Use the parent implementation directly. |  | ||||||
|       browser_context_ = parent; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     request_context_impl_ = parent->request_context().get(); |  | ||||||
|     DCHECK(request_context_impl_); |  | ||||||
|  |  | ||||||
|     if (handler_.get()) { |  | ||||||
|       // Keep the handler alive until the associated request context is |  | ||||||
|       // destroyed. |  | ||||||
|       request_context_impl_->AddHandler(handler_); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (!request_context_impl_) { |  | ||||||
|     request_context_impl_ = |  | ||||||
|         CefBrowserContextImpl::GetForContext(browser_context_.get())-> |  | ||||||
|             request_context().get(); |  | ||||||
|     DCHECK(request_context_impl_); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (other_.get()) { |  | ||||||
|     // Clear the reference to |other_| after setting |request_context_impl_|. |  | ||||||
|     // This is the reverse order of checks in IsSharedWith(). |  | ||||||
|     other_ = NULL; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return browser_context_; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRequestContextImpl::GetBrowserContext( | void CefRequestContextImpl::GetBrowserContext( | ||||||
| @@ -235,8 +193,8 @@ void CefRequestContextImpl::GetRequestContextImpl( | |||||||
|     task_runner = base::MessageLoop::current()->task_runner(); |     task_runner = base::MessageLoop::current()->task_runner(); | ||||||
|   if (request_context_impl_) { |   if (request_context_impl_) { | ||||||
|     // The browser context already exists. |     // The browser context already exists. | ||||||
|     DCHECK(browser_context_.get()); |     DCHECK(browser_context()); | ||||||
|     GetRequestContextImplOnIOThread(task_runner, callback, browser_context_); |     GetRequestContextImplOnIOThread(task_runner, callback, browser_context()); | ||||||
|   } else { |   } else { | ||||||
|     // Need to initialize the browser context first. |     // Need to initialize the browser context first. | ||||||
|     GetBrowserContextOnUIThread( |     GetBrowserContextOnUIThread( | ||||||
| @@ -252,14 +210,28 @@ bool CefRequestContextImpl::IsSame(CefRefPtr<CefRequestContext> other) { | |||||||
|   if (!other_impl) |   if (!other_impl) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|  |   // Compare whether both are the global context. | ||||||
|  |   if (config_.is_global && other_impl->config_.is_global) | ||||||
|  |     return true; | ||||||
|  |  | ||||||
|   // Compare CefBrowserContext pointers if one has been associated. |   // Compare CefBrowserContext pointers if one has been associated. | ||||||
|   if (browser_context_ && other_impl->browser_context_) |   if (browser_context() && other_impl->browser_context()) { | ||||||
|     return (browser_context_ == other_impl->browser_context_); |     if (browser_context()->is_proxy() && | ||||||
|   else if (browser_context_ || other_impl->browser_context_) |         other_impl->browser_context()->is_proxy()) { | ||||||
|  |       CefBrowserContextProxy* proxy = | ||||||
|  |           static_cast<CefBrowserContextProxy*>(browser_context()); | ||||||
|  |       CefBrowserContextProxy* other_proxy = | ||||||
|  |           static_cast<CefBrowserContextProxy*>(other_impl->browser_context()); | ||||||
|  |       return (proxy->parent() == other_proxy->parent() && | ||||||
|  |               proxy->GetHandler() == other_proxy->GetHandler()); | ||||||
|  |     } | ||||||
|  |     return (browser_context() == other_impl->browser_context()); | ||||||
|  |   } else if (browser_context() || other_impl->browser_context()) { | ||||||
|     return false; |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Otherwise compare unique IDs. |   // Otherwise compare unique IDs. | ||||||
|   return (unique_id_ == other_impl->unique_id_); |   return (config_.unique_id == other_impl->config_.unique_id); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) { | bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) { | ||||||
| @@ -271,14 +243,14 @@ bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) { | |||||||
|   if (IsSame(other)) |   if (IsSame(other)) | ||||||
|     return true; |     return true; | ||||||
|  |  | ||||||
|   CefRefPtr<CefRequestContext> pending_other = other_; |   CefRefPtr<CefRequestContext> pending_other = config_.other; | ||||||
|   if (pending_other.get()) { |   if (pending_other.get()) { | ||||||
|     // This object is not initialized but we know what context this object will |     // This object is not initialized but we know what context this object will | ||||||
|     // share with. Compare to that other context instead. |     // share with. Compare to that other context instead. | ||||||
|     return pending_other->IsSharingWith(other); |     return pending_other->IsSharingWith(other); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   pending_other = other_impl->other_; |   pending_other = other_impl->config_.other; | ||||||
|   if (pending_other.get()) { |   if (pending_other.get()) { | ||||||
|     // The other object is not initialized but we know what context that object |     // The other object is not initialized but we know what context that object | ||||||
|     // will share with. Compare to that other context instead. |     // will share with. Compare to that other context instead. | ||||||
| @@ -292,26 +264,26 @@ bool CefRequestContextImpl::IsSharingWith(CefRefPtr<CefRequestContext> other) { | |||||||
|  |  | ||||||
|   // This or the other object is not initialized. Compare the cache path values. |   // This or the other object is not initialized. Compare the cache path values. | ||||||
|   // If both are non-empty and the same then they'll share the same storage. |   // If both are non-empty and the same then they'll share the same storage. | ||||||
|   if (settings_.cache_path.length > 0 && |   if (config_.settings.cache_path.length > 0 && | ||||||
|       other_impl->settings_.cache_path.length > 0) { |       other_impl->config_.settings.cache_path.length > 0) { | ||||||
|     return (base::FilePath(CefString(&settings_.cache_path)) == |     return (base::FilePath(CefString(&config_.settings.cache_path)) == | ||||||
|             base::FilePath(CefString(&other_impl->settings_.cache_path))); |             base::FilePath( | ||||||
|  |                 CefString(&other_impl->config_.settings.cache_path))); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefRequestContextImpl::IsGlobal() { | bool CefRequestContextImpl::IsGlobal() { | ||||||
|   return (browser_context_ == |   return config_.is_global; | ||||||
|           CefContentBrowserClient::Get()->browser_context()); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| CefRefPtr<CefRequestContextHandler> CefRequestContextImpl::GetHandler() { | CefRefPtr<CefRequestContextHandler> CefRequestContextImpl::GetHandler() { | ||||||
|   return handler_; |   return config_.handler; | ||||||
| } | } | ||||||
|  |  | ||||||
| CefString CefRequestContextImpl::GetCachePath() { | CefString CefRequestContextImpl::GetCachePath() { | ||||||
|   return CefString(&settings_.cache_path); |   return CefString(&config_.settings.cache_path); | ||||||
| } | } | ||||||
|  |  | ||||||
| CefRefPtr<CefCookieManager> CefRequestContextImpl::GetDefaultCookieManager( | CefRefPtr<CefCookieManager> CefRequestContextImpl::GetDefaultCookieManager( | ||||||
| @@ -357,7 +329,7 @@ bool CefRequestContextImpl::HasPreference(const CefString& name) { | |||||||
|   // Make sure the browser context exists. |   // Make sure the browser context exists. | ||||||
|   EnsureBrowserContext(); |   EnsureBrowserContext(); | ||||||
|  |  | ||||||
|   PrefService* pref_service = browser_context_->GetPrefs(); |   PrefService* pref_service = browser_context()->GetPrefs(); | ||||||
|   return (pref_service->FindPreference(name) != NULL); |   return (pref_service->FindPreference(name) != NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -372,7 +344,7 @@ CefRefPtr<CefValue> CefRequestContextImpl::GetPreference( | |||||||
|   // Make sure the browser context exists. |   // Make sure the browser context exists. | ||||||
|   EnsureBrowserContext(); |   EnsureBrowserContext(); | ||||||
|  |  | ||||||
|   PrefService* pref_service = browser_context_->GetPrefs(); |   PrefService* pref_service = browser_context()->GetPrefs(); | ||||||
|   const PrefService::Preference* pref = pref_service->FindPreference(name); |   const PrefService::Preference* pref = pref_service->FindPreference(name); | ||||||
|   if (!pref) |   if (!pref) | ||||||
|     return NULL; |     return NULL; | ||||||
| @@ -390,7 +362,7 @@ CefRefPtr<CefDictionaryValue> CefRequestContextImpl::GetAllPreferences( | |||||||
|   // Make sure the browser context exists. |   // Make sure the browser context exists. | ||||||
|   EnsureBrowserContext(); |   EnsureBrowserContext(); | ||||||
|  |  | ||||||
|   PrefService* pref_service = browser_context_->GetPrefs(); |   PrefService* pref_service = browser_context()->GetPrefs(); | ||||||
|  |  | ||||||
|   std::unique_ptr<base::DictionaryValue> values; |   std::unique_ptr<base::DictionaryValue> values; | ||||||
|   if (include_defaults) |   if (include_defaults) | ||||||
| @@ -412,7 +384,7 @@ bool CefRequestContextImpl::CanSetPreference(const CefString& name) { | |||||||
|   // Make sure the browser context exists. |   // Make sure the browser context exists. | ||||||
|   EnsureBrowserContext(); |   EnsureBrowserContext(); | ||||||
|  |  | ||||||
|   PrefService* pref_service = browser_context_->GetPrefs(); |   PrefService* pref_service = browser_context()->GetPrefs(); | ||||||
|   const PrefService::Preference* pref = pref_service->FindPreference(name); |   const PrefService::Preference* pref = pref_service->FindPreference(name); | ||||||
|   return (pref && pref->IsUserModifiable()); |   return (pref && pref->IsUserModifiable()); | ||||||
| } | } | ||||||
| @@ -429,7 +401,7 @@ bool CefRequestContextImpl::SetPreference(const CefString& name, | |||||||
|   // Make sure the browser context exists. |   // Make sure the browser context exists. | ||||||
|   EnsureBrowserContext(); |   EnsureBrowserContext(); | ||||||
|  |  | ||||||
|   PrefService* pref_service = browser_context_->GetPrefs(); |   PrefService* pref_service = browser_context()->GetPrefs(); | ||||||
|  |  | ||||||
|   // The below validation logic should match PrefService::SetUserPrefValue. |   // The below validation logic should match PrefService::SetUserPrefValue. | ||||||
|  |  | ||||||
| @@ -530,35 +502,91 @@ cef_errorcode_t CefRequestContextImpl::ResolveHostCached( | |||||||
| } | } | ||||||
|  |  | ||||||
| CefRequestContextImpl::CefRequestContextImpl( | CefRequestContextImpl::CefRequestContextImpl( | ||||||
|     scoped_refptr<CefBrowserContext> browser_context) |     const CefRequestContextImpl::Config& config) | ||||||
|     : browser_context_(browser_context), |     : config_(config) { | ||||||
|       settings_(browser_context->GetSettings()), |  | ||||||
|       handler_(browser_context->GetHandler()), |  | ||||||
|       unique_id_(0), |  | ||||||
|       request_context_impl_(NULL) { |  | ||||||
| } | } | ||||||
|  |  | ||||||
| CefRequestContextImpl::CefRequestContextImpl( | void CefRequestContextImpl::Initialize() { | ||||||
|     const CefRequestContextSettings& settings, |   CefBrowserContext* other_browser_context = nullptr; | ||||||
|     CefRefPtr<CefRequestContextHandler> handler) |   if (config_.is_global) | ||||||
|     : settings_(settings), |     other_browser_context = CefContentBrowserClient::Get()->browser_context(); | ||||||
|       handler_(handler), |   else if (config_.other.get()) | ||||||
|       unique_id_(g_next_id.GetNext()), |     other_browser_context = config_.other->GetBrowserContext(); | ||||||
|       request_context_impl_(NULL) { |  | ||||||
|  |   Initialize(other_browser_context); | ||||||
|  |  | ||||||
|  |   if (config_.other.get()) { | ||||||
|  |     // Clear the reference to |other_| after setting |request_context_impl_|. | ||||||
|  |     // This is the reverse order of checks in IsSharedWith(). | ||||||
|  |     config_.other = NULL; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| CefRequestContextImpl::CefRequestContextImpl( | void CefRequestContextImpl::Initialize( | ||||||
|     CefRefPtr<CefRequestContextImpl> other, |     CefBrowserContext* other_browser_context) { | ||||||
|     CefRefPtr<CefRequestContextHandler> handler) |   CEF_REQUIRE_UIT(); | ||||||
|     : other_(other), |  | ||||||
|       handler_(handler), |   DCHECK(!browser_context_impl_); | ||||||
|       unique_id_(g_next_id.GetNext()), |   DCHECK(!request_context_impl_); | ||||||
|       request_context_impl_(NULL) { |  | ||||||
|  |   if (other_browser_context) { | ||||||
|  |     // Share storage with |other_browser_context|. | ||||||
|  |     browser_context_impl_ = CefBrowserContextImpl::GetForContext( | ||||||
|  |         other_browser_context); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!browser_context_impl_) { | ||||||
|  |     const base::FilePath& cache_path = | ||||||
|  |         base::FilePath(CefString(&config_.settings.cache_path)); | ||||||
|  |     if (!cache_path.empty()) { | ||||||
|  |       // Check if a CefBrowserContextImpl is already globally registered for | ||||||
|  |       // the specified cache path. If so then use it. | ||||||
|  |       browser_context_impl_ = | ||||||
|  |           CefBrowserContextImpl::GetForCachePath(cache_path); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!browser_context_impl_) { | ||||||
|  |     // Create a new CefBrowserContextImpl instance. If the cache path is non- | ||||||
|  |     // empty then this new instance will become the globally registered | ||||||
|  |     // CefBrowserContextImpl for that path. Otherwise, this new instance will | ||||||
|  |     // be a completely isolated "incongento mode" context. | ||||||
|  |     browser_context_impl_ = new CefBrowserContextImpl(config_.settings); | ||||||
|  |     browser_context_impl_->Initialize(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // We'll disassociate from |browser_context_impl_| on destruction. | ||||||
|  |   browser_context_impl_->AddRequestContext(); | ||||||
|  |  | ||||||
|  |   // Force our settings to match |browser_context_impl_|. | ||||||
|  |   config_.settings = browser_context_impl_->GetSettings(); | ||||||
|  |  | ||||||
|  |   if (config_.handler.get()) { | ||||||
|  |     // Use a proxy that will execute handler callbacks where appropriate and | ||||||
|  |     // otherwise forward all requests to |browser_context_impl_|. | ||||||
|  |     browser_context_proxy_.reset( | ||||||
|  |         new CefBrowserContextProxy(config_.handler, browser_context_impl_)); | ||||||
|  |     browser_context_proxy_->Initialize(); | ||||||
|  |     DCHECK(!config_.is_global); | ||||||
|  |   } else { | ||||||
|  |     config_.is_global = (browser_context_impl_ == | ||||||
|  |                          CefContentBrowserClient::Get()->browser_context()); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   request_context_impl_ = browser_context_impl_->request_context().get(); | ||||||
|  |   DCHECK(request_context_impl_); | ||||||
|  |  | ||||||
|  |   if (config_.handler.get()) { | ||||||
|  |     // Keep the handler alive until the associated request context is | ||||||
|  |     // destroyed. | ||||||
|  |     request_context_impl_->AddHandler(config_.handler); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRequestContextImpl::EnsureBrowserContext() { | void CefRequestContextImpl::EnsureBrowserContext() { | ||||||
|   GetBrowserContext(); |   if (!browser_context()) | ||||||
|   DCHECK(browser_context_.get()); |     Initialize(); | ||||||
|  |   DCHECK(browser_context()); | ||||||
|   DCHECK(request_context_impl_); |   DCHECK(request_context_impl_); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -577,17 +605,17 @@ void CefRequestContextImpl::GetBrowserContextOnUIThread( | |||||||
|  |  | ||||||
|   if (task_runner->BelongsToCurrentThread()) { |   if (task_runner->BelongsToCurrentThread()) { | ||||||
|     // Execute the callback immediately. |     // Execute the callback immediately. | ||||||
|     callback.Run(browser_context_); |     callback.Run(browser_context()); | ||||||
|   } else { |   } else { | ||||||
|     // Execute the callback on the target thread. |     // Execute the callback on the target thread. | ||||||
|     task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context_)); |     task_runner->PostTask(FROM_HERE, base::Bind(callback, browser_context())); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRequestContextImpl::GetRequestContextImplOnIOThread( | void CefRequestContextImpl::GetRequestContextImplOnIOThread( | ||||||
|     scoped_refptr<base::SingleThreadTaskRunner> task_runner, |     scoped_refptr<base::SingleThreadTaskRunner> task_runner, | ||||||
|     const RequestContextCallback& callback, |     const RequestContextCallback& callback, | ||||||
|     scoped_refptr<CefBrowserContext> browser_context) { |     CefBrowserContext* browser_context) { | ||||||
|   if (!CEF_CURRENTLY_ON_IOT()) { |   if (!CEF_CURRENTLY_ON_IOT()) { | ||||||
|     CEF_POST_TASK(CEF_IOT, |     CEF_POST_TASK(CEF_IOT, | ||||||
|         base::Bind(&CefRequestContextImpl::GetRequestContextImplOnIOThread, |         base::Bind(&CefRequestContextImpl::GetRequestContextImplOnIOThread, | ||||||
| @@ -628,16 +656,16 @@ void CefRequestContextImpl::ClearSchemeHandlerFactoriesInternal( | |||||||
|  |  | ||||||
| void CefRequestContextImpl::PurgePluginListCacheInternal( | void CefRequestContextImpl::PurgePluginListCacheInternal( | ||||||
|     bool reload_pages, |     bool reload_pages, | ||||||
|     scoped_refptr<CefBrowserContext> browser_context) { |     CefBrowserContext* browser_context) { | ||||||
|   CEF_REQUIRE_UIT(); |   CEF_REQUIRE_UIT(); | ||||||
|   browser_context->OnPurgePluginListCache(); |   browser_context->OnPurgePluginListCache(); | ||||||
|   content::PluginService::GetInstance()->PurgePluginListCache( |   content::PluginService::GetInstance()->PurgePluginListCache( | ||||||
|       browser_context.get(), false); |       browser_context, false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRequestContextImpl::ClearCertificateExceptionsInternal( | void CefRequestContextImpl::ClearCertificateExceptionsInternal( | ||||||
|     CefRefPtr<CefCompletionCallback> callback, |     CefRefPtr<CefCompletionCallback> callback, | ||||||
|     scoped_refptr<CefBrowserContext> browser_context) { |     CefBrowserContext* browser_context) { | ||||||
|   CEF_REQUIRE_UIT(); |   CEF_REQUIRE_UIT(); | ||||||
|  |  | ||||||
|   content::SSLHostStateDelegate* ssl_delegate = |   content::SSLHostStateDelegate* ssl_delegate = | ||||||
| @@ -647,7 +675,7 @@ void CefRequestContextImpl::ClearCertificateExceptionsInternal( | |||||||
|  |  | ||||||
|   if (callback) { |   if (callback) { | ||||||
|     CEF_POST_TASK(CEF_UIT, |     CEF_POST_TASK(CEF_UIT, | ||||||
|         base::Bind(&CefCompletionCallback::OnComplete, callback.get())); |         base::Bind(&CefCompletionCallback::OnComplete, callback)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -669,7 +697,7 @@ void CefRequestContextImpl::CloseAllConnectionsInternal( | |||||||
|  |  | ||||||
|   if (callback) { |   if (callback) { | ||||||
|     CEF_POST_TASK(CEF_UIT, |     CEF_POST_TASK(CEF_UIT, | ||||||
|         base::Bind(&CefCompletionCallback::OnComplete, callback.get())); |         base::Bind(&CefCompletionCallback::OnComplete, callback)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -702,3 +730,10 @@ void CefRequestContextImpl::ResolveHostInternal( | |||||||
|  |  | ||||||
|   helper->OnResolveCompleted(retval); |   helper->OnResolveCompleted(retval); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CefBrowserContext* CefRequestContextImpl::browser_context() const { | ||||||
|  |   if (browser_context_proxy_) | ||||||
|  |     return browser_context_proxy_.get(); | ||||||
|  |   return browser_context_impl_; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,32 +8,35 @@ | |||||||
|  |  | ||||||
| #include "include/cef_request_context.h" | #include "include/cef_request_context.h" | ||||||
| #include "libcef/browser/browser_context.h" | #include "libcef/browser/browser_context.h" | ||||||
|  | #include "libcef/browser/thread_util.h" | ||||||
|  |  | ||||||
|  | class CefBrowserContextImpl; | ||||||
|  | class CefBrowserContextProxy; | ||||||
|  |  | ||||||
| // Implementation of the CefRequestContext interface. All methods are thread- | // Implementation of the CefRequestContext interface. All methods are thread- | ||||||
| // safe unless otherwise indicated. | // safe unless otherwise indicated. Will be deleted on the UI thread. | ||||||
| class CefRequestContextImpl : public CefRequestContext { | class CefRequestContextImpl : public CefRequestContext { | ||||||
|  public: |  public: | ||||||
|   ~CefRequestContextImpl() override; |   ~CefRequestContextImpl() override; | ||||||
|  |  | ||||||
|   // Returns a CefRequestContextImpl for the specified |request_context|. |   // Returns a CefRequestContextImpl for the specified |request_context|. | ||||||
|   // Will return the global context if |request_context| is NULL. |   // Will return the global context if |request_context| is NULL. | ||||||
|   static CefRefPtr<CefRequestContextImpl> GetForRequestContext( |   static CefRefPtr<CefRequestContextImpl> GetOrCreateForRequestContext( | ||||||
|       CefRefPtr<CefRequestContext> request_context); |       CefRefPtr<CefRequestContext> request_context); | ||||||
|  |  | ||||||
|   // Returns a CefRequestContextImpl for the specified |browser_context|. |   // Returns a CefRequestContextImpl for the specified |browser_context|. | ||||||
|   // |browser_context| must be non-NULL. |   // |browser_context| must be non-NULL. | ||||||
|   static CefRefPtr<CefRequestContextImpl> GetForBrowserContext( |   static CefRefPtr<CefRequestContextImpl> CreateForBrowserContext( | ||||||
|       scoped_refptr<CefBrowserContext> browser_context); |       CefBrowserContext* browser_context); | ||||||
|  |  | ||||||
|   // Returns the browser context object. Can only be called on the UI thread. |   // Returns the browser context object. Can only be called on the UI thread. | ||||||
|   scoped_refptr<CefBrowserContext> GetBrowserContext(); |   CefBrowserContext* GetBrowserContext(); | ||||||
|  |  | ||||||
|   // Executes |callback| either synchronously or asynchronously with the browser |   // Executes |callback| either synchronously or asynchronously with the browser | ||||||
|   // context object when it's available. If |task_runner| is NULL the callback |   // context object when it's available. If |task_runner| is NULL the callback | ||||||
|   // will be executed on the originating thread. The resulting context object |   // will be executed on the originating thread. The resulting context object | ||||||
|   // can only be accessed on the UI thread. |   // can only be accessed on the UI thread. | ||||||
|   typedef base::Callback<void(scoped_refptr<CefBrowserContext>)> |   typedef base::Callback<void(CefBrowserContext*)> BrowserContextCallback; | ||||||
|       BrowserContextCallback; |  | ||||||
|   void GetBrowserContext( |   void GetBrowserContext( | ||||||
|       scoped_refptr<base::SingleThreadTaskRunner> task_runner, |       scoped_refptr<base::SingleThreadTaskRunner> task_runner, | ||||||
|       const BrowserContextCallback& callback); |       const BrowserContextCallback& callback); | ||||||
| @@ -79,17 +82,36 @@ class CefRequestContextImpl : public CefRequestContext { | |||||||
|       const CefString& origin, |       const CefString& origin, | ||||||
|       std::vector<CefString>& resolved_ips) override; |       std::vector<CefString>& resolved_ips) override; | ||||||
|  |  | ||||||
|   const CefRequestContextSettings& settings() const { return settings_; } |   const CefRequestContextSettings& settings() const { return config_.settings; } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   friend class CefRequestContext; |   friend class CefRequestContext; | ||||||
|  |  | ||||||
|   explicit CefRequestContextImpl( |   struct Config { | ||||||
|       scoped_refptr<CefBrowserContext> browser_context); |     // True if wrapping the global context. | ||||||
|   CefRequestContextImpl(const CefRequestContextSettings& settings, |     bool is_global = false; | ||||||
|                         CefRefPtr<CefRequestContextHandler> handler); |  | ||||||
|   CefRequestContextImpl(CefRefPtr<CefRequestContextImpl> other, |     // |settings| or |other| will be set when creating a new CefRequestContext | ||||||
|                         CefRefPtr<CefRequestContextHandler> handler); |     // via the API. When wrapping an existing CefBrowserContext* both will be | ||||||
|  |     // empty and Initialize(CefBrowserContext*) will be called immediately after | ||||||
|  |     // CefRequestContextImpl construction. | ||||||
|  |     CefRequestContextSettings settings; | ||||||
|  |     CefRefPtr<CefRequestContextImpl> other; | ||||||
|  |  | ||||||
|  |     // Optionally use this handler, in which case a CefBrowserContextProxy will | ||||||
|  |     // be created. | ||||||
|  |     CefRefPtr<CefRequestContextHandler> handler; | ||||||
|  |  | ||||||
|  |     // Used to uniquely identify CefRequestContext objects before an associated | ||||||
|  |     // CefBrowserContext has been created. Should be set when a new | ||||||
|  |     // CefRequestContext via the API. | ||||||
|  |     int unique_id = -1; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   explicit CefRequestContextImpl(const Config& config); | ||||||
|  |  | ||||||
|  |   void Initialize(); | ||||||
|  |   void Initialize(CefBrowserContext* other_browser_context); | ||||||
|  |  | ||||||
|   // Make sure the browser context exists. Only called on the UI thread. |   // Make sure the browser context exists. Only called on the UI thread. | ||||||
|   void EnsureBrowserContext(); |   void EnsureBrowserContext(); | ||||||
| @@ -100,7 +122,7 @@ class CefRequestContextImpl : public CefRequestContext { | |||||||
|   void GetRequestContextImplOnIOThread( |   void GetRequestContextImplOnIOThread( | ||||||
|       scoped_refptr<base::SingleThreadTaskRunner> task_runner, |       scoped_refptr<base::SingleThreadTaskRunner> task_runner, | ||||||
|       const RequestContextCallback& callback, |       const RequestContextCallback& callback, | ||||||
|       scoped_refptr<CefBrowserContext> browser_context); |       CefBrowserContext* browser_context); | ||||||
|  |  | ||||||
|   void RegisterSchemeHandlerFactoryInternal( |   void RegisterSchemeHandlerFactoryInternal( | ||||||
|       const CefString& scheme_name, |       const CefString& scheme_name, | ||||||
| @@ -111,10 +133,10 @@ class CefRequestContextImpl : public CefRequestContext { | |||||||
|       scoped_refptr<CefURLRequestContextGetterImpl> request_context); |       scoped_refptr<CefURLRequestContextGetterImpl> request_context); | ||||||
|   void PurgePluginListCacheInternal( |   void PurgePluginListCacheInternal( | ||||||
|       bool reload_pages, |       bool reload_pages, | ||||||
|       scoped_refptr<CefBrowserContext> browser_context); |       CefBrowserContext* browser_context); | ||||||
|   void ClearCertificateExceptionsInternal( |   void ClearCertificateExceptionsInternal( | ||||||
|       CefRefPtr<CefCompletionCallback> callback, |       CefRefPtr<CefCompletionCallback> callback, | ||||||
|       scoped_refptr<CefBrowserContext> browser_context); |       CefBrowserContext* browser_context); | ||||||
|   void CloseAllConnectionsInternal( |   void CloseAllConnectionsInternal( | ||||||
|       CefRefPtr<CefCompletionCallback> callback, |       CefRefPtr<CefCompletionCallback> callback, | ||||||
|       scoped_refptr<CefURLRequestContextGetterImpl> request_context); |       scoped_refptr<CefURLRequestContextGetterImpl> request_context); | ||||||
| @@ -123,19 +145,19 @@ class CefRequestContextImpl : public CefRequestContext { | |||||||
|       CefRefPtr<CefResolveCallback> callback, |       CefRefPtr<CefResolveCallback> callback, | ||||||
|       scoped_refptr<CefURLRequestContextGetterImpl> request_context); |       scoped_refptr<CefURLRequestContextGetterImpl> request_context); | ||||||
|  |  | ||||||
|   scoped_refptr<CefBrowserContext> browser_context_; |   CefBrowserContext* browser_context() const; | ||||||
|   CefRequestContextSettings settings_; |  | ||||||
|   CefRefPtr<CefRequestContextImpl> other_; |  | ||||||
|   CefRefPtr<CefRequestContextHandler> handler_; |  | ||||||
|  |  | ||||||
|   // Used to uniquely identify CefRequestContext objects before an associated |   // If *Impl then we must disassociate from it on destruction. | ||||||
|   // CefBrowserContext has been created. |   CefBrowserContextImpl* browser_context_impl_ = nullptr; | ||||||
|   int unique_id_; |   // If *Proxy then we own it. | ||||||
|  |   std::unique_ptr<CefBrowserContextProxy> browser_context_proxy_; | ||||||
|  |  | ||||||
|  |   Config config_; | ||||||
|  |  | ||||||
|   // Owned by the CefBrowserContext. |   // Owned by the CefBrowserContext. | ||||||
|   CefURLRequestContextGetterImpl* request_context_impl_; |   CefURLRequestContextGetterImpl* request_context_impl_ = nullptr; | ||||||
|  |  | ||||||
|   IMPLEMENT_REFCOUNTING(CefRequestContextImpl); |   IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefRequestContextImpl); | ||||||
|   DISALLOW_COPY_AND_ASSIGN(CefRequestContextImpl); |   DISALLOW_COPY_AND_ASSIGN(CefRequestContextImpl); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -671,8 +671,6 @@ class MethodTestHandler : public TestHandler { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     ~CompletionCallback() override { |     ~CompletionCallback() override { | ||||||
|       EXPECT_UI_THREAD(); |  | ||||||
|  |  | ||||||
|       // OnComplete should be executed. |       // OnComplete should be executed. | ||||||
|       EXPECT_FALSE(test_handler_); |       EXPECT_FALSE(test_handler_); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user