Skip to content
This repository has been archived by the owner on Jan 4, 2019. It is now read-only.

Commit

Permalink
allow switching extension ids
Browse files Browse the repository at this point in the history
  • Loading branch information
bridiver committed May 31, 2017
1 parent e3d617f commit 7b0352f
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 82 deletions.
222 changes: 143 additions & 79 deletions atom/browser/javascript_environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ using extensions::RequestSender;
using extensions::ScriptContext;
using extensions::ScriptContextSet;
using extensions::SendRequestNatives;
using extensions::UnloadedExtensionInfo;
using extensions::UtilsNativeHandler;
using extensions::V8ContextNativeHandler;
using extensions::V8SchemaRegistry;
Expand Down Expand Up @@ -199,7 +200,7 @@ class LocalRequestSender : public RequestSender {
ExtensionHostMsg_Request_Params& params) override {
params.worker_thread_id = worker_thread_id_;
params.service_worker_version_id = service_worker_version_id_;
params.extension_id = kInternalExtensionId;

if (for_io_thread) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
Expand Down Expand Up @@ -310,7 +311,7 @@ JavascriptEnvironment* JavascriptEnvironment::Get() {
return lazy_tls.Pointer()->Get();
}

scoped_refptr<const Extension> CreateExtension(
scoped_refptr<const Extension> CreateInternalExtension(
BrowserContext* browser_context) {
base::DictionaryValue manifest;
manifest.SetString("name", std::string("Internal Extension"));
Expand Down Expand Up @@ -359,50 +360,125 @@ JavascriptEnvironment::JavascriptEnvironment()
context_holder_->SetContext(ctx);
context()->Enter();

if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
blink_platform_impl_.reset(new content::BlinkPlatformImpl);
blink::Platform::Initialize(blink_platform_impl_.get());
}

PopulateSourceMap();

ModuleRegistry* registry = ModuleRegistry::From(context());
registry->AddBuiltinModule(isolate(),
gin::Console::kModuleName,
gin::Console::GetModule(isolate()));

fake_render_process_host_->AddFilter(
new LocalRequestSenderMessageFilter(base::ThreadTaskRunnerHandle::Get()));

int worker_thread_id_ = -1;
if (V8WorkerThread::current()) {
worker_thread_id_ = V8WorkerThread::current()->GetThreadId();
} else {
worker_thread_id_ = BrowserThread::UI;
}

bindings_system_.reset(new JsExtensionBindingsSystem(
source_map_.GetResourceBundleSourceMap(),
base::MakeUnique<LocalRequestSender>(
dispatcher_->AsWeakPtr(),
fake_render_process_host_->GetID(), worker_thread_id_)));

auto extension_registry =
extensions::ExtensionRegistry::Get(browser_context_);
extension_ = extension_registry->GetExtensionById(kInternalExtensionId,
ExtensionRegistry::ENABLED);
if (!extension_) {
const Extension* internal_extension =
extension_registry->GetExtensionById(kInternalExtensionId,
ExtensionRegistry::ENABLED);
extension_registry->AddObserver(this);
if (!internal_extension) {
auto extension_service =
ExtensionSystem::Get(browser_context_)->extension_service();
extension_ = extension_service->AddExtension(
CreateExtension(browser_context_).get());
internal_extension = extension_service->AddExtension(
CreateInternalExtension(browser_context_).get());
}
DCHECK(extension_);
DCHECK(internal_extension);
SetExtension(internal_extension);
}

fake_render_process_host_->AddExtension(extension_);
fake_render_process_host_->AddFilter(
new LocalRequestSenderMessageFilter(base::ThreadTaskRunnerHandle::Get()));
JavascriptEnvironment::~JavascriptEnvironment() {
auto extension_registry =
extensions::ExtensionRegistry::Get(browser_context_);
extension_registry->RemoveObserver(this);
lazy_tls.Pointer()->Set(NULL);
context()->Exit();
if (script_context_.get() && script_context_->is_valid()) {
DestroyScriptContext();
fake_render_process_host_->Cleanup();
}
}

void JavascriptEnvironment::DestroyScriptContext() {
if (script_context_.get() && script_context_->is_valid()) {
bindings_system_->WillReleaseScriptContext(script_context_.get());
const Extension* extension = script_context_->extension();
if (extension) {
fake_render_process_host_->RemoveExtension(extension);
}
script_context_->Invalidate();
script_context_.reset();
}
}

script_context_.reset(new ScriptContext(context(),
void JavascriptEnvironment::SetExtension(const Extension* extension) {
if (!script_context_.get() ||
extension != script_context_->extension()) {
DestroyScriptContext();
script_context_.reset(CreateScriptContext(extension));
}
}

void JavascriptEnvironment::OnExtensionUnloaded(content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
if (browser_context == browser_context_ &&
extension && script_context_->extension() &&
extension->id() == script_context_->extension()->id()) {
DCHECK(extension->id() != kInternalExtensionId);

auto extension_registry =
extensions::ExtensionRegistry::Get(browser_context_);
const Extension* internal_extension =
extension_registry->GetExtensionById(kInternalExtensionId,
ExtensionRegistry::ENABLED);
DCHECK(internal_extension);
SetExtension(internal_extension);
}
}

ScriptContext* JavascriptEnvironment::CreateScriptContext(const Extension* extension) {
fake_render_process_host_->AddExtension(extension);

ScriptContext* script_context = new ScriptContext(context(),
nullptr, // WebFrame
extension_, // Extension
extension, // Extension
Feature::SERVICE_WORKER_CONTEXT,
extension_, // Effective Extension
Feature::SERVICE_WORKER_CONTEXT));
int worker_thread_id = -1;
if (V8WorkerThread::current()) {
worker_thread_id = V8WorkerThread::current()->GetThreadId();
} else {
worker_thread_id = BrowserThread::UI;
}
script_context_->set_url(
GURL("chrome://brave/worker/" + std::to_string(worker_thread_id)));
{
std::unique_ptr<ModuleSystem> module_system(
new ModuleSystem(script_context_.get(), &source_map_));
script_context_->set_module_system(std::move(module_system));
script_context_->module_system()->RegisterNativeHandler(
"path", std::unique_ptr<extensions::NativeHandler>(
new brave::PathBindings(script_context_.get(), &source_map_)));
extension, // Effective Extension
Feature::SERVICE_WORKER_CONTEXT);

if (extension) {
script_context->set_url(
GURL("chrome://brave/worker/" +
extension->id() + "/" + std::to_string(worker_thread_id_)));
}
std::unique_ptr<ModuleSystem> module_system(
new ModuleSystem(script_context, &source_map_));
script_context->set_module_system(std::move(module_system));

DidCreateScriptContext(script_context);
return script_context;
}

void JavascriptEnvironment::DidCreateScriptContext(
ScriptContext* script_context) {
v8::Local<v8::Object> global = context()->Global();
v8::Local<v8::Object> muon = v8::Object::New(isolate_);
global->Set(v8::String::NewFromUtf8(isolate_, "muon"), muon);
Expand All @@ -412,56 +488,29 @@ JavascriptEnvironment::JavascriptEnvironment()
global->Set(v8::String::NewFromUtf8(isolate_, "navigator"), navigator);

v8::Local<v8::Object> shared_memory =
brave::SharedMemoryBindings::API(script_context_.get());
brave::SharedMemoryBindings::API(script_context);
muon->Set(v8::String::NewFromUtf8(isolate_, "shared_memory"), shared_memory);

v8::Local<v8::Object> file =
brave::FileBindings::API(script_context_.get());
brave::FileBindings::API(script_context);
muon->Set(v8::String::NewFromUtf8(isolate_, "file"), file);

v8::Local<v8::Object> url =
brave::URLBindings::API(script_context_.get());
brave::URLBindings::API(script_context);
muon->Set(v8::String::NewFromUtf8(isolate_, "url"), url);

if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
blink_platform_impl_.reset(new content::BlinkPlatformImpl);
blink::Platform::Initialize(blink_platform_impl_.get());
}

bindings_system_.reset(new JsExtensionBindingsSystem(
source_map_.GetResourceBundleSourceMap(),
base::MakeUnique<LocalRequestSender>(
dispatcher_->AsWeakPtr(),
fake_render_process_host_->GetID(), worker_thread_id))),

PopulateSourceMap();
DidCreateScriptContext(script_context_.get());
}

JavascriptEnvironment::~JavascriptEnvironment() {
lazy_tls.Pointer()->Set(NULL);
context()->Exit();
if (script_context_.get() && script_context_->is_valid()) {
bindings_system_->WillReleaseScriptContext(script_context_.get());
script_context_->Invalidate();
fake_render_process_host_->RemoveExtension(extension_);
fake_render_process_host_->Cleanup();
}
}

void JavascriptEnvironment::DidCreateScriptContext(ScriptContext* context) {
// Enable natives in startup.
extensions::ModuleSystem* module_system = context->module_system();
extensions::ModuleSystem* module_system = script_context->module_system();
extensions::ModuleSystem::NativesEnabledScope
natives_enabled_scope(module_system);

RegisterNativeHandlers(module_system,
context,
script_context,
bindings_system_->GetRequestSender(),
v8_schema_registry_.get());

bindings_system_->DidCreateScriptContext(context);
bindings_system_->UpdateBindingsForContext(context);
bindings_system_->DidCreateScriptContext(script_context);
bindings_system_->UpdateBindingsForContext(script_context);
}

void JavascriptEnvironment::PopulateSourceMap() {
Expand Down Expand Up @@ -501,41 +550,56 @@ void JavascriptEnvironment::DispatchEvent(

void JavascriptEnvironment::RegisterNativeHandlers(
extensions::ModuleSystem* module_system,
ScriptContext* context,
ScriptContext* script_context,
RequestSender* request_sender,
V8SchemaRegistry* v8_schema_registry) {
module_system->RegisterNativeHandler(
"path",
std::unique_ptr<extensions::NativeHandler>(
new brave::PathBindings(script_context, &source_map_)));
module_system->RegisterNativeHandler(
"logging",
std::unique_ptr<NativeHandler>(new LoggingNativeHandler(context)));
std::unique_ptr<NativeHandler>(
new LoggingNativeHandler(script_context)));
module_system->RegisterNativeHandler("schema_registry",
v8_schema_registry->AsNativeHandler());
module_system->RegisterNativeHandler(
"v8_context",
std::unique_ptr<NativeHandler>(new V8ContextNativeHandler(context)));
"v8_script_context",
std::unique_ptr<NativeHandler>(
new V8ContextNativeHandler(script_context)));
module_system->RegisterNativeHandler(
"sendRequest", std::unique_ptr<NativeHandler>(
new SendRequestNatives(request_sender, context)));
new SendRequestNatives(request_sender, script_context)));
module_system->RegisterNativeHandler(
"event_natives",
std::unique_ptr<NativeHandler>(new EventBindings(context)));
std::unique_ptr<NativeHandler>(new EventBindings(script_context)));
module_system->RegisterNativeHandler(
"utils", std::unique_ptr<NativeHandler>(new UtilsNativeHandler(context)));
"utils", std::unique_ptr<NativeHandler>(
new UtilsNativeHandler(script_context)));
module_system->RegisterNativeHandler(
"id_generator",
std::unique_ptr<NativeHandler>(new IdGeneratorCustomBindings(context)));
std::unique_ptr<NativeHandler>(
new IdGeneratorCustomBindings(script_context)));
module_system->RegisterNativeHandler(
"process",
std::unique_ptr<NativeHandler>(new ProcessInfoNativeHandler(
context,
std::string(), /* extension id */
context->GetContextTypeDescription(),
false, /* incognito process */
true, /* component_extension */
2, /* manifest version */
script_context,
script_context->extension()
? script_context->extension()->id()
: std::string(),
script_context->GetContextTypeDescription(),
browser_context_->IsOffTheRecord(),
script_context->extension()
? script_context->extension()->location() ==
extensions::Manifest::COMPONENT
: false,
script_context->extension()
? script_context->extension()->manifest_version()
: 2,
false /* sendRequest disabled */)));
module_system->RegisterNativeHandler(
"activityLogger", std::unique_ptr<NativeHandler>(
new LocalAPIActivityLogger(context)));
new LocalAPIActivityLogger(script_context)));
}

