Browse Source

webview: fix partition attribute

Robo 9 years ago
parent
commit
d180d3b168

+ 7 - 3
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);
   }

+ 2 - 1
atom/browser/api/atom_api_web_view_manager.cc

@@ -43,7 +43,8 @@ struct Converter<atom::WebViewManager::WebViewInfo> {
 
     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));
   }
 };
 

+ 32 - 0
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);

+ 10 - 0
atom/browser/atom_browser_main_parts.h

@@ -6,10 +6,13 @@
 #define ATOM_BROWSER_ATOM_BROWSER_MAIN_PARTS_H_
 
 #include <list>
+#include <map>
+#include <string>
 
 #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<base::Closure> destruction_callbacks_;
 
+  // partition_id => browser_context
+  std::map<std::string, content::BrowserContext*> browser_context_map_;
+
   static AtomBrowserMainParts* self_;
 
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts);

+ 12 - 1
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

+ 8 - 7
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;

+ 3 - 1
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<int, WebContentsWithEmbedder> web_contents_embdder_map_;
+  std::map<int, WebContentsWithEmbedder> web_contents_embedder_map_;
 
   struct ElementInstanceKey {
     int embedder_process_id;