summaryrefslogtreecommitdiffstats
path: root/mojo/public
diff options
context:
space:
mode:
authorabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-25 02:19:34 +0000
committerabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-25 02:19:34 +0000
commit0d72f004efa9898b428b9b289a8d63d2427e2828 (patch)
treef749189620fba034c4e09aa5e64c537eba778e61 /mojo/public
parent6a36eff422ce0dfaf8bcb75585863c38817d219d (diff)
downloadchromium_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.js1
-rw-r--r--mojo/public/bindings/js/connector.js98
-rw-r--r--mojo/public/bindings/js/support.cc86
-rw-r--r--mojo/public/bindings/js/support.h22
-rw-r--r--mojo/public/bindings/js/waiting_callback.cc72
-rw-r--r--mojo/public/bindings/js/waiting_callback.h56
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_