void JavascriptEnvironment::OnMessageLoopCreated() {
Expand Down
16 changes: 13 additions & 3 deletions atom/browser/javascript_environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "base/macros.h"
#include "brave/common/extensions/asar_source_map.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/renderer/script_context.h"
#include "gin/modules/module_runner_delegate.h"
#include "gin/public/context_holder.h"
Expand Down Expand Up @@ -42,7 +43,7 @@ namespace atom {

class LocalRequestSenderMessageFilter;

class JavascriptEnvironment {
class JavascriptEnvironment : public extensions::ExtensionRegistryObserver {
public:
static JavascriptEnvironment* Get();

Expand All @@ -52,6 +53,8 @@ class JavascriptEnvironment {
void OnMessageLoopCreated();
void OnMessageLoopDestroying();

void SetExtension(const extensions::Extension* extension);

v8::Isolate* isolate() const { return isolate_; }
extensions::ScriptContext* script_context() {
return script_context_.get();
Expand Down Expand Up @@ -88,6 +91,14 @@ class JavascriptEnvironment {
const base::ListValue& event_args,
const base::DictionaryValue& filtering_info);

void DestroyScriptContext();
extensions::ScriptContext* CreateScriptContext(
const extensions::Extension* extension);
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const extensions::Extension* extension,
extensions::UnloadedExtensionInfo::Reason reason) override;


bool initialized_;
std::unique_ptr<gin::IsolateHolder> isolate_holder_;
v8::Isolate* isolate_;
Expand All @@ -101,12 +112,11 @@ class JavascriptEnvironment {
std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher_;
std::unique_ptr<extensions::ExtensionBindingsSystem> bindings_system_;
std::unique_ptr<extensions::V8SchemaRegistry> v8_schema_registry_;
int worker_thread_id_;

std::unique_ptr<extensions::ScriptContext> script_context_;
std::unique_ptr<content::BlinkPlatformImpl> blink_platform_impl_;

const extensions::Extension* extension_;

DISALLOW_COPY_AND_ASSIGN(JavascriptEnvironment);
};

Expand Down
Loading

0 comments on commit 7b0352f

Please sign in to comment.