Read guest view's info from WebContentsPreferences

This commit is contained in:
Cheng Zhao 2015-09-05 11:43:30 +09:00
parent b1afe538ee
commit 9c235509a6
8 changed files with 45 additions and 144 deletions

View file

@ -3,14 +3,12 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "atom/browser/web_view_constants.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h" #include "atom/browser/web_view_manager.h"
#include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h"
#include "atom/common/node_includes.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "native_mate/dictionary.h" #include "native_mate/dictionary.h"
#include "net/base/filename_util.h"
#include "atom/common/node_includes.h"
namespace mate { namespace mate {
@ -26,31 +24,6 @@ struct Converter<content::WebContents*> {
} }
}; };
template<>
struct Converter<atom::WebViewManager::WebViewInfo> {
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
atom::WebViewManager::WebViewInfo* out) {
Dictionary options;
if (!ConvertFromV8(isolate, val, &options))
return false;
GURL preload_url;
if (!options.Get(atom::web_view::kPreloadUrl, &preload_url))
return false;
if (!preload_url.is_empty() &&
!net::FileURLToFilePath(preload_url, &(out->preload_script)))
return false;
return options.Get(atom::web_view::kNodeIntegration,
&(out->node_integration)) &&
options.Get(atom::web_view::kPlugins, &(out->plugins)) &&
options.Get(atom::web_view::kPartitionId, &(out->partition_id)) &&
options.Get(atom::web_view::kDisableWebSecurity,
&(out->disable_web_security));
}
};
} // namespace mate } // namespace mate
namespace { namespace {
@ -69,17 +42,13 @@ void AddGuest(int guest_instance_id,
int element_instance_id, int element_instance_id,
content::WebContents* embedder, content::WebContents* embedder,
content::WebContents* guest_web_contents, content::WebContents* guest_web_contents,
atom::WebViewManager::WebViewInfo info) { const base::DictionaryValue& options) {
auto manager = GetWebViewManager(embedder); auto manager = GetWebViewManager(embedder);
if (manager) if (manager)
manager->AddGuest(guest_instance_id, element_instance_id, embedder, manager->AddGuest(guest_instance_id, element_instance_id, embedder,
guest_web_contents); guest_web_contents);
info.guest_instance_id = guest_instance_id; atom::WebContentsPreferences::From(guest_web_contents)->Merge(options);
info.embedder = embedder;
auto data = new atom::WebViewManager::WebViewInfoUserData(info);
guest_web_contents->SetUserData(
atom::web_view::kWebViewInfoKeyName, data);
} }
void RemoveGuest(content::WebContents* embedder, int guest_instance_id) { void RemoveGuest(content::WebContents* embedder, int guest_instance_id) {

View file

@ -16,8 +16,6 @@
#include "atom/browser/browser.h" #include "atom/browser/browser.h"
#include "atom/browser/native_window.h" #include "atom/browser/native_window.h"
#include "atom/browser/web_contents_preferences.h" #include "atom/browser/web_contents_preferences.h"
#include "atom/browser/web_view_manager.h"
#include "atom/browser/web_view_constants.h"
#include "atom/browser/window_list.h" #include "atom/browser/window_list.h"
#include "atom/common/options_switches.h" #include "atom/common/options_switches.h"
#include "base/command_line.h" #include "base/command_line.h"
@ -56,37 +54,6 @@ bool g_suppress_renderer_process_restart = false;
// Custom schemes to be registered to standard. // Custom schemes to be registered to standard.
std::string g_custom_schemes = ""; std::string g_custom_schemes = "";
// Find out the owner of the child process according to |process_id|.
enum ProcessOwner {
OWNER_NATIVE_WINDOW,
OWNER_GUEST_WEB_CONTENTS,
OWNER_NONE, // it might be devtools though.
};
ProcessOwner GetProcessOwner(int process_id,
NativeWindow** window,
WebViewManager::WebViewInfo* info) {
content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
if (!web_contents)
return OWNER_NONE;
// First search for NativeWindow.
*window = NativeWindow::FromWebContents(web_contents);
if (*window)
return OWNER_NATIVE_WINDOW;
// Then search for guest WebContents.
auto data = static_cast<WebViewManager::WebViewInfoUserData*>(
web_contents->GetUserData(web_view::kWebViewInfoKeyName));
if (data) {
*info = data->web_view_info();
return OWNER_GUEST_WEB_CONTENTS;
}
return OWNER_NONE;
}
scoped_refptr<net::X509Certificate> ImportCertFromFile( scoped_refptr<net::X509Certificate> ImportCertFromFile(
const base::FilePath& path) { const base::FilePath& path) {
if (path.empty()) if (path.empty())
@ -162,16 +129,7 @@ void AtomBrowserClient::OverrideWebkitPrefs(
// Custom preferences of guest page. // Custom preferences of guest page.
auto web_contents = content::WebContents::FromRenderViewHost(host); auto web_contents = content::WebContents::FromRenderViewHost(host);
auto info = static_cast<WebViewManager::WebViewInfoUserData*>( WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs);
web_contents->GetUserData(web_view::kWebViewInfoKeyName));
if (info) {
prefs->web_security_enabled = !info->web_view_info().disable_web_security;
return;
}
NativeWindow* window = NativeWindow::FromWebContents(web_contents);
if (window)
WebContentsPreferences::OverrideWebkitPrefs(web_contents, prefs);
} }
std::string AtomBrowserClient::GetApplicationLocale() { std::string AtomBrowserClient::GetApplicationLocale() {
@ -227,24 +185,14 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
if (ContainsKey(pending_processes_, process_id)) if (ContainsKey(pending_processes_, process_id))
process_id = pending_processes_[process_id]; process_id = pending_processes_[process_id];
NativeWindow* window; // Get the WebContents of the render process.
WebViewManager::WebViewInfo info; content::WebContents* web_contents = content::WebContents::FromRenderViewHost(
ProcessOwner owner = GetProcessOwner(process_id, &window, &info); content::RenderViewHost::FromID(process_id, kDefaultRoutingID));
if (!web_contents)
return;
if (owner == OWNER_NATIVE_WINDOW) { WebContentsPreferences::AppendExtraCommandLineSwitches(
WebContentsPreferences::AppendExtraCommandLineSwitches( web_contents, command_line);
window->web_contents(), command_line);
} else if (owner == OWNER_GUEST_WEB_CONTENTS) {
command_line->AppendSwitchASCII(
switches::kGuestInstanceID, base::IntToString(info.guest_instance_id));
command_line->AppendSwitchASCII(
switches::kNodeIntegration, info.node_integration ? "true" : "false");
if (info.plugins)
command_line->AppendSwitch(switches::kEnablePlugins);
if (!info.preload_script.empty())
command_line->AppendSwitchPath(
switches::kPreloadScript, info.preload_script);
}
} }
void AtomBrowserClient::DidCreatePpapiPlugin( void AtomBrowserClient::DidCreatePpapiPlugin(

View file

@ -150,7 +150,7 @@ AtomBrowserContext::GetDownloadManagerDelegate() {
content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() {
if (!guest_manager_) if (!guest_manager_)
guest_manager_.reset(new WebViewManager(this)); guest_manager_.reset(new WebViewManager);
return guest_manager_.get(); return guest_manager_.get();
} }

View file

@ -132,12 +132,14 @@ attachGuest = (embedder, elementInstanceId, guestInstanceId, params) ->
return unless guestInstances[oldGuestInstanceId]? return unless guestInstances[oldGuestInstanceId]?
destroyGuest embedder, oldGuestInstanceId destroyGuest embedder, oldGuestInstanceId
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences =
nodeIntegration: params.nodeintegration 'guest-instance-id': guestInstanceId
plugins: params.plugins 'node-integration': params.nodeintegration ? false
disableWebSecurity: params.disablewebsecurity 'plugins': params.plugins
preloadUrl: params.preload ? '' 'web-security': !params.disablewebsecurity
partitionId: getPartitionId(params.partition) webPreferences['preload-url'] = params.preload if params.preload
webPreferences['partition'] = getPartitionId(params.partition) if params.partition
webViewManager.addGuest guestInstanceId, elementInstanceId, embedder, guest, webPreferences
guest.attachParams = params guest.attachParams = params
embedderElementsMap[key] = guestInstanceId embedderElementsMap[key] = guestInstanceId

View file

@ -44,6 +44,10 @@ WebContentsPreferences::WebContentsPreferences(
WebContentsPreferences::~WebContentsPreferences() { WebContentsPreferences::~WebContentsPreferences() {
} }
void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
web_preferences_.MergeDictionary(&extend);
}
// static // static
WebContentsPreferences* WebContentsPreferences::From( WebContentsPreferences* WebContentsPreferences::From(
content::WebContents* web_contents) { content::WebContents* web_contents) {
@ -55,7 +59,9 @@ WebContentsPreferences* WebContentsPreferences::From(
void WebContentsPreferences::AppendExtraCommandLineSwitches( void WebContentsPreferences::AppendExtraCommandLineSwitches(
content::WebContents* web_contents, base::CommandLine* command_line) { content::WebContents* web_contents, base::CommandLine* command_line) {
WebContentsPreferences* self = From(web_contents); WebContentsPreferences* self = From(web_contents);
CHECK(self); if (!self)
return;
base::DictionaryValue& web_preferences = self->web_preferences_; base::DictionaryValue& web_preferences = self->web_preferences_;
bool b; bool b;
@ -110,12 +116,21 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
zoom_factor != 1.0) zoom_factor != 1.0)
command_line->AppendSwitchASCII(switches::kZoomFactor, command_line->AppendSwitchASCII(switches::kZoomFactor,
base::DoubleToString(zoom_factor)); base::DoubleToString(zoom_factor));
// --guest-instance-id, which is used to identify guest WebContents.
int guest_instance_id;
if (web_preferences.GetInteger(switches::kGuestInstanceID,
&guest_instance_id))
command_line->AppendSwitchASCII(switches::kGuestInstanceID,
base::IntToString(guest_instance_id));
} }
// static
void WebContentsPreferences::OverrideWebkitPrefs( void WebContentsPreferences::OverrideWebkitPrefs(
content::WebContents* web_contents, content::WebPreferences* prefs) { content::WebContents* web_contents, content::WebPreferences* prefs) {
WebContentsPreferences* self = From(web_contents); WebContentsPreferences* self = From(web_contents);
CHECK(self); if (!self)
return;
bool b; bool b;
if (self->web_preferences_.GetBoolean("javascript", &b)) if (self->web_preferences_.GetBoolean("javascript", &b))

View file

@ -37,6 +37,9 @@ class WebContentsPreferences
base::DictionaryValue&& web_preferences); base::DictionaryValue&& web_preferences);
~WebContentsPreferences() override; ~WebContentsPreferences() override;
// $.extend(|web_preferences_|, |new_web_preferences|).
void Merge(const base::DictionaryValue& new_web_preferences);
private: private:
friend class content::WebContentsUserData<WebContentsPreferences>; friend class content::WebContentsUserData<WebContentsPreferences>;

View file

@ -5,13 +5,12 @@
#include "atom/browser/web_view_manager.h" #include "atom/browser/web_view_manager.h"
#include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
namespace atom { namespace atom {
WebViewManager::WebViewManager(content::BrowserContext* context) { WebViewManager::WebViewManager() {
} }
WebViewManager::~WebViewManager() { WebViewManager::~WebViewManager() {
@ -21,7 +20,6 @@ void WebViewManager::AddGuest(int guest_instance_id,
int element_instance_id, int element_instance_id,
content::WebContents* embedder, content::WebContents* embedder,
content::WebContents* web_contents) { content::WebContents* web_contents) {
base::AutoLock auto_lock(lock_);
web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder }; web_contents_embedder_map_[guest_instance_id] = { web_contents, embedder };
// Map the element in embedder to guest. // Map the element in embedder to guest.
@ -31,7 +29,6 @@ void WebViewManager::AddGuest(int guest_instance_id,
} }
void WebViewManager::RemoveGuest(int guest_instance_id) { void WebViewManager::RemoveGuest(int guest_instance_id) {
base::AutoLock auto_lock(lock_);
if (!ContainsKey(web_contents_embedder_map_, guest_instance_id)) if (!ContainsKey(web_contents_embedder_map_, guest_instance_id))
return; return;

View file

@ -7,45 +7,14 @@
#include <map> #include <map>
#include "base/files/file_path.h"
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/browser_plugin_guest_manager.h" #include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/site_instance.h"
namespace content {
class BrowserContext;
class RenderProcessHost;
}
namespace atom { namespace atom {
class WebViewManager : public content::BrowserPluginGuestManager { class WebViewManager : public content::BrowserPluginGuestManager {
public: public:
struct WebViewInfo { WebViewManager();
int guest_instance_id; ~WebViewManager() override;
content::WebContents* embedder;
bool node_integration;
bool plugins;
bool disable_web_security;
base::FilePath preload_script;
GURL partition_id;
};
class WebViewInfoUserData : public base::SupportsUserData::Data {
public:
explicit WebViewInfoUserData(WebViewInfo info)
: web_view_info_(info) {}
~WebViewInfoUserData() override {}
WebViewInfo& web_view_info() { return web_view_info_; }
private:
WebViewInfo web_view_info_;
};
explicit WebViewManager(content::BrowserContext* context);
virtual ~WebViewManager();
void AddGuest(int guest_instance_id, void AddGuest(int guest_instance_id,
int element_instance_id, int element_instance_id,
@ -90,8 +59,6 @@ class WebViewManager : public content::BrowserPluginGuestManager {
// (embedder_process_id, element_instance_id) => guest_instance_id // (embedder_process_id, element_instance_id) => guest_instance_id
std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_; std::map<ElementInstanceKey, int> element_instance_id_to_guest_map_;
base::Lock lock_;
DISALLOW_COPY_AND_ASSIGN(WebViewManager); DISALLOW_COPY_AND_ASSIGN(WebViewManager);
}; };