From d180d3b1682e2d633ceb4e09bb675a1c463d8da5 Mon Sep 17 00:00:00 2001 From: Robo Date: Thu, 6 Aug 2015 20:31:05 +0530 Subject: [PATCH] webview: fix partition attribute --- atom/browser/api/atom_api_web_contents.cc | 10 ++++-- atom/browser/api/atom_api_web_view_manager.cc | 3 +- atom/browser/atom_browser_main_parts.cc | 32 +++++++++++++++++++ atom/browser/atom_browser_main_parts.h | 10 ++++++ atom/browser/lib/guest-view-manager.coffee | 13 +++++++- atom/browser/web_view_manager.cc | 15 +++++---- atom/browser/web_view_manager.h | 4 ++- 7 files changed, 74 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5b723801cde..da33451c1e7 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -159,16 +159,20 @@ WebContents::WebContents(const mate::Dictionary& options) { type_ = is_guest ? WEB_VIEW : BROWSER_WINDOW; - auto browser_context = AtomBrowserMainParts::Get()->browser_context(); content::WebContents* web_contents; if (is_guest) { - content::SiteInstance* site_instance = content::SiteInstance::CreateForURL( - browser_context, GURL("chrome-guest://fake-host")); + GURL guest_site; + options.Get("partition", &guest_site); + auto browser_context = + AtomBrowserMainParts::Get()->GetBrowserContextForPartition(guest_site); + auto site_instance = + content::SiteInstance::CreateForURL(browser_context, guest_site); content::WebContents::CreateParams params(browser_context, site_instance); guest_delegate_.reset(new WebViewGuestDelegate); params.guest_delegate = guest_delegate_.get(); web_contents = content::WebContents::Create(params); } else { + auto browser_context = AtomBrowserMainParts::Get()->browser_context(); content::WebContents::CreateParams params(browser_context); web_contents = content::WebContents::Create(params); } diff --git a/atom/browser/api/atom_api_web_view_manager.cc b/atom/browser/api/atom_api_web_view_manager.cc index d77ea18d6d0..c69285a6980 100644 --- a/atom/browser/api/atom_api_web_view_manager.cc +++ b/atom/browser/api/atom_api_web_view_manager.cc @@ -43,7 +43,8 @@ struct Converter { return options.Get("nodeIntegration", &(out->node_integration)) && options.Get("plugins", &(out->plugins)) && - options.Get("disableWebSecurity", &(out->disable_web_security)); + options.Get("disableWebSecurity", &(out->disable_web_security)) && + options.Get("partitionId", &(out->partition_id)); } }; diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index b4f61d0f195..189fc938698 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -26,6 +26,21 @@ namespace atom { +namespace { + +const base::FilePath::CharType kStoragePartitionDirName[] = "Partitions"; + +void GetStoragePartitionConfig(const GURL& partition, + base::FilePath* partition_path, + bool* in_memory, + std::string* id) { + *in_memory = (partition.path() != "/persist"); + *id = partition.query(); + *partition_path = base::FilePath(kStoragePartitionDirName).AppendASCII(*id); +} + +} // namespace + // static AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL; @@ -40,6 +55,7 @@ AtomBrowserMainParts::AtomBrowserMainParts() } AtomBrowserMainParts::~AtomBrowserMainParts() { + STLDeleteValues(&browser_context_map_); for (const auto& callback : destruction_callbacks_) callback.Run(); } @@ -50,6 +66,22 @@ AtomBrowserMainParts* AtomBrowserMainParts::Get() { return self_; } +content::BrowserContext* AtomBrowserMainParts::GetBrowserContextForPartition( + const GURL& partition) { + std::string id; + bool in_memory; + base::FilePath partition_path; + GetStoragePartitionConfig(partition, &partition_path, &in_memory, &id); + auto item = browser_context_map_.find(id); + if (item != browser_context_map_.end()) + return item->second; + + auto browser_context = CreateBrowserContext(); + browser_context->Initialize(partition_path, in_memory); + browser_context_map_[id] = browser_context; + return browser_context; +} + void AtomBrowserMainParts::RegisterDestructionCallback( const base::Closure& callback) { destruction_callbacks_.push_back(callback); diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index a2909cac53d..993340bfb42 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -6,10 +6,13 @@ #define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_ #include +#include +#include #include "base/callback.h" #include "base/timer/timer.h" #include "brightray/browser/browser_main_parts.h" +#include "content/public/browser/browser_context.h" class BrowserProcess; @@ -29,6 +32,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { static AtomBrowserMainParts* Get(); + // Returns the BrowserContext associated with the partition. + content::BrowserContext* GetBrowserContextForPartition( + const GURL& partition); + // Register a callback that should be destroyed before JavaScript environment // gets destroyed. void RegisterDestructionCallback(const base::Closure& callback); @@ -70,6 +77,9 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { // List of callbacks should be executed before destroying JS env. std::list destruction_callbacks_; + // partition_id => browser_context + std::map browser_context_map_; + static AtomBrowserMainParts* self_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts); diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index 398cdb5d949..c0a87a7ac1c 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -1,3 +1,4 @@ +crypto = require 'crypto' ipc = require 'ipc' webContents = require 'web-contents' webViewManager = null # Doesn't exist in early initialization. @@ -38,12 +39,21 @@ moveLastToFirst = (list) -> getNextInstanceId = (webContents) -> ++nextInstanceId +# Generate URL encoded partition id. +getPartitionId = (partition='default') -> + persist = partition.startsWith('persist:') + # Guest site url will be chrome-guest://fake-host/{persist}?{partitionId} + partitionId = "chrome-guest://fake-host/" + partitionId += if persist then 'persist?' else '?' + partitionId += crypto.createHash('sha256').update(partition).digest('hex') + # Create a new guest instance. createGuest = (embedder, params) -> webViewManager ?= process.atomBinding 'web_view_manager' id = getNextInstanceId embedder - guest = webContents.create {isGuest: true, embedder} + partitionId = getPartitionId params.partition + guest = webContents.create {isGuest: true, partition: partitionId, embedder} guestInstances[id] = {guest, embedder} # Destroy guest when the embedder is gone or navigated. @@ -120,6 +130,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) -> plugins: params.plugins disableWebSecurity: params.disablewebsecurity preloadUrl: params.preload ? '' + partitionId: getPartitionId(params.partition) guest.attachParams = params embedderElementsMap[key] = guestInstanceId diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 7dba6c06dd3..50e07230197 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -48,7 +48,7 @@ void WebViewManager::AddGuest(int guest_instance_id, content::WebContents* web_contents, const WebViewInfo& info) { base::AutoLock auto_lock(lock_); - web_contents_embdder_map_[guest_instance_id] = { web_contents, embedder }; + web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder }; webview_info_map_[web_contents] = info; // Map the element in embedder to guest. @@ -59,11 +59,12 @@ void WebViewManager::AddGuest(int guest_instance_id, void WebViewManager::RemoveGuest(int guest_instance_id) { base::AutoLock auto_lock(lock_); - if (!ContainsKey(web_contents_embdder_map_, guest_instance_id)) + if (!ContainsKey(web_contents_embedder_map_, guest_instance_id)) return; - auto web_contents = web_contents_embdder_map_[guest_instance_id].web_contents; - web_contents_embdder_map_.erase(guest_instance_id); + auto web_contents = + web_contents_embedder_map_[guest_instance_id].web_contents; + web_contents_embedder_map_.erase(guest_instance_id); webview_info_map_.erase(web_contents); // Remove the record of element in embedder too. @@ -82,15 +83,15 @@ content::WebContents* WebViewManager::GetGuestByInstanceID( return nullptr; int guest_instance_id = element_instance_id_to_guest_map_[key]; - if (ContainsKey(web_contents_embdder_map_, guest_instance_id)) - return web_contents_embdder_map_[guest_instance_id].web_contents; + if (ContainsKey(web_contents_embedder_map_, guest_instance_id)) + return web_contents_embedder_map_[guest_instance_id].web_contents; else return nullptr; } bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents, const GuestCallback& callback) { - for (auto& item : web_contents_embdder_map_) + for (auto& item : web_contents_embedder_map_) if (item.second.embedder == embedder_web_contents && callback.Run(item.second.web_contents)) return true; diff --git a/atom/browser/web_view_manager.h b/atom/browser/web_view_manager.h index b1bea92702c..d8ed857b444 100644 --- a/atom/browser/web_view_manager.h +++ b/atom/browser/web_view_manager.h @@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/synchronization/lock.h" #include "content/public/browser/browser_plugin_guest_manager.h" +#include "content/public/browser/site_instance.h" namespace content { class BrowserContext; @@ -27,6 +28,7 @@ class WebViewManager : public content::BrowserPluginGuestManager { bool plugins; bool disable_web_security; base::FilePath preload_script; + GURL partition_id; }; // Finds the WebViewManager attached with |web_contents| and returns the @@ -57,7 +59,7 @@ class WebViewManager : public content::BrowserPluginGuestManager { content::WebContents* embedder; }; // guest_instance_id => (web_contents, embedder) - std::map web_contents_embdder_map_; + std::map web_contents_embedder_map_; struct ElementInstanceKey { int embedder_process_id;