Merge pull request #1097 from atom/fix-webview-race-condition
Fix the race condition when updating webview info
This commit is contained in:
commit
0b694dffd8
12 changed files with 248 additions and 303 deletions
7
atom.gyp
7
atom.gyp
|
@ -88,6 +88,7 @@
|
|||
'atom/browser/api/atom_api_tray.h',
|
||||
'atom/browser/api/atom_api_web_contents.cc',
|
||||
'atom/browser/api/atom_api_web_contents.h',
|
||||
'atom/browser/api/atom_api_web_view_manager.cc',
|
||||
'atom/browser/api/atom_api_window.cc',
|
||||
'atom/browser/api/atom_api_window.h',
|
||||
'atom/browser/api/event.cc',
|
||||
|
@ -190,10 +191,8 @@
|
|||
'atom/browser/ui/x/window_state_watcher.h',
|
||||
'atom/browser/ui/x/x_window_utils.cc',
|
||||
'atom/browser/ui/x/x_window_utils.h',
|
||||
'atom/browser/web_view/web_view_manager.cc',
|
||||
'atom/browser/web_view/web_view_manager.h',
|
||||
'atom/browser/web_view/web_view_renderer_state.cc',
|
||||
'atom/browser/web_view/web_view_renderer_state.h',
|
||||
'atom/browser/web_view_manager.cc',
|
||||
'atom/browser/web_view_manager.h',
|
||||
'atom/browser/web_dialog_helper.cc',
|
||||
'atom/browser/web_dialog_helper.h',
|
||||
'atom/browser/window_list.cc',
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_dialog_helper.h"
|
||||
#include "atom/browser/web_view/web_view_renderer_state.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/api/api_messages.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
|
@ -39,9 +39,9 @@ v8::Persistent<v8::ObjectTemplate> template_;
|
|||
|
||||
// Get the window that has the |guest| embedded.
|
||||
NativeWindow* GetWindowFromGuest(const content::WebContents* guest) {
|
||||
int guest_process_id = guest->GetRenderProcessHost()->GetID();
|
||||
WebViewRendererState::WebViewInfo info;
|
||||
if (!WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info))
|
||||
auto process = guest->GetRenderProcessHost();
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(process, &info))
|
||||
return nullptr;
|
||||
return NativeWindow::FromRenderView(
|
||||
info.embedder->GetRenderProcessHost()->GetID(),
|
||||
|
|
92
atom/browser/api/atom_api_web_view_manager.cc
Normal file
92
atom/browser/api/atom_api_web_view_manager.cc
Normal file
|
@ -0,0 +1,92 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::WebContents*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* contents;
|
||||
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
|
||||
return false;
|
||||
*out = contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<atom::WebViewManager::WebViewInfo> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
atom::WebViewManager::WebViewInfo* out) {
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
|
||||
GURL preload_url;
|
||||
if (!options.Get("preloadUrl", &preload_url))
|
||||
return false;
|
||||
|
||||
if (!preload_url.is_empty() &&
|
||||
!net::FileURLToFilePath(preload_url, &(out->preload_script)))
|
||||
return false;
|
||||
|
||||
return options.Get("nodeIntegration", &(out->node_integration)) &&
|
||||
options.Get("plugins", &(out->plugins)) &&
|
||||
options.Get("disableWebSecurity", &(out->disable_web_security));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace {
|
||||
|
||||
atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) {
|
||||
auto context = web_contents->GetBrowserContext();
|
||||
if (context) {
|
||||
auto manager = context->GetGuestManager();
|
||||
return static_cast<atom::WebViewManager*>(manager);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* guest_web_contents,
|
||||
atom::WebViewManager::WebViewInfo info) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
if (manager) {
|
||||
info.guest_instance_id = guest_instance_id;
|
||||
info.embedder = embedder;
|
||||
manager->AddGuest(guest_instance_id, element_instance_id, embedder,
|
||||
guest_web_contents, info);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {
|
||||
auto manager = GetWebViewManager(embedder);
|
||||
if (manager)
|
||||
manager->RemoveGuest(guest_instance_id);
|
||||
}
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||
v8::Handle<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("addGuest", &AddGuest);
|
||||
dict.SetMethod("removeGuest", &RemoveGuest);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize)
|
|
@ -9,7 +9,7 @@
|
|||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_speech_recognition_manager_delegate.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/web_view/web_view_renderer_state.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
|
@ -97,16 +97,15 @@ void AtomBrowserClient::OverrideWebkitPrefs(
|
|||
}
|
||||
|
||||
// Custom preferences of guest page.
|
||||
int guest_process_id = render_view_host->GetProcess()->GetID();
|
||||
WebViewRendererState::WebViewInfo info;
|
||||
if (WebViewRendererState::GetInstance()->GetInfo(guest_process_id, &info)) {
|
||||
auto process = render_view_host->GetProcess();
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(process, &info)) {
|
||||
prefs->web_security_enabled = !info.disable_web_security;
|
||||
return;
|
||||
}
|
||||
|
||||
NativeWindow* window = NativeWindow::FromRenderView(
|
||||
render_view_host->GetProcess()->GetID(),
|
||||
render_view_host->GetRoutingID());
|
||||
process->GetID(), render_view_host->GetRoutingID());
|
||||
if (window)
|
||||
window->OverrideWebkitPrefs(url, prefs);
|
||||
}
|
||||
|
@ -154,8 +153,9 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
|||
window->AppendExtraCommandLineSwitches(command_line, child_process_id);
|
||||
} else {
|
||||
// Append commnad line arguments for guest web view.
|
||||
WebViewRendererState::WebViewInfo info;
|
||||
if (WebViewRendererState::GetInstance()->GetInfo(child_process_id, &info)) {
|
||||
auto child_process = content::RenderProcessHost::FromID(child_process_id);
|
||||
WebViewManager::WebViewInfo info;
|
||||
if (WebViewManager::GetInfoForProcess(child_process, &info)) {
|
||||
command_line->AppendSwitchASCII(
|
||||
switches::kGuestInstanceID,
|
||||
base::IntToString(info.guest_instance_id));
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/net/atom_url_request_job_factory.h"
|
||||
#include "atom/browser/net/asar/asar_protocol_handler.h"
|
||||
#include "atom/browser/web_view/web_view_manager.h"
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/threading/sequenced_worker_pool.h"
|
||||
|
|
|
@ -39,7 +39,7 @@ createGuest = (embedder, params) ->
|
|||
# Destroy guest when the embedder is gone or navigated.
|
||||
destroyEvents = ['destroyed', 'crashed', 'did-navigate-to-different-page']
|
||||
destroy = ->
|
||||
destroyGuest id if guestInstances[id]?
|
||||
destroyGuest embedder, id if guestInstances[id]?
|
||||
embedder.once event, destroy for event in destroyEvents
|
||||
guest.once 'destroyed', ->
|
||||
embedder.removeListener event, destroy for event in destroyEvents
|
||||
|
@ -90,7 +90,7 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
|
|||
return unless oldGuestInstanceId != guestInstanceId
|
||||
|
||||
return unless guestInstances[oldGuestInstanceId]?
|
||||
destroyGuest oldGuestInstanceId
|
||||
destroyGuest embedder, oldGuestInstanceId
|
||||
|
||||
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest,
|
||||
nodeIntegration: params.nodeintegration
|
||||
|
@ -103,8 +103,8 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
|
|||
reverseEmbedderElementsMap[guestInstanceId] = key
|
||||
|
||||
# Destroy an existing guest instance.
|
||||
destroyGuest = (id) ->
|
||||
webViewManager.removeGuest id
|
||||
destroyGuest = (embedder, id) ->
|
||||
webViewManager.removeGuest embedder, id
|
||||
guestInstances[id].guest.destroy()
|
||||
delete guestInstances[id]
|
||||
|
||||
|
@ -120,7 +120,7 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
|
|||
attachGuest event.sender, elementInstanceId, guestInstanceId, params
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
|
||||
destroyGuest id
|
||||
destroyGuest event.sender, id
|
||||
|
||||
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
|
||||
guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/web_view/web_view_manager.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/web_view/web_view_renderer_state.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::WebContents*> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
content::WebContents** out) {
|
||||
atom::api::WebContents* contents;
|
||||
if (!Converter<atom::api::WebContents*>::FromV8(isolate, val, &contents))
|
||||
return false;
|
||||
*out = contents->web_contents();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<atom::WebViewManager::WebViewOptions> {
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
atom::WebViewManager::WebViewOptions* out) {
|
||||
Dictionary options;
|
||||
if (!ConvertFromV8(isolate, val, &options))
|
||||
return false;
|
||||
return options.Get("nodeIntegration", &(out->node_integration)) &&
|
||||
options.Get("plugins", &(out->plugins)) &&
|
||||
options.Get("preloadUrl", &(out->preload_url)) &&
|
||||
options.Get("disableWebSecurity", &(out->disable_web_security));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
|
||||
WebViewManager::WebViewManager(content::BrowserContext* context) {
|
||||
}
|
||||
|
||||
WebViewManager::~WebViewManager() {
|
||||
}
|
||||
|
||||
void WebViewManager::AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* web_contents,
|
||||
const WebViewOptions& options) {
|
||||
web_contents_map_[guest_instance_id] = { web_contents, embedder };
|
||||
|
||||
WebViewRendererState::WebViewInfo web_view_info = {
|
||||
guest_instance_id,
|
||||
embedder,
|
||||
options.node_integration,
|
||||
options.plugins,
|
||||
options.disable_web_security,
|
||||
};
|
||||
net::FileURLToFilePath(options.preload_url, &web_view_info.preload_script);
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO,
|
||||
FROM_HERE,
|
||||
base::Bind(&WebViewRendererState::AddGuest,
|
||||
base::Unretained(WebViewRendererState::GetInstance()),
|
||||
web_contents->GetRenderProcessHost()->GetID(),
|
||||
web_view_info));
|
||||
|
||||
// Map the element in embedder to guest.
|
||||
ElementInstanceKey key(embedder, element_instance_id);
|
||||
element_instance_id_to_guest_map_[key] = guest_instance_id;
|
||||
}
|
||||
|
||||
void WebViewManager::RemoveGuest(int guest_instance_id) {
|
||||
if (!ContainsKey(web_contents_map_, guest_instance_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto web_contents = web_contents_map_[guest_instance_id].web_contents;
|
||||
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(
|
||||
&WebViewRendererState::RemoveGuest,
|
||||
base::Unretained(WebViewRendererState::GetInstance()),
|
||||
web_contents->GetRenderProcessHost()->GetID()));
|
||||
|
||||
web_contents_map_.erase(guest_instance_id);
|
||||
|
||||
// Remove the record of element in embedder too.
|
||||
for (const auto& element : element_instance_id_to_guest_map_)
|
||||
if (element.second == guest_instance_id) {
|
||||
element_instance_id_to_guest_map_.erase(element.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
||||
content::WebContents* embedder,
|
||||
int element_instance_id) {
|
||||
ElementInstanceKey key(embedder, element_instance_id);
|
||||
if (!ContainsKey(element_instance_id_to_guest_map_, key))
|
||||
return nullptr;
|
||||
|
||||
int guest_instance_id = element_instance_id_to_guest_map_[key];
|
||||
if (ContainsKey(web_contents_map_, guest_instance_id))
|
||||
return web_contents_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_map_)
|
||||
if (item.second.embedder == embedder_web_contents &&
|
||||
callback.Run(item.second.web_contents))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||
v8::Handle<v8::Context> context, void* priv) {
|
||||
using atom::WebViewManager;
|
||||
auto manager = static_cast<WebViewManager*>(
|
||||
atom::AtomBrowserContext::Get()->GetGuestManager());
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("addGuest",
|
||||
base::Bind(&WebViewManager::AddGuest,
|
||||
base::Unretained(manager)));
|
||||
dict.SetMethod("removeGuest",
|
||||
base::Bind(&WebViewManager::RemoveGuest,
|
||||
base::Unretained(manager)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_web_view_manager, Initialize)
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/web_view/web_view_renderer_state.h"
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
WebViewRendererState* WebViewRendererState::GetInstance() {
|
||||
return Singleton<WebViewRendererState>::get();
|
||||
}
|
||||
|
||||
WebViewRendererState::WebViewRendererState() {
|
||||
}
|
||||
|
||||
WebViewRendererState::~WebViewRendererState() {
|
||||
}
|
||||
|
||||
bool WebViewRendererState::IsGuest(int render_process_id) {
|
||||
return webview_info_map_.find(render_process_id) !=
|
||||
webview_info_map_.end();
|
||||
}
|
||||
|
||||
void WebViewRendererState::AddGuest(int guest_process_id,
|
||||
const WebViewInfo& webview_info) {
|
||||
webview_info_map_[guest_process_id] = webview_info;
|
||||
}
|
||||
|
||||
void WebViewRendererState::RemoveGuest(int guest_process_id) {
|
||||
webview_info_map_.erase(guest_process_id);
|
||||
}
|
||||
|
||||
bool WebViewRendererState::GetInfo(int guest_process_id,
|
||||
WebViewInfo* webview_info) {
|
||||
WebViewInfoMap::iterator iter = webview_info_map_.find(guest_process_id);
|
||||
if (iter != webview_info_map_.end()) {
|
||||
*webview_info = iter->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_
|
||||
#define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/memory/singleton.h"
|
||||
|
||||
namespace content {
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class WebViewManager;
|
||||
|
||||
// This class keeps track of <webview> renderer state for use on the IO thread.
|
||||
// All methods should be called on the IO thread.
|
||||
class WebViewRendererState {
|
||||
public:
|
||||
struct WebViewInfo {
|
||||
int guest_instance_id;
|
||||
content::WebContents* embedder;
|
||||
bool node_integration;
|
||||
bool plugins;
|
||||
bool disable_web_security;
|
||||
base::FilePath preload_script;
|
||||
};
|
||||
|
||||
static WebViewRendererState* GetInstance();
|
||||
|
||||
// Looks up the information for the embedder <webview> for a given render
|
||||
// view, if one exists. Called on the IO thread.
|
||||
bool GetInfo(int guest_process_id, WebViewInfo* webview_info);
|
||||
|
||||
// Returns true if the given renderer is used by webviews.
|
||||
bool IsGuest(int render_process_id);
|
||||
|
||||
private:
|
||||
friend class WebViewManager;
|
||||
friend struct DefaultSingletonTraits<WebViewRendererState>;
|
||||
|
||||
typedef std::map<int, WebViewInfo> WebViewInfoMap;
|
||||
|
||||
WebViewRendererState();
|
||||
~WebViewRendererState();
|
||||
|
||||
// Adds or removes a <webview> guest render process from the set.
|
||||
void AddGuest(int render_process_id, const WebViewInfo& webview_info);
|
||||
void RemoveGuest(int render_process_id);
|
||||
|
||||
WebViewInfoMap webview_info_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebViewRendererState);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_WEB_VIEW_WEB_VIEW_RENDERER_STATE_H_
|
101
atom/browser/web_view_manager.cc
Normal file
101
atom/browser/web_view_manager.cc
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/web_view_manager.h"
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
// static
|
||||
bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process,
|
||||
WebViewInfo* info) {
|
||||
if (!process)
|
||||
return false;
|
||||
auto context = process->GetBrowserContext();
|
||||
if (!context)
|
||||
return false;
|
||||
auto manager = context->GetGuestManager();
|
||||
if (!manager)
|
||||
return false;
|
||||
return static_cast<WebViewManager*>(manager)->GetInfo(process->GetID(), info);
|
||||
}
|
||||
|
||||
WebViewManager::WebViewManager(content::BrowserContext* context) {
|
||||
}
|
||||
|
||||
WebViewManager::~WebViewManager() {
|
||||
}
|
||||
|
||||
void WebViewManager::AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* web_contents,
|
||||
const WebViewInfo& info) {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
web_contents_embdder_map_[guest_instance_id] = { web_contents, embedder };
|
||||
|
||||
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
webview_info_map_[guest_process_id] = info;
|
||||
|
||||
// Map the element in embedder to guest.
|
||||
ElementInstanceKey key(embedder, element_instance_id);
|
||||
element_instance_id_to_guest_map_[key] = guest_instance_id;
|
||||
}
|
||||
|
||||
void WebViewManager::RemoveGuest(int guest_instance_id) {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
if (!ContainsKey(web_contents_embdder_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);
|
||||
|
||||
int guest_process_id = web_contents->GetRenderProcessHost()->GetID();
|
||||
webview_info_map_.erase(guest_process_id);
|
||||
|
||||
// Remove the record of element in embedder too.
|
||||
for (const auto& element : element_instance_id_to_guest_map_)
|
||||
if (element.second == guest_instance_id) {
|
||||
element_instance_id_to_guest_map_.erase(element.first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool WebViewManager::GetInfo(int guest_process_id, WebViewInfo* webview_info) {
|
||||
base::AutoLock auto_lock(lock_);
|
||||
WebViewInfoMap::iterator iter = webview_info_map_.find(guest_process_id);
|
||||
if (iter != webview_info_map_.end()) {
|
||||
*webview_info = iter->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
content::WebContents* WebViewManager::GetGuestByInstanceID(
|
||||
content::WebContents* embedder,
|
||||
int element_instance_id) {
|
||||
ElementInstanceKey key(embedder, element_instance_id);
|
||||
if (!ContainsKey(element_instance_id_to_guest_map_, key))
|
||||
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;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents,
|
||||
const GuestCallback& callback) {
|
||||
for (auto& item : web_contents_embdder_map_)
|
||||
if (item.second.embedder == embedder_web_contents &&
|
||||
callback.Run(item.second.web_contents))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace atom
|
|
@ -2,39 +2,52 @@
|
|||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
|
||||
#define ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
|
||||
#ifndef ATOM_BROWSER_WEB_VIEW_MANAGER_H_
|
||||
#define ATOM_BROWSER_WEB_VIEW_MANAGER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/browser_plugin_guest_manager.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
class RenderProcessHost;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
class WebViewManager : public content::BrowserPluginGuestManager {
|
||||
public:
|
||||
explicit WebViewManager(content::BrowserContext* context);
|
||||
virtual ~WebViewManager();
|
||||
|
||||
struct WebViewOptions {
|
||||
struct WebViewInfo {
|
||||
int guest_instance_id;
|
||||
content::WebContents* embedder;
|
||||
bool node_integration;
|
||||
bool plugins;
|
||||
bool disable_web_security;
|
||||
GURL preload_url;
|
||||
base::FilePath preload_script;
|
||||
};
|
||||
|
||||
// Finds the WebViewManager attached with |process| and returns the
|
||||
// WebViewInfo of it.
|
||||
static bool GetInfoForProcess(content::RenderProcessHost* process,
|
||||
WebViewInfo* info);
|
||||
|
||||
explicit WebViewManager(content::BrowserContext* context);
|
||||
virtual ~WebViewManager();
|
||||
|
||||
void AddGuest(int guest_instance_id,
|
||||
int element_instance_id,
|
||||
content::WebContents* embedder,
|
||||
content::WebContents* web_contents,
|
||||
const WebViewOptions& options);
|
||||
const WebViewInfo& info);
|
||||
void RemoveGuest(int guest_instance_id);
|
||||
|
||||
// Looks up the information for the embedder <webview> for a given render
|
||||
// view, if one exists. Called on the IO thread.
|
||||
bool GetInfo(int guest_process_id, WebViewInfo* webview_info);
|
||||
|
||||
protected:
|
||||
// content::BrowserPluginGuestManager:
|
||||
content::WebContents* GetGuestByInstanceID(
|
||||
|
@ -45,19 +58,16 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
|||
|
||||
private:
|
||||
struct WebContentsWithEmbedder {
|
||||
content::WebContents* web_contents; // Weak ref.
|
||||
content::WebContents* web_contents;
|
||||
content::WebContents* embedder;
|
||||
};
|
||||
std::map<int, WebContentsWithEmbedder> web_contents_map_;
|
||||
// guest_instance_id => (web_contents, embedder)
|
||||
std::map<int, WebContentsWithEmbedder> web_contents_embdder_map_;
|
||||
|
||||
struct ElementInstanceKey {
|
||||
content::WebContents* owner_web_contents;
|
||||
int element_instance_id;
|
||||
|
||||
ElementInstanceKey()
|
||||
: owner_web_contents(nullptr),
|
||||
element_instance_id(0) {}
|
||||
|
||||
ElementInstanceKey(content::WebContents* owner_web_contents,
|
||||
int element_instance_id)
|
||||
: owner_web_contents(owner_web_contents),
|
||||
|
@ -74,11 +84,18 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
|||
(element_instance_id == other.element_instance_id);
|
||||
}
|
||||
};
|
||||
// (web_contents, element_instance_id) => guest_instance_id
|
||||
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
|
||||
|
||||
typedef std::map<int, WebViewInfo> WebViewInfoMap;
|
||||
// guest_process_id => (guest_instance_id, embedder, ...)
|
||||
WebViewInfoMap webview_info_map_;
|
||||
|
||||
base::Lock lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebViewManager);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_WEB_VIEW_WEB_VIEW_MANAGER_H_
|
||||
#endif // ATOM_BROWSER_WEB_VIEW_MANAGER_H_
|
|
@ -66,6 +66,7 @@ REFERENCE_MODULE(atom_browser_protocol);
|
|||
REFERENCE_MODULE(atom_browser_global_shortcut);
|
||||
REFERENCE_MODULE(atom_browser_tray);
|
||||
REFERENCE_MODULE(atom_browser_web_contents);
|
||||
REFERENCE_MODULE(atom_browser_web_view_manager);
|
||||
REFERENCE_MODULE(atom_browser_window);
|
||||
REFERENCE_MODULE(atom_common_asar);
|
||||
REFERENCE_MODULE(atom_common_clipboard);
|
||||
|
|
Loading…
Reference in a new issue