mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	chrome: Support client-created request contexts (see issue #2969)
RequestContextTest and URLRequestTest suites now pass with the Chrome runtime enabled.
This commit is contained in:
		| @@ -242,7 +242,9 @@ typedef struct _cef_settings_t { | |||||||
|   // in-memory caches are used for storage and no data is persisted to disk. |   // in-memory caches are used for storage and no data is persisted to disk. | ||||||
|   // HTML5 databases such as localStorage will only persist across sessions if a |   // HTML5 databases such as localStorage will only persist across sessions if a | ||||||
|   // cache path is specified. Can be overridden for individual CefRequestContext |   // cache path is specified. Can be overridden for individual CefRequestContext | ||||||
|   // instances via the CefRequestContextSettings.cache_path value. |   // instances via the CefRequestContextSettings.cache_path value. When using | ||||||
|  |   // the Chrome runtime the "default" profile will be used if |cache_path| and | ||||||
|  |   // |root_cache_path| have the same value. | ||||||
|   /// |   /// | ||||||
|   cef_string_t cache_path; |   cef_string_t cache_path; | ||||||
|  |  | ||||||
| @@ -264,7 +266,8 @@ typedef struct _cef_settings_t { | |||||||
|   // directory on Linux, "~/Library/Application Support/CEF/User Data" directory |   // directory on Linux, "~/Library/Application Support/CEF/User Data" directory | ||||||
|   // on Mac OS X, "Local Settings\Application Data\CEF\User Data" directory |   // on Mac OS X, "Local Settings\Application Data\CEF\User Data" directory | ||||||
|   // under the user profile directory on Windows). If this value is non-empty |   // under the user profile directory on Windows). If this value is non-empty | ||||||
|   // then it must be an absolute path. |   // then it must be an absolute path. When using the Chrome runtime this value | ||||||
|  |   // will be ignored in favor of the |root_cache_path| value. | ||||||
|   /// |   /// | ||||||
|   cef_string_t user_data_path; |   cef_string_t user_data_path; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,11 +12,13 @@ | |||||||
| #include "libcef/browser/request_context_impl.h" | #include "libcef/browser/request_context_impl.h" | ||||||
| #include "libcef/browser/thread_util.h" | #include "libcef/browser/thread_util.h" | ||||||
| #include "libcef/common/cef_switches.h" | #include "libcef/common/cef_switches.h" | ||||||
|  | #include "libcef/features/runtime.h" | ||||||
|  |  | ||||||
| #include "base/files/file_util.h" | #include "base/files/file_util.h" | ||||||
| #include "base/lazy_instance.h" | #include "base/lazy_instance.h" | ||||||
| #include "base/logging.h" | #include "base/logging.h" | ||||||
| #include "base/strings/string_util.h" | #include "base/strings/string_util.h" | ||||||
|  | #include "chrome/browser/profiles/profile.h" | ||||||
| #include "content/public/browser/browser_context.h" | #include "content/public/browser/browser_context.h" | ||||||
| #include "content/public/browser/browser_task_traits.h" | #include "content/public/browser/browser_task_traits.h" | ||||||
| #include "content/public/browser/browser_thread.h" | #include "content/public/browser/browser_thread.h" | ||||||
| @@ -229,6 +231,25 @@ CefBrowserContext* CefBrowserContext::FromBrowserContext( | |||||||
|   return g_manager.Get().GetImplFromBrowserContext(context); |   return g_manager.Get().GetImplFromBrowserContext(context); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // static | ||||||
|  | CefBrowserContext* CefBrowserContext::FromProfile(const Profile* profile) { | ||||||
|  |   auto* cef_context = FromBrowserContext(profile); | ||||||
|  |   if (cef_context) | ||||||
|  |     return cef_context; | ||||||
|  |  | ||||||
|  |   if (cef::IsChromeRuntimeEnabled()) { | ||||||
|  |     auto* original_profile = profile->GetOriginalProfile(); | ||||||
|  |     if (original_profile != profile) { | ||||||
|  |       // With the Chrome runtime if the user launches an incognito window via | ||||||
|  |       // the UI we might be associated with the original Profile instead of the | ||||||
|  |       // (current) incognito profile. | ||||||
|  |       return FromBrowserContext(original_profile); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
| // static | // static | ||||||
| std::vector<CefBrowserContext*> CefBrowserContext::GetAll() { | std::vector<CefBrowserContext*> CefBrowserContext::GetAll() { | ||||||
|   return g_manager.Get().GetAllImpl(); |   return g_manager.Get().GetAllImpl(); | ||||||
|   | |||||||
| @@ -103,6 +103,7 @@ class CefBrowserContext { | |||||||
|   // Returns the underlying CefBrowserContext if any. |   // Returns the underlying CefBrowserContext if any. | ||||||
|   static CefBrowserContext* FromBrowserContext( |   static CefBrowserContext* FromBrowserContext( | ||||||
|       const content::BrowserContext* context); |       const content::BrowserContext* context); | ||||||
|  |   static CefBrowserContext* FromProfile(const Profile* profile); | ||||||
|  |  | ||||||
|   // Returns all existing CefBrowserContext. |   // Returns all existing CefBrowserContext. | ||||||
|   static std::vector<CefBrowserContext*> GetAll(); |   static std::vector<CefBrowserContext*> GetAll(); | ||||||
|   | |||||||
| @@ -6,11 +6,11 @@ | |||||||
|  |  | ||||||
| #include "libcef/browser/prefs/browser_prefs.h" | #include "libcef/browser/prefs/browser_prefs.h" | ||||||
|  |  | ||||||
| #include "chrome/browser/profiles/profile_manager.h" | #include "chrome/browser/browser_process.h" | ||||||
|  |  | ||||||
| ChromeBrowserContext::ChromeBrowserContext( | ChromeBrowserContext::ChromeBrowserContext( | ||||||
|     const CefRequestContextSettings& settings) |     const CefRequestContextSettings& settings) | ||||||
|     : CefBrowserContext(settings) {} |     : CefBrowserContext(settings), weak_ptr_factory_(this) {} | ||||||
|  |  | ||||||
| ChromeBrowserContext::~ChromeBrowserContext() = default; | ChromeBrowserContext::~ChromeBrowserContext() = default; | ||||||
|  |  | ||||||
| @@ -22,19 +22,73 @@ Profile* ChromeBrowserContext::AsProfile() { | |||||||
|   return profile_; |   return profile_; | ||||||
| } | } | ||||||
|  |  | ||||||
| void ChromeBrowserContext::Initialize() { | void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) { | ||||||
|  |   initialized_cb_ = std::move(initialized_cb); | ||||||
|  |  | ||||||
|   CefBrowserContext::Initialize(); |   CefBrowserContext::Initialize(); | ||||||
|  |  | ||||||
|   // TODO(chrome-runtime): ProfileManager can create new profiles relative to |   if (!cache_path_.empty()) { | ||||||
|   // the user-data-dir, but it should be done asynchronously. |     auto* profile_manager = g_browser_process->profile_manager(); | ||||||
|   // The global ProfileManager instance can be retrieved via |     const auto& user_data_dir = profile_manager->user_data_dir(); | ||||||
|   // |g_browser_process->profile_manager()|. |  | ||||||
|   profile_ = ProfileManager::GetLastUsedProfileAllowedByPolicy(); |  | ||||||
|  |  | ||||||
|   browser_prefs::SetLanguagePrefs(profile_); |     if (cache_path_ == user_data_dir) { | ||||||
|  |       // Use the default disk-based profile. | ||||||
|  |       ProfileCreated(profile_manager->GetActiveUserProfile(), | ||||||
|  |                      Profile::CreateStatus::CREATE_STATUS_INITIALIZED); | ||||||
|  |       return; | ||||||
|  |     } else if (cache_path_.DirName() == user_data_dir) { | ||||||
|  |       // Create or load a specific disk-based profile. May continue | ||||||
|  |       // synchronously or asynchronously. | ||||||
|  |       profile_manager->CreateProfileAsync( | ||||||
|  |           cache_path_, | ||||||
|  |           base::Bind(&ChromeBrowserContext::ProfileCreated, | ||||||
|  |                      weak_ptr_factory_.GetWeakPtr()), | ||||||
|  |           /*name=*/base::string16(), /*icon_url=*/std::string()); | ||||||
|  |       return; | ||||||
|  |     } else { | ||||||
|  |       // All profile directories must be relative to |user_data_dir|. | ||||||
|  |       LOG(ERROR) << "Cannot create profile at path " | ||||||
|  |                  << cache_path_.AsUTF8Unsafe(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Default to creating a new/unique OffTheRecord profile. | ||||||
|  |   ProfileCreated(nullptr, Profile::CreateStatus::CREATE_STATUS_CANCELED); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ChromeBrowserContext::Shutdown() { | void ChromeBrowserContext::Shutdown() { | ||||||
|   CefBrowserContext::Shutdown(); |   CefBrowserContext::Shutdown(); | ||||||
|  |   // |g_browser_process| may be nullptr during shutdown. | ||||||
|  |   if (should_destroy_ && g_browser_process) { | ||||||
|  |     g_browser_process->profile_manager() | ||||||
|  |         ->GetActiveUserProfile() | ||||||
|  |         ->DestroyOffTheRecordProfile(profile_); | ||||||
|  |   } | ||||||
|   profile_ = nullptr; |   profile_ = nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ChromeBrowserContext::ProfileCreated(Profile* profile, | ||||||
|  |                                           Profile::CreateStatus status) { | ||||||
|  |   if (status != Profile::CreateStatus::CREATE_STATUS_CREATED && | ||||||
|  |       status != Profile::CreateStatus::CREATE_STATUS_INITIALIZED) { | ||||||
|  |     DCHECK(!profile); | ||||||
|  |  | ||||||
|  |     // Creation of a disk-based profile failed for some reason. Create a | ||||||
|  |     // new/unique OffTheRecord profile instead. | ||||||
|  |     const auto& profile_id = Profile::OTRProfileID::CreateUniqueForCEF(); | ||||||
|  |     profile = g_browser_process->profile_manager() | ||||||
|  |                   ->GetActiveUserProfile() | ||||||
|  |                   ->GetOffTheRecordProfile(profile_id); | ||||||
|  |     status = Profile::CreateStatus::CREATE_STATUS_INITIALIZED; | ||||||
|  |     should_destroy_ = true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) { | ||||||
|  |     DCHECK(profile); | ||||||
|  |     DCHECK(!profile_); | ||||||
|  |     profile_ = profile; | ||||||
|  |     browser_prefs::SetLanguagePrefs(profile_); | ||||||
|  |  | ||||||
|  |     std::move(initialized_cb_).Run(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -8,22 +8,32 @@ | |||||||
|  |  | ||||||
| #include "libcef/browser/browser_context.h" | #include "libcef/browser/browser_context.h" | ||||||
|  |  | ||||||
|  | #include "base/memory/weak_ptr.h" | ||||||
|  | #include "chrome/browser/profiles/profile_manager.h" | ||||||
|  |  | ||||||
| // See CefBrowserContext documentation for usage. Only accessed on the UI thread | // See CefBrowserContext documentation for usage. Only accessed on the UI thread | ||||||
| // unless otherwise indicated. | // unless otherwise indicated. | ||||||
| class ChromeBrowserContext : public CefBrowserContext { | class ChromeBrowserContext : public CefBrowserContext { | ||||||
|  public: |  public: | ||||||
|   explicit ChromeBrowserContext(const CefRequestContextSettings& settings); |   explicit ChromeBrowserContext(const CefRequestContextSettings& settings); | ||||||
|  |  | ||||||
|  |   void InitializeAsync(base::OnceClosure initialized_cb); | ||||||
|  |  | ||||||
|   // CefBrowserContext overrides. |   // CefBrowserContext overrides. | ||||||
|   content::BrowserContext* AsBrowserContext() override; |   content::BrowserContext* AsBrowserContext() override; | ||||||
|   Profile* AsProfile() override; |   Profile* AsProfile() override; | ||||||
|   void Initialize() override; |  | ||||||
|   void Shutdown() override; |   void Shutdown() override; | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   ~ChromeBrowserContext() override; |   ~ChromeBrowserContext() override; | ||||||
|  |  | ||||||
|  |   void ProfileCreated(Profile* profile, Profile::CreateStatus status); | ||||||
|  |  | ||||||
|  |   base::OnceClosure initialized_cb_; | ||||||
|   Profile* profile_ = nullptr; |   Profile* profile_ = nullptr; | ||||||
|  |   bool should_destroy_ = false; | ||||||
|  |  | ||||||
|  |   base::WeakPtrFactory<ChromeBrowserContext> weak_ptr_factory_; | ||||||
|  |  | ||||||
|   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserContext); |   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserContext); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -175,7 +175,7 @@ bool ChromeContentBrowserClientCef::WillCreateURLLoaderFactory( | |||||||
|   // For example, the User Manager profile created via |   // For example, the User Manager profile created via | ||||||
|   // profiles::CreateSystemProfileForUserManager. |   // profiles::CreateSystemProfileForUserManager. | ||||||
|   auto profile = Profile::FromBrowserContext(browser_context); |   auto profile = Profile::FromBrowserContext(browser_context); | ||||||
|   if (!CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile())) |   if (!CefBrowserContext::FromProfile(profile)) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   auto request_handler = net_service::CreateInterceptedRequestHandler( |   auto request_handler = net_service::CreateInterceptedRequestHandler( | ||||||
|   | |||||||
| @@ -262,8 +262,7 @@ class InterceptedRequestHandlerWrapper : public InterceptedRequestHandler { | |||||||
|       browser_context_ = browser_context; |       browser_context_ = browser_context; | ||||||
|  |  | ||||||
|       auto profile = Profile::FromBrowserContext(browser_context); |       auto profile = Profile::FromBrowserContext(browser_context); | ||||||
|       auto cef_browser_context = |       auto cef_browser_context = CefBrowserContext::FromProfile(profile); | ||||||
|           CefBrowserContext::FromBrowserContext(profile->GetOriginalProfile()); |  | ||||||
|       iothread_state_ = cef_browser_context->iothread_state(); |       iothread_state_ = cef_browser_context->iothread_state(); | ||||||
|       DCHECK(iothread_state_); |       DCHECK(iothread_state_); | ||||||
|       cookieable_schemes_ = cef_browser_context->GetCookieableSchemes(); |       cookieable_schemes_ = cef_browser_context->GetCookieableSchemes(); | ||||||
|   | |||||||
| @@ -612,7 +612,19 @@ CefRequestContextImpl::GetOrCreateRequestContext(const Config& config) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // The new context will be initialized later by EnsureBrowserContext(). |   // The new context will be initialized later by EnsureBrowserContext(). | ||||||
|   return new CefRequestContextImpl(config); |   CefRefPtr<CefRequestContextImpl> context = new CefRequestContextImpl(config); | ||||||
|  |  | ||||||
|  |   if (config.handler) { | ||||||
|  |     // Keep the context alive until OnRequestContextInitialized is called. | ||||||
|  |     if (CEF_CURRENTLY_ON_UIT()) { | ||||||
|  |       context->Initialize(); | ||||||
|  |     } else { | ||||||
|  |       CEF_POST_TASK( | ||||||
|  |           CEF_UIT, base::BindOnce(&CefRequestContextImpl::Initialize, context)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return context; | ||||||
| } | } | ||||||
|  |  | ||||||
| CefRequestContextImpl::CefRequestContextImpl( | CefRequestContextImpl::CefRequestContextImpl( | ||||||
| @@ -645,16 +657,20 @@ void CefRequestContextImpl::Initialize() { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   auto initialized_cb = | ||||||
|  |       base::BindOnce(&CefRequestContextImpl::BrowserContextInitialized, this); | ||||||
|  |  | ||||||
|   if (!browser_context_) { |   if (!browser_context_) { | ||||||
|     // Create a new CefBrowserContext instance. If the cache path is non- |     // Create a new CefBrowserContext instance. If the cache path is non- | ||||||
|     // empty then this new instance will become the globally registered |     // empty then this new instance will become the globally registered | ||||||
|     // CefBrowserContext for that path. Otherwise, this new instance will |     // CefBrowserContext for that path. Otherwise, this new instance will | ||||||
|     // be a completely isolated "incognito mode" context. |     // be a completely isolated "incognito mode" context. | ||||||
|     browser_context_ = |     browser_context_ = CefAppManager::Get()->CreateNewBrowserContext( | ||||||
|         CefAppManager::Get()->CreateNewBrowserContext(config_.settings); |         config_.settings, std::move(initialized_cb)); | ||||||
|   } else { |   } else { | ||||||
|     // Share the same settings as the existing context. |     // Share the same settings as the existing context. | ||||||
|     config_.settings = browser_context_->settings(); |     config_.settings = browser_context_->settings(); | ||||||
|  |     std::move(initialized_cb).Run(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // We'll disassociate from |browser_context_| on destruction. |   // We'll disassociate from |browser_context_| on destruction. | ||||||
| @@ -666,9 +682,16 @@ void CefRequestContextImpl::Initialize() { | |||||||
|     // IsSharedWith(). |     // IsSharedWith(). | ||||||
|     config_.other = nullptr; |     config_.other = nullptr; | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|   if (config_.handler) | void CefRequestContextImpl::BrowserContextInitialized() { | ||||||
|     config_.handler->OnRequestContextInitialized(this); |   if (config_.handler) { | ||||||
|  |     // Always execute asynchronously so the current call stack can unwind. | ||||||
|  |     CEF_POST_TASK( | ||||||
|  |         CEF_UIT, | ||||||
|  |         base::BindOnce(&CefRequestContextHandler::OnRequestContextInitialized, | ||||||
|  |                        config_.handler, CefRefPtr<CefRequestContext>(this))); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefRequestContextImpl::EnsureBrowserContext() { | void CefRequestContextImpl::EnsureBrowserContext() { | ||||||
|   | |||||||
| @@ -128,6 +128,7 @@ class CefRequestContextImpl : public CefRequestContext { | |||||||
|   explicit CefRequestContextImpl(const Config& config); |   explicit CefRequestContextImpl(const Config& config); | ||||||
|  |  | ||||||
|   void Initialize(); |   void Initialize(); | ||||||
|  |   void BrowserContextInitialized(); | ||||||
|  |  | ||||||
|   // 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(); | ||||||
|   | |||||||
| @@ -443,9 +443,11 @@ CefRefPtr<CefRequestContext> AlloyMainDelegate::GetGlobalRequestContext() { | |||||||
| } | } | ||||||
|  |  | ||||||
| CefBrowserContext* AlloyMainDelegate::CreateNewBrowserContext( | CefBrowserContext* AlloyMainDelegate::CreateNewBrowserContext( | ||||||
|     const CefRequestContextSettings& settings) { |     const CefRequestContextSettings& settings, | ||||||
|  |     base::OnceClosure initialized_cb) { | ||||||
|   auto context = new AlloyBrowserContext(settings); |   auto context = new AlloyBrowserContext(settings); | ||||||
|   context->Initialize(); |   context->Initialize(); | ||||||
|  |   std::move(initialized_cb).Run(); | ||||||
|   return context; |   return context; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -62,7 +62,8 @@ class AlloyMainDelegate : public content::ContentMainDelegate, | |||||||
|   } |   } | ||||||
|   CefRefPtr<CefRequestContext> GetGlobalRequestContext() override; |   CefRefPtr<CefRequestContext> GetGlobalRequestContext() override; | ||||||
|   CefBrowserContext* CreateNewBrowserContext( |   CefBrowserContext* CreateNewBrowserContext( | ||||||
|       const CefRequestContextSettings& settings) override; |       const CefRequestContextSettings& settings, | ||||||
|  |       base::OnceClosure initialized_cb) override; | ||||||
|  |  | ||||||
|   // CefTaskRunnerManager overrides. |   // CefTaskRunnerManager overrides. | ||||||
|   scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner() |   scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner() | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| #include "include/cef_app.h" | #include "include/cef_app.h" | ||||||
| #include "include/cef_request_context.h" | #include "include/cef_request_context.h" | ||||||
|  |  | ||||||
|  | #include "base/callback.h" | ||||||
| #include "base/macros.h" | #include "base/macros.h" | ||||||
| #include "build/build_config.h" | #include "build/build_config.h" | ||||||
| #include "content/public/common/content_client.h" | #include "content/public/common/content_client.h" | ||||||
| @@ -44,10 +45,12 @@ class CefAppManager { | |||||||
|  |  | ||||||
|   // The following methods are only available in the main (browser) process. |   // The following methods are only available in the main (browser) process. | ||||||
|  |  | ||||||
|   // Called from CefRequestContextImpl. |   // Called from CefRequestContextImpl. |initialized_cb| may be executed | ||||||
|  |   // synchronously or asynchronously. | ||||||
|   virtual CefRefPtr<CefRequestContext> GetGlobalRequestContext() = 0; |   virtual CefRefPtr<CefRequestContext> GetGlobalRequestContext() = 0; | ||||||
|   virtual CefBrowserContext* CreateNewBrowserContext( |   virtual CefBrowserContext* CreateNewBrowserContext( | ||||||
|       const CefRequestContextSettings& settings) = 0; |       const CefRequestContextSettings& settings, | ||||||
|  |       base::OnceClosure initialized_cb) = 0; | ||||||
|  |  | ||||||
| #if defined(OS_WIN) | #if defined(OS_WIN) | ||||||
|   // Returns the module name (usually libcef.dll). |   // Returns the module name (usually libcef.dll). | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ | |||||||
|  |  | ||||||
| #include "base/command_line.h" | #include "base/command_line.h" | ||||||
| #include "base/lazy_instance.h" | #include "base/lazy_instance.h" | ||||||
|  | #include "chrome/common/chrome_switches.h" | ||||||
| #include "content/public/common/content_switches.h" | #include "content/public/common/content_switches.h" | ||||||
| #include "sandbox/policy/switches.h" | #include "sandbox/policy/switches.h" | ||||||
|  |  | ||||||
| @@ -194,9 +195,10 @@ CefRefPtr<CefRequestContext> ChromeMainDelegateCef::GetGlobalRequestContext() { | |||||||
| } | } | ||||||
|  |  | ||||||
| CefBrowserContext* ChromeMainDelegateCef::CreateNewBrowserContext( | CefBrowserContext* ChromeMainDelegateCef::CreateNewBrowserContext( | ||||||
|     const CefRequestContextSettings& settings) { |     const CefRequestContextSettings& settings, | ||||||
|  |     base::OnceClosure initialized_cb) { | ||||||
|   auto context = new ChromeBrowserContext(settings); |   auto context = new ChromeBrowserContext(settings); | ||||||
|   context->Initialize(); |   context->InitializeAsync(std::move(initialized_cb)); | ||||||
|   return context; |   return context; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,8 @@ class ChromeMainDelegateCef : public ChromeMainDelegate, | |||||||
|   } |   } | ||||||
|   CefRefPtr<CefRequestContext> GetGlobalRequestContext() override; |   CefRefPtr<CefRequestContext> GetGlobalRequestContext() override; | ||||||
|   CefBrowserContext* CreateNewBrowserContext( |   CefBrowserContext* CreateNewBrowserContext( | ||||||
|       const CefRequestContextSettings& settings) override; |       const CefRequestContextSettings& settings, | ||||||
|  |       base::OnceClosure initialized_cb) override; | ||||||
|  |  | ||||||
|   // CefTaskRunnerManager overrides. |   // CefTaskRunnerManager overrides. | ||||||
|   scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner() |   scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner() | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ | |||||||
| #include <dlfcn.h> | #include <dlfcn.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #include "libcef/features/runtime.h" | ||||||
|  |  | ||||||
| #include "base/command_line.h" | #include "base/command_line.h" | ||||||
| #include "base/files/file_path.h" | #include "base/files/file_path.h" | ||||||
| #include "base/files/file_util.h" | #include "base/files/file_util.h" | ||||||
| @@ -80,8 +82,21 @@ bool GetDefaultUserDataDirectory(base::FilePath* result) { | |||||||
| base::FilePath GetUserDataPath(CefSettings* settings, | base::FilePath GetUserDataPath(CefSettings* settings, | ||||||
|                                const base::CommandLine* command_line) { |                                const base::CommandLine* command_line) { | ||||||
|   // |settings| will be non-nullptr in the main process only. |   // |settings| will be non-nullptr in the main process only. | ||||||
|   if (settings && settings->user_data_path.length > 0) |   if (settings) { | ||||||
|     return base::FilePath(CefString(&settings->user_data_path)); |     // With the Chrome runtime Profile paths must always be relative to the | ||||||
|  |     // user data directory, so defaulting to |root_cache_path| first is | ||||||
|  |     // appropriate. | ||||||
|  |     CefString user_data_path; | ||||||
|  |     if (cef::IsChromeRuntimeEnabled() && settings->root_cache_path.length > 0) { | ||||||
|  |       user_data_path = CefString(&settings->root_cache_path); | ||||||
|  |     } | ||||||
|  |     if (user_data_path.empty() && settings->user_data_path.length > 0) { | ||||||
|  |       user_data_path = CefString(&settings->user_data_path); | ||||||
|  |     } | ||||||
|  |     if (!user_data_path.empty()) { | ||||||
|  |       return base::FilePath(user_data_path); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // This may be set for sub-processes. |   // This may be set for sub-processes. | ||||||
|   base::FilePath result = |   base::FilePath result = | ||||||
|   | |||||||
| @@ -232,6 +232,9 @@ patches = [ | |||||||
|     # |     # | ||||||
|     # Don't create IdentityManager in RendererUpdater. |     # Don't create IdentityManager in RendererUpdater. | ||||||
|     # https://bitbucket.org/chromiumembedded/cef/issues/1917 |     # https://bitbucket.org/chromiumembedded/cef/issues/1917 | ||||||
|  |     # | ||||||
|  |     # chrome: Support CEF incognito Profiles that allow Browser creation. | ||||||
|  |     # https://bitbucket.org/chromiumembedded/cef/issues/2969 | ||||||
|     'name': 'chrome_browser_profiles', |     'name': 'chrome_browser_profiles', | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|   | |||||||
| @@ -1,3 +1,50 @@ | |||||||
|  | diff --git chrome/browser/profiles/profile.cc chrome/browser/profiles/profile.cc | ||||||
|  | index 8e8a7abdcf17..89c47d18d379 100644 | ||||||
|  | --- chrome/browser/profiles/profile.cc | ||||||
|  | +++ chrome/browser/profiles/profile.cc | ||||||
|  | @@ -77,6 +77,7 @@ base::LazyInstance<std::set<content::BrowserContext*>>::Leaky | ||||||
|  |   | ||||||
|  |  namespace { | ||||||
|  |   | ||||||
|  | +const char kCEFOTRProfileIDPrefix[] = "CEF::BrowserContext"; | ||||||
|  |  const char kDevToolsOTRProfileIDPrefix[] = "Devtools::BrowserContext"; | ||||||
|  |  const char kMediaRouterOTRProfileIDPrefix[] = "MediaRouter::Presentation"; | ||||||
|  |   | ||||||
|  | @@ -90,6 +91,8 @@ bool Profile::OTRProfileID::AllowsBrowserWindows() const { | ||||||
|  |    // DevTools::BrowserContext and MediaRouter::Presentation are an | ||||||
|  |    // exception to this ban. | ||||||
|  |    return *this == PrimaryID() || | ||||||
|  | +         base::StartsWith(profile_id_, kCEFOTRProfileIDPrefix, | ||||||
|  | +                          base::CompareCase::SENSITIVE) || | ||||||
|  |           base::StartsWith(profile_id_, kDevToolsOTRProfileIDPrefix, | ||||||
|  |                            base::CompareCase::SENSITIVE) || | ||||||
|  |           base::StartsWith(profile_id_, kMediaRouterOTRProfileIDPrefix, | ||||||
|  | @@ -111,6 +114,11 @@ Profile::OTRProfileID Profile::OTRProfileID::CreateUnique( | ||||||
|  |                                           first_unused_index_++)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +// static | ||||||
|  | +Profile::OTRProfileID Profile::OTRProfileID::CreateUniqueForCEF() { | ||||||
|  | +  return CreateUnique(kCEFOTRProfileIDPrefix); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  // static | ||||||
|  |  Profile::OTRProfileID Profile::OTRProfileID::CreateUniqueForDevTools() { | ||||||
|  |    return CreateUnique(kDevToolsOTRProfileIDPrefix); | ||||||
|  | diff --git chrome/browser/profiles/profile.h chrome/browser/profiles/profile.h | ||||||
|  | index e77f4b15ce32..13569302c96b 100644 | ||||||
|  | --- chrome/browser/profiles/profile.h | ||||||
|  | +++ chrome/browser/profiles/profile.h | ||||||
|  | @@ -116,6 +116,9 @@ class Profile : public content::BrowserContext { | ||||||
|  |      // Creates a unique OTR profile id with the given profile id prefix. | ||||||
|  |      static OTRProfileID CreateUnique(const std::string& profile_id_prefix); | ||||||
|  |   | ||||||
|  | +    // Creates a unique OTR profile id to be used for CEF browser contexts. | ||||||
|  | +    static OTRProfileID CreateUniqueForCEF(); | ||||||
|  | + | ||||||
|  |      // Creates a unique OTR profile id to be used for DevTools browser contexts. | ||||||
|  |      static OTRProfileID CreateUniqueForDevTools(); | ||||||
|  |   | ||||||
| diff --git chrome/browser/profiles/profile_manager.cc chrome/browser/profiles/profile_manager.cc | diff --git chrome/browser/profiles/profile_manager.cc chrome/browser/profiles/profile_manager.cc | ||||||
| index 71730949d2bd..eedcde617f01 100644 | index 71730949d2bd..eedcde617f01 100644 | ||||||
| --- chrome/browser/profiles/profile_manager.cc | --- chrome/browser/profiles/profile_manager.cc | ||||||
|   | |||||||
| @@ -26,9 +26,8 @@ ExtensionTestHandler::ExtensionTestHandler( | |||||||
|  |  | ||||||
| ExtensionTestHandler::~ExtensionTestHandler() { | ExtensionTestHandler::~ExtensionTestHandler() { | ||||||
|   if (!request_context_temp_dir_.IsEmpty()) { |   if (!request_context_temp_dir_.IsEmpty()) { | ||||||
|     // Delete temporary directories on shutdown. |     // Temporary directory will be deleted on shutdown. | ||||||
|     CefTestSuite::GetInstance()->RegisterTempDirectory( |     request_context_temp_dir_.Take(); | ||||||
|         request_context_temp_dir_.Take()); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -65,7 +64,8 @@ void ExtensionTestHandler::RunTest() { | |||||||
|  |  | ||||||
|     if (request_context_on_disk()) { |     if (request_context_on_disk()) { | ||||||
|       // Create a new temporary directory. |       // Create a new temporary directory. | ||||||
|       EXPECT_TRUE(request_context_temp_dir_.CreateUniqueTempDir()); |       EXPECT_TRUE(request_context_temp_dir_.CreateUniqueTempDirUnderPath( | ||||||
|  |           CefTestSuite::GetInstance()->root_cache_path())); | ||||||
|       CefString(&settings.cache_path) = request_context_temp_dir_.GetPath(); |       CefString(&settings.cache_path) = request_context_temp_dir_.GetPath(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -136,7 +136,8 @@ TEST(RequestContextTest, BasicCreateSharedGlobal) { | |||||||
|  |  | ||||||
| TEST(RequestContextTest, BasicCreateSharedOnDisk) { | TEST(RequestContextTest, BasicCreateSharedOnDisk) { | ||||||
|   CefScopedTempDir tempdir; |   CefScopedTempDir tempdir; | ||||||
|   EXPECT_TRUE(tempdir.CreateUniqueTempDir()); |   EXPECT_TRUE(tempdir.CreateUniqueTempDirUnderPath( | ||||||
|  |       CefTestSuite::GetInstance()->root_cache_path())); | ||||||
|  |  | ||||||
|   CefRequestContextSettings settings; |   CefRequestContextSettings settings; | ||||||
|   CefString(&settings.cache_path) = tempdir.GetPath(); |   CefString(&settings.cache_path) = tempdir.GetPath(); | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include "tests/ceftests/test_suite.h" | #include "tests/ceftests/test_suite.h" | ||||||
|  |  | ||||||
| #include "include/cef_file_util.h" | #include "include/cef_file_util.h" | ||||||
|  | #include "include/wrapper/cef_scoped_temp_dir.h" | ||||||
| #include "tests/gtest/include/gtest/gtest.h" | #include "tests/gtest/include/gtest/gtest.h" | ||||||
| #include "tests/shared/common/client_switches.h" | #include "tests/shared/common/client_switches.h" | ||||||
|  |  | ||||||
| @@ -92,6 +93,18 @@ CefTestSuite::CefTestSuite(int argc, char** argv) | |||||||
| #else | #else | ||||||
|   command_line_->InitFromArgv(argc, argv); |   command_line_->InitFromArgv(argc, argv); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |   if (!command_line_->HasSwitch("type")) { | ||||||
|  |     // Initialize in the main process only. | ||||||
|  |     root_cache_path_ = | ||||||
|  |         command_line_->GetSwitchValue(client::switches::kCachePath); | ||||||
|  |     if (root_cache_path_.empty()) { | ||||||
|  |       CefScopedTempDir temp_dir; | ||||||
|  |       CHECK(temp_dir.CreateUniqueTempDir()); | ||||||
|  |       root_cache_path_ = temp_dir.Take(); | ||||||
|  |       RegisterTempDirectory(root_cache_path_); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| CefTestSuite::~CefTestSuite() { | CefTestSuite::~CefTestSuite() { | ||||||
| @@ -133,8 +146,9 @@ void CefTestSuite::GetSettings(CefSettings& settings) const { | |||||||
|         command_line_->HasSwitch(client::switches::kExternalMessagePump); |         command_line_->HasSwitch(client::switches::kExternalMessagePump); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   CefString(&settings.cache_path) = |   CefString(&settings.cache_path) = root_cache_path_; | ||||||
|       command_line_->GetSwitchValue(client::switches::kCachePath); |   CefString(&settings.root_cache_path) = root_cache_path_; | ||||||
|  |   CefString(&settings.user_data_path) = root_cache_path_; | ||||||
|  |  | ||||||
|   // Always expose the V8 gc() function to give tests finer-grained control over |   // Always expose the V8 gc() function to give tests finer-grained control over | ||||||
|   // memory management. |   // memory management. | ||||||
| @@ -156,17 +170,6 @@ void CefTestSuite::GetSettings(CefSettings& settings) const { | |||||||
|   CefString(&settings.accept_language_list) = CEF_SETTINGS_ACCEPT_LANGUAGE; |   CefString(&settings.accept_language_list) = CEF_SETTINGS_ACCEPT_LANGUAGE; | ||||||
| } | } | ||||||
|  |  | ||||||
| // static |  | ||||||
| bool CefTestSuite::GetCachePath(std::string& path) const { |  | ||||||
|   if (command_line_->HasSwitch(client::switches::kCachePath)) { |  | ||||||
|     // Set the cache_path value. |  | ||||||
|     path = command_line_->GetSwitchValue(client::switches::kCachePath); |  | ||||||
|     return true; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return false; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void CefTestSuite::RegisterTempDirectory(const CefString& directory) { | void CefTestSuite::RegisterTempDirectory(const CefString& directory) { | ||||||
|   base::AutoLock lock_scope(temp_directories_lock_); |   base::AutoLock lock_scope(temp_directories_lock_); | ||||||
|   temp_directories_.push_back(directory); |   temp_directories_.push_back(directory); | ||||||
|   | |||||||
| @@ -25,7 +25,6 @@ class CefTestSuite { | |||||||
|   int Run(); |   int Run(); | ||||||
|  |  | ||||||
|   void GetSettings(CefSettings& settings) const; |   void GetSettings(CefSettings& settings) const; | ||||||
|   bool GetCachePath(std::string& path) const; |  | ||||||
|  |  | ||||||
|   // Register a temp directory that should be deleted on shutdown. |   // Register a temp directory that should be deleted on shutdown. | ||||||
|   void RegisterTempDirectory(const CefString& directory); |   void RegisterTempDirectory(const CefString& directory); | ||||||
| @@ -34,6 +33,7 @@ class CefTestSuite { | |||||||
|   void DeleteTempDirectories(); |   void DeleteTempDirectories(); | ||||||
|  |  | ||||||
|   CefRefPtr<CefCommandLine> command_line() const { return command_line_; } |   CefRefPtr<CefCommandLine> command_line() const { return command_line_; } | ||||||
|  |   CefString root_cache_path() const { return root_cache_path_; } | ||||||
|  |  | ||||||
|   // The return value from Run(). |   // The return value from Run(). | ||||||
|   int retval() const { return retval_; } |   int retval() const { return retval_; } | ||||||
| @@ -50,6 +50,8 @@ class CefTestSuite { | |||||||
|   std::vector<CefString> temp_directories_; |   std::vector<CefString> temp_directories_; | ||||||
|   base::Lock temp_directories_lock_; |   base::Lock temp_directories_lock_; | ||||||
|  |  | ||||||
|  |   CefString root_cache_path_; | ||||||
|  |  | ||||||
|   int retval_; |   int retval_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -99,7 +99,8 @@ CefRefPtr<CefRequestContext> CreateTestRequestContext( | |||||||
|     CefScopedTempDir scoped_temp_dir;                                  \ |     CefScopedTempDir scoped_temp_dir;                                  \ | ||||||
|     std::string cache_path;                                            \ |     std::string cache_path;                                            \ | ||||||
|     if (with_cache_path) {                                             \ |     if (with_cache_path) {                                             \ | ||||||
|       EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());              \ |       EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDirUnderPath(        \ | ||||||
|  |           CefTestSuite::GetInstance()->root_cache_path()));            \ | ||||||
|       cache_path = scoped_temp_dir.GetPath();                          \ |       cache_path = scoped_temp_dir.GetPath();                          \ | ||||||
|     }                                                                  \ |     }                                                                  \ | ||||||
|     CefRefPtr<test_class> handler =                                    \ |     CefRefPtr<test_class> handler =                                    \ | ||||||
| @@ -107,8 +108,7 @@ CefRefPtr<CefRequestContext> CreateTestRequestContext( | |||||||
|     handler->ExecuteTest();                                            \ |     handler->ExecuteTest();                                            \ | ||||||
|     ReleaseAndWaitForDestructor(handler);                              \ |     ReleaseAndWaitForDestructor(handler);                              \ | ||||||
|     if (!scoped_temp_dir.IsEmpty()) {                                  \ |     if (!scoped_temp_dir.IsEmpty()) {                                  \ | ||||||
|       CefTestSuite::GetInstance()->RegisterTempDirectory(              \ |       scoped_temp_dir.Take();                                          \ | ||||||
|           scoped_temp_dir.Take());                                     \ |  | ||||||
|     }                                                                  \ |     }                                                                  \ | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,6 +47,11 @@ class URLRequestBrowserTest : public client::ClientAppBrowser::Delegate { | |||||||
|       CefRefPtr<CefCommandLine> command_line) override { |       CefRefPtr<CefCommandLine> command_line) override { | ||||||
|     // Delegate auth callbacks to GetAuthCredentials with the chrome runtime. |     // Delegate auth callbacks to GetAuthCredentials with the chrome runtime. | ||||||
|     command_line->AppendSwitch("disable-chrome-login-prompt"); |     command_line->AppendSwitch("disable-chrome-login-prompt"); | ||||||
|  |  | ||||||
|  |     // Disable component extensions that require creation of a background | ||||||
|  |     // WebContents because they slow down test runs. | ||||||
|  |     command_line->AppendSwitch( | ||||||
|  |         "disable-component-extensions-with-background-pages"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
| @@ -2843,7 +2848,7 @@ class RequestTestHandler : public TestHandler { | |||||||
|  |  | ||||||
|   void RunTest() override { |   void RunTest() override { | ||||||
|     // Time out the test after a reasonable period of time. |     // Time out the test after a reasonable period of time. | ||||||
|     SetTestTimeout(); |     SetTestTimeout(IsChromeRuntimeEnabled() ? 10000 : 5000); | ||||||
|  |  | ||||||
|     // Start pre-setup actions. |     // Start pre-setup actions. | ||||||
|     PreSetupStart(); |     PreSetupStart(); | ||||||
| @@ -2858,7 +2863,8 @@ class RequestTestHandler : public TestHandler { | |||||||
|     EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); |     EXPECT_TRUE(CefCurrentlyOn(TID_FILE_USER_VISIBLE)); | ||||||
|  |  | ||||||
|     if (context_mode_ == CONTEXT_ONDISK) { |     if (context_mode_ == CONTEXT_ONDISK) { | ||||||
|       EXPECT_TRUE(context_tmpdir_.CreateUniqueTempDir()); |       EXPECT_TRUE(context_tmpdir_.CreateUniqueTempDirUnderPath( | ||||||
|  |           CefTestSuite::GetInstance()->root_cache_path())); | ||||||
|       context_tmpdir_path_ = context_tmpdir_.GetPath(); |       context_tmpdir_path_ = context_tmpdir_.GetPath(); | ||||||
|       EXPECT_FALSE(context_tmpdir_path_.empty()); |       EXPECT_FALSE(context_tmpdir_path_.empty()); | ||||||
|     } |     } | ||||||
| @@ -2894,10 +2900,14 @@ class RequestTestHandler : public TestHandler { | |||||||
|         CefString(&settings.cache_path) = context_tmpdir_path_; |         CefString(&settings.cache_path) = context_tmpdir_path_; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       // Create a new temporary request context. |       // Create a new temporary request context. Calls OnContextInitialized. | ||||||
|       CefRefPtr<CefRequestContext> request_context = |  | ||||||
|       CefRequestContext::CreateContext(settings, |       CefRequestContext::CreateContext(settings, | ||||||
|                                        new RequestContextHandler(this)); |                                        new RequestContextHandler(this)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void OnContextInitialized(CefRefPtr<CefRequestContext> request_context) { | ||||||
|  |     EXPECT_TRUE(CefCurrentlyOn(TID_UI)); | ||||||
|     EXPECT_TRUE(request_context.get()); |     EXPECT_TRUE(request_context.get()); | ||||||
|     test_runner_->SetRequestContext(request_context); |     test_runner_->SetRequestContext(request_context); | ||||||
|  |  | ||||||
| @@ -2915,7 +2925,6 @@ class RequestTestHandler : public TestHandler { | |||||||
|       PreSetupComplete(); |       PreSetupComplete(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void PreSetupComplete() { |   void PreSetupComplete() { | ||||||
|     if (!CefCurrentlyOn(TID_UI)) { |     if (!CefCurrentlyOn(TID_UI)) { | ||||||
| @@ -3182,9 +3191,8 @@ class RequestTestHandler : public TestHandler { | |||||||
|     got_on_test_complete_.yes(); |     got_on_test_complete_.yes(); | ||||||
|  |  | ||||||
|     if (!context_tmpdir_.IsEmpty()) { |     if (!context_tmpdir_.IsEmpty()) { | ||||||
|       // Delete the temp directory on application shutdown. |       // Temp directory will be deleted on application shutdown. | ||||||
|       CefTestSuite::GetInstance()->RegisterTempDirectory( |       context_tmpdir_.Take(); | ||||||
|           context_tmpdir_.Take()); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     TestComplete(); |     TestComplete(); | ||||||
| @@ -3199,6 +3207,11 @@ class RequestTestHandler : public TestHandler { | |||||||
|         : test_handler_(test_handler) {} |         : test_handler_(test_handler) {} | ||||||
|     ~RequestContextHandler() override { test_handler_->OnTestComplete(); } |     ~RequestContextHandler() override { test_handler_->OnTestComplete(); } | ||||||
|  |  | ||||||
|  |     void OnRequestContextInitialized( | ||||||
|  |         CefRefPtr<CefRequestContext> request_context) override { | ||||||
|  |       test_handler_->OnContextInitialized(request_context); | ||||||
|  |     } | ||||||
|  |  | ||||||
|    private: |    private: | ||||||
|     CefRefPtr<RequestTestHandler> test_handler_; |     CefRefPtr<RequestTestHandler> test_handler_; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user