Use patch worldScriptContext to get isolated context

This commit is contained in:
Kevin Sawicki 2016-12-15 08:26:37 -08:00
parent 309ac75284
commit 2e7dbe6c6b
3 changed files with 38 additions and 31 deletions

View file

@ -94,7 +94,7 @@ void AtomRenderViewObserver::EmitIPCEvent(blink::WebFrame* frame,
v8::Isolate* isolate = blink::mainThreadIsolate(); v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = renderer_client_->GetAPIContext(isolate); v8::Local<v8::Context> context = renderer_client_->GetContext(frame, isolate);
v8::Context::Scope context_scope(context); v8::Context::Scope context_scope(context);
// Only emit IPC event for context with node integration. // Only emit IPC event for context with node integration.

View file

@ -57,15 +57,22 @@ namespace atom {
namespace { namespace {
enum World {
MAIN_WORLD = 0,
ISOLATED_WORLD = 999
};
enum ExtensionGroup {
MAIN_GROUP = 1
};
// Helper class to forward the messages to the client. // Helper class to forward the messages to the client.
class AtomRenderFrameObserver : public content::RenderFrameObserver { class AtomRenderFrameObserver : public content::RenderFrameObserver {
public: public:
AtomRenderFrameObserver(content::RenderFrame* frame, AtomRenderFrameObserver(content::RenderFrame* frame,
AtomRendererClient* renderer_client, AtomRendererClient* renderer_client)
bool isolated_world)
: content::RenderFrameObserver(frame), : content::RenderFrameObserver(frame),
render_frame_(frame), render_frame_(frame),
isolated_world_(isolated_world),
renderer_client_(renderer_client) {} renderer_client_(renderer_client) {}
// content::RenderFrameObserver: // content::RenderFrameObserver:
@ -76,34 +83,37 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
void CreateIsolatedWorldContext() { void CreateIsolatedWorldContext() {
blink::WebScriptSource source("void 0"); blink::WebScriptSource source("void 0");
render_frame_->GetWebFrame()->executeScriptInIsolatedWorld( render_frame_->GetWebFrame()->executeScriptInIsolatedWorld(
World::ISOLATED, &source, 1, 1); World::ISOLATED_WORLD, &source, 1, ExtensionGroup::MAIN_GROUP);
} }
bool IsMainWorld(int world_id) { bool IsMainWorld(int world_id) {
return world_id == World::MAIN; return world_id == World::MAIN_WORLD;
} }
bool IsIsolatedWorld(int world_id) { bool IsIsolatedWorld(int world_id) {
return world_id == World::ISOLATED; return world_id == World::ISOLATED_WORLD;
}
bool NotifyClient(int world_id) {
if (renderer_client_->isolated_world())
return IsIsolatedWorld(world_id);
else
return IsMainWorld(world_id);
} }
void DidCreateScriptContext(v8::Handle<v8::Context> context, void DidCreateScriptContext(v8::Handle<v8::Context> context,
int extension_group, int extension_group,
int world_id) override { int world_id) override {
bool notify_client = if (NotifyClient(world_id))
isolated_world_ ? IsIsolatedWorld(world_id) : IsMainWorld(world_id);
if (notify_client)
renderer_client_->DidCreateScriptContext(context, render_frame_); renderer_client_->DidCreateScriptContext(context, render_frame_);
if (isolated_world_ && IsMainWorld(world_id)) if (renderer_client_->isolated_world() && IsMainWorld(world_id))
CreateIsolatedWorldContext(); CreateIsolatedWorldContext();
} }
void WillReleaseScriptContext(v8::Local<v8::Context> context, void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override { int world_id) override {
bool notify_client = if (NotifyClient(world_id))
isolated_world_ ? IsIsolatedWorld(world_id) : IsMainWorld(world_id);
if (notify_client)
renderer_client_->WillReleaseScriptContext(context, render_frame_); renderer_client_->WillReleaseScriptContext(context, render_frame_);
} }
@ -113,14 +123,8 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
private: private:
content::RenderFrame* render_frame_; content::RenderFrame* render_frame_;
bool isolated_world_;
AtomRendererClient* renderer_client_; AtomRendererClient* renderer_client_;
enum World {
MAIN = 0,
ISOLATED = 999
};
DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver); DISALLOW_COPY_AND_ASSIGN(AtomRenderFrameObserver);
}; };
@ -158,6 +162,8 @@ std::vector<std::string> ParseSchemesCLISwitch(const char* switch_name) {
AtomRendererClient::AtomRendererClient() AtomRendererClient::AtomRendererClient()
: node_bindings_(NodeBindings::Create(false)), : node_bindings_(NodeBindings::Create(false)),
atom_bindings_(new AtomBindings) { atom_bindings_(new AtomBindings) {
isolated_world_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kIsolatedWorld);
// Parse --standard-schemes=scheme1,scheme2 // Parse --standard-schemes=scheme1,scheme2
std::vector<std::string> standard_schemes_list = std::vector<std::string> standard_schemes_list =
ParseSchemesCLISwitch(switches::kStandardSchemes); ParseSchemesCLISwitch(switches::kStandardSchemes);
@ -203,10 +209,7 @@ void AtomRendererClient::RenderThreadStarted() {
void AtomRendererClient::RenderFrameCreated( void AtomRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) { content::RenderFrame* render_frame) {
new PepperHelper(render_frame); new PepperHelper(render_frame);
new AtomRenderFrameObserver(render_frame, this);
bool isolated_world = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kIsolatedWorld);
new AtomRenderFrameObserver(render_frame, this, isolated_world);
new ContentSettingsObserver(render_frame); new ContentSettingsObserver(render_frame);
@ -294,9 +297,6 @@ void AtomRendererClient::DidCreateScriptContext(
if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame)) if (!render_frame->IsMainFrame() && !IsDevToolsExtension(render_frame))
return; return;
api_context_.Reset(context->GetIsolate(), context);
api_context_.SetWeak();
// Whether the node binding has been initialized. // Whether the node binding has been initialized.
bool first_time = node_bindings_->uv_env() == nullptr; bool first_time = node_bindings_->uv_env() == nullptr;
@ -368,8 +368,13 @@ void AtomRendererClient::AddSupportedKeySystems(
AddChromeKeySystems(key_systems); AddChromeKeySystems(key_systems);
} }
v8::Local<v8::Context> AtomRendererClient::GetAPIContext(v8::Isolate* isolate) { v8::Local<v8::Context> AtomRendererClient::GetContext(
return api_context_.Get(isolate); blink::WebFrame* frame, v8::Isolate* isolate) {
if (isolated_world_)
return frame->worldScriptContext(
isolate, World::ISOLATED_WORLD, ExtensionGroup::MAIN_GROUP);
else
return frame->mainWorldScriptContext();
} }
} // namespace atom } // namespace atom

View file

@ -28,7 +28,9 @@ class AtomRendererClient : public content::ContentRendererClient {
v8::Handle<v8::Context> context, content::RenderFrame* render_frame); v8::Handle<v8::Context> context, content::RenderFrame* render_frame);
// Get the context that the Electron API is running in. // Get the context that the Electron API is running in.
v8::Local<v8::Context> GetAPIContext(v8::Isolate* isolate); v8::Local<v8::Context> GetContext(
blink::WebFrame* frame, v8::Isolate* isolate);
bool isolated_world() { return isolated_world_; }
private: private:
enum NodeIntegration { enum NodeIntegration {
@ -67,7 +69,7 @@ class AtomRendererClient : public content::ContentRendererClient {
std::unique_ptr<NodeBindings> node_bindings_; std::unique_ptr<NodeBindings> node_bindings_;
std::unique_ptr<AtomBindings> atom_bindings_; std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<PreferencesManager> preferences_manager_; std::unique_ptr<PreferencesManager> preferences_manager_;
v8::Persistent<v8::Context> api_context_; bool isolated_world_;
DISALLOW_COPY_AND_ASSIGN(AtomRendererClient); DISALLOW_COPY_AND_ASSIGN(AtomRendererClient);
}; };