diff options
author | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-25 02:19:34 +0000 |
---|---|---|
committer | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-25 02:19:34 +0000 |
commit | 0d72f004efa9898b428b9b289a8d63d2427e2828 (patch) | |
tree | f749189620fba034c4e09aa5e64c537eba778e61 /mojo/public | |
parent | 6a36eff422ce0dfaf8bcb75585863c38817d219d (diff) | |
download | chromium_src-0d72f004efa9898b428b9b289a8d63d2427e2828.zip chromium_src-0d72f004efa9898b428b9b289a8d63d2427e2828.tar.gz chromium_src-0d72f004efa9898b428b9b289a8d63d2427e2828.tar.bz2 |
[Mojo] Almost connect mojo_js with hello_world_service
This CL connects mojo_js with hello_world_service. After this
CL, the JavaScript and C++ implementations have reached
parity.
BUG=317398
Review URL: https://codereview.chromium.org/82953004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237018 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public')
-rw-r--r-- | mojo/public/bindings/js/codec.js | 1 | ||||
-rw-r--r-- | mojo/public/bindings/js/connector.js | 98 | ||||
-rw-r--r-- | mojo/public/bindings/js/support.cc | 86 | ||||
-rw-r--r-- | mojo/public/bindings/js/support.h | 22 | ||||
-rw-r--r-- | mojo/public/bindings/js/waiting_callback.cc | 72 | ||||
-rw-r--r-- | mojo/public/bindings/js/waiting_callback.h | 56 |
6 files changed, 335 insertions, 0 deletions
diff --git a/mojo/public/bindings/js/codec.js b/mojo/public/bindings/js/codec.js index 2b3f86c..0245de4 100644 --- a/mojo/public/bindings/js/codec.js +++ b/mojo/public/bindings/js/codec.js @@ -428,6 +428,7 @@ define(function() { var exports = {}; exports.align = align; + exports.Message = Message; exports.MessageBuilder = MessageBuilder; exports.MessageReader = MessageReader; exports.kArrayHeaderSize = kArrayHeaderSize; diff --git a/mojo/public/bindings/js/connector.js b/mojo/public/bindings/js/connector.js new file mode 100644 index 0000000..c9d0566 --- /dev/null +++ b/mojo/public/bindings/js/connector.js @@ -0,0 +1,98 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +define([ + "mojo/public/bindings/js/codec", + "mojo/public/bindings/js/core", + "mojo/public/bindings/js/support", +], function(codec, core, support) { + + function Connector(handle) { + this.handle_ = handle; + this.error_ = false; + this.incomingReceiver_ = null; + this.readWaitCookie_ = null; + } + + Connector.prototype.close = function() { + if (this.readWaitCookie_) { + support.cancelWait(this.readWaitCookie_); + this.readWaitCookie_ = null; + } + if (this.handle_ != core.kInvalidHandle) { + core.close(this.handle_); + this.handle_ = core.kInvalidHandle; + } + }; + + Connector.prototype.accept = function(message) { + if (this.error_) + return false; + this.write_(message); + return !this.error_; + }; + + Connector.prototype.setIncomingReceiver = function(receiver) { + this.incomingReceiver_ = receiver; + if (this.incomingReceiver_) + this.waitToReadMore_(); + }; + + Connector.prototype.write_ = function(message) { + var result = core.writeMessage(this.handle_, + message.memory, + message.handles, + core.WRITE_MESSAGE_FLAG_NONE); + if (result != core.RESULT_OK) { + this.error_ = true + return; + } + // The handles were successfully transferred, so we don't own them anymore. + message.handles = []; + }; + + Connector.prototype.waitToReadMore_ = function() { + this.readWaitCookie_ = support.asyncWait(this.handle_, + core.WAIT_FLAG_READABLE, + this.readMore_.bind(this)); + }; + + Connector.prototype.readMore_ = function(result) { + for (;;) { + var read = core.readMessage(this.handle_, + core.READ_MESSAGE_FLAG_NONE); + if (read.result == core.RESULT_NOT_FOUND) { + this.waitToReadMore_(); + return; + } + if (read.result != core.RESULT_OK) { + this.error_ = true; + return; + } + // TODO(abarth): Should core.readMessage return a Uint8Array? + var memory = new Uint8Array(read.buffer); + var message = new codec.Message(memory, read.handles); + this.incomingReceiver_.accept(message); + } + }; + + function Connection(handle, localFactory, remoteFactory) { + this.connector_ = new Connector(handle); + this.local = new localFactory(); + this.remote = new remoteFactory(this.connector_); + + this.connector_.setIncomingReceiver(this.local); + } + + Connection.prototype.close = function() { + this.connector_.close(); + this.connector_ = null; + this.local = null; + this.remote = null; + }; + + var exports = {}; + exports.Connection = Connection; + return exports; +}); diff --git a/mojo/public/bindings/js/support.cc b/mojo/public/bindings/js/support.cc new file mode 100644 index 0000000..da279f3 --- /dev/null +++ b/mojo/public/bindings/js/support.cc @@ -0,0 +1,86 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/bindings/js/support.h" + +#include "gin/arguments.h" +#include "gin/converter.h" +#include "gin/per_isolate_data.h" +#include "gin/public/wrapper_info.h" +#include "gin/wrappable.h" +#include "mojo/public/bindings/js/handle.h" +#include "mojo/public/bindings/js/waiting_callback.h" +#include "mojo/public/bindings/lib/bindings_support.h" + +namespace mojo { +namespace js { + +namespace { + +void AsyncWait(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + mojo::Handle handle; + MojoWaitFlags flags = MOJO_WAIT_FLAG_NONE; + v8::Handle<v8::Function> callback; + + if (!args.GetNext(&handle) || + !args.GetNext(&flags) || + !args.GetNext(&callback)) + return args.ThrowError(); + + scoped_refptr<WaitingCallback> waiting_callback = + WaitingCallback::Create(args.isolate(), callback); + + BindingsSupport::AsyncWaitID wait_id = BindingsSupport::Get()->AsyncWait( + handle, flags, waiting_callback.get()); + + waiting_callback->set_wait_id(wait_id); + + args.Return(waiting_callback.get()); +} + +void CancelWait(const v8::FunctionCallbackInfo<v8::Value>& info) { + gin::Arguments args(info); + + WaitingCallback* waiting_callback = NULL; + + if (!args.GetNext(&waiting_callback)) + return args.ThrowError(); + + if (!waiting_callback->wait_id()) + return; + BindingsSupport::Get()->CancelWait(waiting_callback->wait_id()); + waiting_callback->set_wait_id(NULL); +} + +gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; + +} // namespace + +const char Support::kModuleName[] = "mojo/public/bindings/js/support"; + +v8::Local<v8::ObjectTemplate> Support::GetTemplate(v8::Isolate* isolate) { + gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); + v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( + &g_wrapper_info); + + if (templ.IsEmpty()) { + WaitingCallback::EnsureRegistered(isolate); + + templ = v8::ObjectTemplate::New(); + + templ->Set(gin::StringToSymbol(isolate, "asyncWait"), + v8::FunctionTemplate::New(AsyncWait)); + templ->Set(gin::StringToSymbol(isolate, "cancelWait"), + v8::FunctionTemplate::New(CancelWait)); + + data->SetObjectTemplate(&g_wrapper_info, templ); + } + + return templ; +} + +} // namespace js +} // namespace mojo diff --git a/mojo/public/bindings/js/support.h b/mojo/public/bindings/js/support.h new file mode 100644 index 0000000..e5736592 --- /dev/null +++ b/mojo/public/bindings/js/support.h @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_BINDINGS_JS_SUPPORT_H_ +#define MOJO_PUBLIC_BINDINGS_JS_SUPPORT_H_ + +#include "v8/include/v8.h" + +namespace mojo { +namespace js { + +class Support { + public: + static const char kModuleName[]; + static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate); +}; + +} // namespace js +} // namespace mojo + +#endif // MOJO_PUBLIC_BINDINGS_JS_SUPPORT_H_ diff --git a/mojo/public/bindings/js/waiting_callback.cc b/mojo/public/bindings/js/waiting_callback.cc new file mode 100644 index 0000000..d2613fa --- /dev/null +++ b/mojo/public/bindings/js/waiting_callback.cc @@ -0,0 +1,72 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/bindings/js/waiting_callback.h" + +#include "gin/per_context_data.h" +#include "gin/per_isolate_data.h" + +namespace mojo { +namespace js { + +namespace { + +v8::Handle<v8::String> GetHiddenPropertyName(v8::Isolate* isolate) { + return gin::StringToSymbol(isolate, "::mojo::js::WaitingCallback"); +} + +} // namespace + +WaitingCallback::WaitingCallback(v8::Isolate* isolate, + v8::Handle<v8::Function> callback) + : wait_id_() { + v8::Handle<v8::Context> context = isolate->GetCurrentContext(); + runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); + GetWrapper(isolate)->SetHiddenValue(GetHiddenPropertyName(isolate), callback); +} + +WaitingCallback::~WaitingCallback() { + DCHECK(!wait_id_) << "Waiting callback was destroyed before being cancelled."; +} + +scoped_refptr<WaitingCallback> WaitingCallback::Create( + v8::Isolate* isolate, v8::Handle<v8::Function> callback) { + return make_scoped_refptr(new WaitingCallback(isolate, callback)); +} + +gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin }; + +gin::WrapperInfo* WaitingCallback::GetWrapperInfo() { + return &kWrapperInfo; +} + +void WaitingCallback::EnsureRegistered(v8::Isolate* isolate) { + gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); + if (!data->GetObjectTemplate(&kWrapperInfo).IsEmpty()) + return; + v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); + templ->SetInternalFieldCount(gin::kNumberOfInternalFields); + data->SetObjectTemplate(&kWrapperInfo, templ); +} + +void WaitingCallback::OnHandleReady(MojoResult result) { + wait_id_ = NULL; + + if (!runner_) + return; + + gin::Runner::Scope scope(runner_.get()); + v8::Isolate* isolate = runner_->isolate(); + + v8::Handle<v8::Value> hidden_value = + GetWrapper(isolate)->GetHiddenValue(GetHiddenPropertyName(isolate)); + v8::Handle<v8::Function> callback; + CHECK(gin::ConvertFromV8(hidden_value, &callback)); + + v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, result) }; + runner_->Call(callback, runner_->global(), 1, args); +} + +} // namespace js +} // namespace mojo diff --git a/mojo/public/bindings/js/waiting_callback.h b/mojo/public/bindings/js/waiting_callback.h new file mode 100644 index 0000000..4a5e3e4 --- /dev/null +++ b/mojo/public/bindings/js/waiting_callback.h @@ -0,0 +1,56 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_BINDINGS_JS_WAITING_CALLBACK_H_ +#define MOJO_PUBLIC_BINDINGS_JS_WAITING_CALLBACK_H_ + +#include "gin/runner.h" +#include "gin/wrappable.h" +#include "mojo/public/bindings/lib/bindings_support.h" + +namespace mojo { +namespace js { + +class WaitingCallback : public gin::Wrappable, + public BindingsSupport::AsyncWaitCallback { + public: + static scoped_refptr<WaitingCallback> Create( + v8::Isolate* isolate, v8::Handle<v8::Function> callback); + + static gin::WrapperInfo kWrapperInfo; + virtual gin::WrapperInfo* GetWrapperInfo() OVERRIDE; + static void EnsureRegistered(v8::Isolate* isolate); + + BindingsSupport::AsyncWaitID wait_id() const { + return wait_id_; + } + + void set_wait_id(BindingsSupport::AsyncWaitID wait_id) { + wait_id_ = wait_id; + } + + private: + WaitingCallback(v8::Isolate* isolate, v8::Handle<v8::Function> callback); + virtual ~WaitingCallback(); + + virtual void OnHandleReady(MojoResult result) OVERRIDE; + + base::WeakPtr<gin::Runner> runner_; + BindingsSupport::AsyncWaitID wait_id_; + + DISALLOW_COPY_AND_ASSIGN(WaitingCallback); +}; + +} // namespace js +} // namespace mojo + +namespace gin { + +template<> +struct Converter<mojo::js::WaitingCallback*> + : public WrappableConverter<mojo::js::WaitingCallback> {}; + +} // namespace gin + +#endif // MOJO_PUBLIC_BINDINGS_JS_WAITING_CALLBACK_H_ |