diff options
Diffstat (limited to 'mojo/edk/js')
28 files changed, 0 insertions, 2762 deletions
diff --git a/mojo/edk/js/BUILD.gn b/mojo/edk/js/BUILD.gn deleted file mode 100644 index 9a066d3..0000000 --- a/mojo/edk/js/BUILD.gn +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2014 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. - -import("../mojo_edk.gni") - -mojo_edk_source_set("js") { - sources = [ - "core.cc", - "core.h", - "drain_data.cc", - "drain_data.h", - "handle.cc", - "handle.h", - "handle_close_observer.h", - "mojo_runner_delegate.cc", - "mojo_runner_delegate.h", - "support.cc", - "support.h", - "threading.cc", - "threading.h", - "waiting_callback.cc", - "waiting_callback.h", - ] - - public_deps = [ - "//base", - "//gin", - "//v8", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/environment", - "mojo/public/cpp/system", - ] -} - -mojo_edk_source_set("js_unittests") { - testonly = true - sources = [ - "handle_unittest.cc", - ] - - deps = [ - "//testing/gtest", - ] - - mojo_edk_deps = [ - "mojo/edk/js", - "mojo/edk/test:test_support", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/system", - ] -} diff --git a/mojo/edk/js/DEPS b/mojo/edk/js/DEPS deleted file mode 100644 index c350edf..0000000 --- a/mojo/edk/js/DEPS +++ /dev/null @@ -1,5 +0,0 @@ -include_rules = [ - "+base", - "+gin", - "+v8", -] diff --git a/mojo/edk/js/core.cc b/mojo/edk/js/core.cc deleted file mode 100644 index c06977d..0000000 --- a/mojo/edk/js/core.cc +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright 2014 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/edk/js/core.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "gin/arguments.h" -#include "gin/array_buffer.h" -#include "gin/converter.h" -#include "gin/dictionary.h" -#include "gin/function_template.h" -#include "gin/handle.h" -#include "gin/object_template_builder.h" -#include "gin/per_isolate_data.h" -#include "gin/public/wrapper_info.h" -#include "gin/wrappable.h" -#include "mojo/edk/js/drain_data.h" -#include "mojo/edk/js/handle.h" - -namespace mojo { -namespace js { - -namespace { - -MojoResult CloseHandle(gin::Handle<HandleWrapper> handle) { - if (!handle->get().is_valid()) - return MOJO_RESULT_INVALID_ARGUMENT; - handle->Close(); - return MOJO_RESULT_OK; -} - -gin::Dictionary WaitHandle(const gin::Arguments& args, - mojo::Handle handle, - MojoHandleSignals signals, - MojoDeadline deadline) { - v8::Isolate* isolate = args.isolate(); - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate); - - MojoHandleSignalsState signals_state; - MojoResult result = mojo::Wait(handle, signals, deadline, &signals_state); - dictionary.Set("result", result); - - mojo::WaitManyResult wmv(result, 0); - if (!wmv.AreSignalsStatesValid()) { - dictionary.Set("signalsState", v8::Null(isolate).As<v8::Value>()); - } else { - gin::Dictionary signalsStateDict = gin::Dictionary::CreateEmpty(isolate); - signalsStateDict.Set("satisfiedSignals", signals_state.satisfied_signals); - signalsStateDict.Set("satisfiableSignals", - signals_state.satisfiable_signals); - dictionary.Set("signalsState", signalsStateDict); - } - - return dictionary; -} - -gin::Dictionary WaitMany(const gin::Arguments& args, - const std::vector<mojo::Handle>& handles, - const std::vector<MojoHandleSignals>& signals, - MojoDeadline deadline) { - v8::Isolate* isolate = args.isolate(); - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate); - - std::vector<MojoHandleSignalsState> signals_states(signals.size()); - mojo::WaitManyResult wmv = - mojo::WaitMany(handles, signals, deadline, &signals_states); - dictionary.Set("result", wmv.result); - if (wmv.IsIndexValid()) { - dictionary.Set("index", wmv.index); - } else { - dictionary.Set("index", v8::Null(isolate).As<v8::Value>()); - } - if (wmv.AreSignalsStatesValid()) { - std::vector<gin::Dictionary> vec; - for (size_t i = 0; i < handles.size(); ++i) { - gin::Dictionary signalsStateDict = gin::Dictionary::CreateEmpty(isolate); - signalsStateDict.Set("satisfiedSignals", - signals_states[i].satisfied_signals); - signalsStateDict.Set("satisfiableSignals", - signals_states[i].satisfiable_signals); - vec.push_back(signalsStateDict); - } - dictionary.Set("signalsState", vec); - } else { - dictionary.Set("signalsState", v8::Null(isolate).As<v8::Value>()); - } - - return dictionary; -} - -gin::Dictionary CreateMessagePipe(const gin::Arguments& args) { - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT); - - MojoHandle handle0 = MOJO_HANDLE_INVALID; - MojoHandle handle1 = MOJO_HANDLE_INVALID; - MojoResult result = MOJO_RESULT_OK; - - v8::Handle<v8::Value> options_value = args.PeekNext(); - if (options_value.IsEmpty() || options_value->IsNull() || - options_value->IsUndefined()) { - result = MojoCreateMessagePipe(NULL, &handle0, &handle1); - } else if (options_value->IsObject()) { - gin::Dictionary options_dict(args.isolate(), options_value->ToObject()); - MojoCreateMessagePipeOptions options; - // For future struct_size, we can probably infer that from the presence of - // properties in options_dict. For now, it's always 8. - options.struct_size = 8; - // Ideally these would be optional. But the interface makes it hard to - // typecheck them then. - if (!options_dict.Get("flags", &options.flags)) { - return dictionary; - } - - result = MojoCreateMessagePipe(&options, &handle0, &handle1); - } else { - return dictionary; - } - - CHECK_EQ(MOJO_RESULT_OK, result); - - dictionary.Set("result", result); - dictionary.Set("handle0", mojo::Handle(handle0)); - dictionary.Set("handle1", mojo::Handle(handle1)); - return dictionary; -} - -MojoResult WriteMessage( - mojo::Handle handle, - const gin::ArrayBufferView& buffer, - const std::vector<gin::Handle<HandleWrapper> >& handles, - MojoWriteMessageFlags flags) { - std::vector<MojoHandle> raw_handles(handles.size()); - for (size_t i = 0; i < handles.size(); ++i) - raw_handles[i] = handles[i]->get().value(); - MojoResult rv = MojoWriteMessage(handle.value(), - buffer.bytes(), - static_cast<uint32_t>(buffer.num_bytes()), - raw_handles.empty() ? NULL : &raw_handles[0], - static_cast<uint32_t>(raw_handles.size()), - flags); - // MojoWriteMessage takes ownership of the handles upon success, so - // release them here. - if (rv == MOJO_RESULT_OK) { - for (size_t i = 0; i < handles.size(); ++i) - ignore_result(handles[i]->release()); - } - return rv; -} - -gin::Dictionary ReadMessage(const gin::Arguments& args, - mojo::Handle handle, - MojoReadMessageFlags flags) { - uint32_t num_bytes = 0; - uint32_t num_handles = 0; - MojoResult result = MojoReadMessage( - handle.value(), NULL, &num_bytes, NULL, &num_handles, flags); - if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) { - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", result); - return dictionary; - } - - v8::Handle<v8::ArrayBuffer> array_buffer = - v8::ArrayBuffer::New(args.isolate(), num_bytes); - std::vector<mojo::Handle> handles(num_handles); - - gin::ArrayBuffer buffer; - ConvertFromV8(args.isolate(), array_buffer, &buffer); - CHECK(buffer.num_bytes() == num_bytes); - - result = MojoReadMessage(handle.value(), - buffer.bytes(), - &num_bytes, - handles.empty() ? NULL : - reinterpret_cast<MojoHandle*>(&handles[0]), - &num_handles, - flags); - - CHECK(buffer.num_bytes() == num_bytes); - CHECK(handles.size() == num_handles); - - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", result); - dictionary.Set("buffer", array_buffer); - dictionary.Set("handles", handles); - return dictionary; -} - -gin::Dictionary CreateDataPipe(const gin::Arguments& args) { - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT); - - MojoHandle producer_handle = MOJO_HANDLE_INVALID; - MojoHandle consumer_handle = MOJO_HANDLE_INVALID; - MojoResult result = MOJO_RESULT_OK; - - v8::Handle<v8::Value> options_value = args.PeekNext(); - if (options_value.IsEmpty() || options_value->IsNull() || - options_value->IsUndefined()) { - result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle); - } else if (options_value->IsObject()) { - gin::Dictionary options_dict(args.isolate(), options_value->ToObject()); - MojoCreateDataPipeOptions options; - // For future struct_size, we can probably infer that from the presence of - // properties in options_dict. For now, it's always 16. - options.struct_size = 16; - // Ideally these would be optional. But the interface makes it hard to - // typecheck them then. - if (!options_dict.Get("flags", &options.flags) || - !options_dict.Get("elementNumBytes", &options.element_num_bytes) || - !options_dict.Get("capacityNumBytes", &options.capacity_num_bytes)) { - return dictionary; - } - - result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle); - } else { - return dictionary; - } - - CHECK_EQ(MOJO_RESULT_OK, result); - - dictionary.Set("result", result); - dictionary.Set("producerHandle", mojo::Handle(producer_handle)); - dictionary.Set("consumerHandle", mojo::Handle(consumer_handle)); - return dictionary; -} - -gin::Dictionary WriteData(const gin::Arguments& args, - mojo::Handle handle, - const gin::ArrayBufferView& buffer, - MojoWriteDataFlags flags) { - uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes()); - MojoResult result = - MojoWriteData(handle.value(), buffer.bytes(), &num_bytes, flags); - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", result); - dictionary.Set("numBytes", num_bytes); - return dictionary; -} - -gin::Dictionary ReadData(const gin::Arguments& args, - mojo::Handle handle, - MojoReadDataFlags flags) { - uint32_t num_bytes = 0; - MojoResult result = MojoReadData( - handle.value(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY); - if (result != MOJO_RESULT_OK) { - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", result); - return dictionary; - } - - v8::Handle<v8::ArrayBuffer> array_buffer = - v8::ArrayBuffer::New(args.isolate(), num_bytes); - gin::ArrayBuffer buffer; - ConvertFromV8(args.isolate(), array_buffer, &buffer); - CHECK_EQ(num_bytes, buffer.num_bytes()); - - result = MojoReadData(handle.value(), buffer.bytes(), &num_bytes, flags); - CHECK_EQ(num_bytes, buffer.num_bytes()); - - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate()); - dictionary.Set("result", result); - dictionary.Set("buffer", array_buffer); - return dictionary; -} - -// Asynchronously read all of the data available for the specified data pipe -// consumer handle until the remote handle is closed or an error occurs. A -// Promise is returned whose settled value is an object like this: -// {result: core.RESULT_OK, buffer: dataArrayBuffer}. If the read failed, -// then the Promise is rejected, the result will be the actual error code, -// and the buffer will contain whatever was read before the error occurred. -// The drainData data pipe handle argument is closed automatically. - -v8::Handle<v8::Value> DoDrainData(gin::Arguments* args, - gin::Handle<HandleWrapper> handle) { - return (new DrainData(args->isolate(), handle->release()))->GetPromise(); -} - -bool IsHandle(gin::Arguments* args, v8::Handle<v8::Value> val) { - gin::Handle<mojo::js::HandleWrapper> ignore_handle; - return gin::Converter<gin::Handle<mojo::js::HandleWrapper>>::FromV8( - args->isolate(), val, &ignore_handle); -} - - -gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; - -} // namespace - -const char Core::kModuleName[] = "mojo/public/js/core"; - -v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) { - gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); - v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( - &g_wrapper_info); - - if (templ.IsEmpty()) { - templ = - gin::ObjectTemplateBuilder(isolate) - // TODO(mpcomplete): Should these just be methods on the JS Handle - // object? - .SetMethod("close", CloseHandle) - .SetMethod("wait", WaitHandle) - .SetMethod("waitMany", WaitMany) - .SetMethod("createMessagePipe", CreateMessagePipe) - .SetMethod("writeMessage", WriteMessage) - .SetMethod("readMessage", ReadMessage) - .SetMethod("createDataPipe", CreateDataPipe) - .SetMethod("writeData", WriteData) - .SetMethod("readData", ReadData) - .SetMethod("drainData", DoDrainData) - .SetMethod("isHandle", IsHandle) - - .SetValue("RESULT_OK", MOJO_RESULT_OK) - .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED) - .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN) - .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT) - .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED) - .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND) - .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS) - .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED) - .SetValue("RESULT_RESOURCE_EXHAUSTED", - MOJO_RESULT_RESOURCE_EXHAUSTED) - .SetValue("RESULT_FAILED_PRECONDITION", - MOJO_RESULT_FAILED_PRECONDITION) - .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED) - .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE) - .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED) - .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL) - .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE) - .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS) - .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY) - .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT) - - .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE) - - .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE) - .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE) - .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE) - .SetValue("HANDLE_SIGNAL_PEER_CLOSED", - MOJO_HANDLE_SIGNAL_PEER_CLOSED) - - .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE", - MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE) - - .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE) - - .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE) - .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD", - MOJO_READ_MESSAGE_FLAG_MAY_DISCARD) - - .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE", - MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE) - .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD", - MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD) - - .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE) - .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE", - MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) - - .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE) - .SetValue("READ_DATA_FLAG_ALL_OR_NONE", - MOJO_READ_DATA_FLAG_ALL_OR_NONE) - .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD) - .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY) - .SetValue("READ_DATA_FLAG_PEEK", MOJO_READ_DATA_FLAG_PEEK) - .Build(); - - data->SetObjectTemplate(&g_wrapper_info, templ); - } - - return templ->NewInstance(); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/core.h b/mojo/edk/js/core.h deleted file mode 100644 index 445fb00..0000000 --- a/mojo/edk/js/core.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 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_EDK_JS_CORE_H_ -#define MOJO_EDK_JS_CORE_H_ - -#include "v8/include/v8.h" - -namespace mojo { -namespace js { - -class Core { - public: - static const char kModuleName[]; - static v8::Local<v8::Value> GetModule(v8::Isolate* isolate); -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_CORE_H_ diff --git a/mojo/edk/js/drain_data.cc b/mojo/edk/js/drain_data.cc deleted file mode 100644 index 0667c64..0000000 --- a/mojo/edk/js/drain_data.cc +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2014 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/edk/js/drain_data.h" - -#include "gin/array_buffer.h" -#include "gin/converter.h" -#include "gin/dictionary.h" -#include "gin/per_context_data.h" -#include "gin/per_isolate_data.h" -#include "mojo/public/cpp/environment/environment.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -namespace js { - -DrainData::DrainData(v8::Isolate* isolate, mojo::Handle handle) - : isolate_(isolate), - handle_(DataPipeConsumerHandle(handle.value())), - wait_id_(0) { - - v8::Handle<v8::Context> context(isolate_->GetCurrentContext()); - runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); - - WaitForData(); -} - -v8::Handle<v8::Value> DrainData::GetPromise() { - CHECK(resolver_.IsEmpty()); - v8::Handle<v8::Promise::Resolver> resolver( - v8::Promise::Resolver::New(isolate_)); - resolver_.Reset(isolate_, resolver); - return resolver->GetPromise(); -} - -DrainData::~DrainData() { - if (wait_id_) - Environment::GetDefaultAsyncWaiter()->CancelWait(wait_id_); - resolver_.Reset(); -} - -void DrainData::WaitForData() { - wait_id_ = Environment::GetDefaultAsyncWaiter()->AsyncWait( - handle_.get().value(), - MOJO_HANDLE_SIGNAL_READABLE, - MOJO_DEADLINE_INDEFINITE, - &DrainData::WaitCompleted, - this); -} - -void DrainData::DataReady(MojoResult result) { - wait_id_ = 0; - if (result != MOJO_RESULT_OK) { - DeliverData(result); - return; - } - while (result == MOJO_RESULT_OK) { - result = ReadData(); - if (result == MOJO_RESULT_SHOULD_WAIT) - WaitForData(); - else if (result != MOJO_RESULT_OK) - DeliverData(result); - } -} - -MojoResult DrainData::ReadData() { - const void* buffer; - uint32_t num_bytes = 0; - MojoResult result = BeginReadDataRaw( - handle_.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); - if (result != MOJO_RESULT_OK) - return result; - const char* p = static_cast<const char*>(buffer); - DataBuffer* data_buffer = new DataBuffer(p, p + num_bytes); - data_buffers_.push_back(data_buffer); - return EndReadDataRaw(handle_.get(), num_bytes); -} - -void DrainData::DeliverData(MojoResult result) { - if (!runner_) { - delete this; - return; - } - - size_t total_bytes = 0; - for (unsigned i = 0; i < data_buffers_.size(); i++) - total_bytes += data_buffers_[i]->size(); - - // Create a total_bytes length ArrayBuffer return value. - gin::Runner::Scope scope(runner_.get()); - v8::Handle<v8::ArrayBuffer> array_buffer = - v8::ArrayBuffer::New(isolate_, total_bytes); - gin::ArrayBuffer buffer; - ConvertFromV8(isolate_, array_buffer, &buffer); - CHECK_EQ(total_bytes, buffer.num_bytes()); - - // Copy the data_buffers into the ArrayBuffer. - char* array_buffer_ptr = static_cast<char*>(buffer.bytes()); - size_t offset = 0; - for (size_t i = 0; i < data_buffers_.size(); i++) { - size_t num_bytes = data_buffers_[i]->size(); - if (num_bytes == 0) - continue; - const char* data_buffer_ptr = &((*data_buffers_[i])[0]); - memcpy(array_buffer_ptr + offset, data_buffer_ptr, num_bytes); - offset += num_bytes; - } - - // The "settled" value of the promise always includes all of the data - // that was read before either an error occurred or the remote pipe handle - // was closed. The latter is indicated by MOJO_RESULT_FAILED_PRECONDITION. - - v8::Handle<v8::Promise::Resolver> resolver( - v8::Local<v8::Promise::Resolver>::New(isolate_, resolver_)); - - gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(isolate_); - dictionary.Set("result", result); - dictionary.Set("buffer", array_buffer); - v8::Handle<v8::Value> settled_value(ConvertToV8(isolate_, dictionary)); - - if (result == MOJO_RESULT_FAILED_PRECONDITION) - resolver->Resolve(settled_value); - else - resolver->Reject(settled_value); - - delete this; -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/drain_data.h b/mojo/edk/js/drain_data.h deleted file mode 100644 index 48f1de2..0000000 --- a/mojo/edk/js/drain_data.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 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_EDK_JS_DRAIN_DATA_H_ -#define MOJO_EDK_JS_DRAIN_DATA_H_ - -#include "base/memory/scoped_vector.h" -#include "gin/runner.h" -#include "mojo/public/c/environment/async_waiter.h" -#include "mojo/public/cpp/system/core.h" -#include "v8/include/v8.h" - -namespace mojo { -namespace js { - -// This class is the implementation of the Mojo JavaScript core module's -// drainData() method. It is not intended to be used directly. The caller -// allocates a DrainData on the heap and returns GetPromise() to JS. The -// implementation deletes itself after reading as much data as possible -// and rejecting or resolving the Promise. - -class DrainData { - public: - // Starts waiting for data on the specified data pipe consumer handle. - // See WaitForData(). The constructor does not block. - DrainData(v8::Isolate* isolate, mojo::Handle handle); - - // Returns a Promise that will be settled when no more data can be read. - // Should be called just once on a newly allocated DrainData object. - v8::Handle<v8::Value> GetPromise(); - - private: - ~DrainData(); - - // Registers an "async waiter" that calls DataReady() via WaitCompleted(). - void WaitForData(); - static void WaitCompleted(void* self, MojoResult result) { - static_cast<DrainData*>(self)->DataReady(result); - } - - // Use ReadData() to read whatever is availble now on handle_ and save - // it in data_buffers_. - void DataReady(MojoResult result); - MojoResult ReadData(); - - // When the remote data pipe handle is closed, or an error occurs, deliver - // all of the buffered data to the JS Promise and then delete this. - void DeliverData(MojoResult result); - - typedef std::vector<char> DataBuffer; - - v8::Isolate* isolate_; - ScopedDataPipeConsumerHandle handle_; - MojoAsyncWaitID wait_id_; - base::WeakPtr<gin::Runner> runner_; - v8::UniquePersistent<v8::Promise::Resolver> resolver_; - ScopedVector<DataBuffer> data_buffers_; -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_DRAIN_DATA_H_ diff --git a/mojo/edk/js/handle.cc b/mojo/edk/js/handle.cc deleted file mode 100644 index de8f338..0000000 --- a/mojo/edk/js/handle.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2014 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/edk/js/handle.h" - -#include "mojo/edk/js/handle_close_observer.h" - -namespace mojo { -namespace js { - -gin::WrapperInfo HandleWrapper::kWrapperInfo = { gin::kEmbedderNativeGin }; - -HandleWrapper::HandleWrapper(MojoHandle handle) - : handle_(mojo::Handle(handle)) { -} - -HandleWrapper::~HandleWrapper() { - NotifyCloseObservers(); -} - -void HandleWrapper::Close() { - NotifyCloseObservers(); - handle_.reset(); -} - -void HandleWrapper::AddCloseObserver(HandleCloseObserver* observer) { - close_observers_.AddObserver(observer); -} - -void HandleWrapper::RemoveCloseObserver(HandleCloseObserver* observer) { - close_observers_.RemoveObserver(observer); -} - -void HandleWrapper::NotifyCloseObservers() { - if (!handle_.is_valid()) - return; - - FOR_EACH_OBSERVER(HandleCloseObserver, close_observers_, OnWillCloseHandle()); -} - -} // namespace js -} // namespace mojo - -namespace gin { - -v8::Handle<v8::Value> Converter<mojo::Handle>::ToV8(v8::Isolate* isolate, - const mojo::Handle& val) { - if (!val.is_valid()) - return v8::Null(isolate); - return mojo::js::HandleWrapper::Create(isolate, val.value()).ToV8(); -} - -bool Converter<mojo::Handle>::FromV8(v8::Isolate* isolate, - v8::Handle<v8::Value> val, - mojo::Handle* out) { - if (val->IsNull()) { - *out = mojo::Handle(); - return true; - } - - gin::Handle<mojo::js::HandleWrapper> handle; - if (!Converter<gin::Handle<mojo::js::HandleWrapper> >::FromV8( - isolate, val, &handle)) - return false; - - *out = handle->get(); - return true; -} - -v8::Handle<v8::Value> Converter<mojo::MessagePipeHandle>::ToV8( - v8::Isolate* isolate, mojo::MessagePipeHandle val) { - return Converter<mojo::Handle>::ToV8(isolate, val); -} - -bool Converter<mojo::MessagePipeHandle>::FromV8(v8::Isolate* isolate, - v8::Handle<v8::Value> val, - mojo::MessagePipeHandle* out) { - return Converter<mojo::Handle>::FromV8(isolate, val, out); -} - - -} // namespace gin diff --git a/mojo/edk/js/handle.h b/mojo/edk/js/handle.h deleted file mode 100644 index 200b322..0000000 --- a/mojo/edk/js/handle.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2014 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_EDK_JS_HANDLE_H_ -#define MOJO_EDK_JS_HANDLE_H_ - -#include "base/observer_list.h" -#include "gin/converter.h" -#include "gin/handle.h" -#include "gin/wrappable.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -namespace js { -class HandleCloseObserver; - -// Wrapper for mojo Handles exposed to JavaScript. This ensures the Handle -// is Closed when its JS object is garbage collected. -class HandleWrapper : public gin::Wrappable<HandleWrapper> { - public: - static gin::WrapperInfo kWrapperInfo; - - static gin::Handle<HandleWrapper> Create(v8::Isolate* isolate, - MojoHandle handle) { - return gin::CreateHandle(isolate, new HandleWrapper(handle)); - } - - mojo::Handle get() const { return handle_.get(); } - mojo::Handle release() { return handle_.release(); } - void Close(); - - void AddCloseObserver(HandleCloseObserver* observer); - void RemoveCloseObserver(HandleCloseObserver* observer); - - protected: - HandleWrapper(MojoHandle handle); - ~HandleWrapper() override; - void NotifyCloseObservers(); - - mojo::ScopedHandle handle_; - ObserverList<HandleCloseObserver> close_observers_; -}; - -} // namespace js -} // namespace mojo - -namespace gin { - -// Note: It's important to use this converter rather than the one for -// MojoHandle, since that will do a simple int32 conversion. It's unfortunate -// there's no way to prevent against accidental use. -// TODO(mpcomplete): define converters for all Handle subtypes. -template<> -struct Converter<mojo::Handle> { - static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, - const mojo::Handle& val); - static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, - mojo::Handle* out); -}; - -template<> -struct Converter<mojo::MessagePipeHandle> { - static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, - mojo::MessagePipeHandle val); - static bool FromV8(v8::Isolate* isolate, - v8::Handle<v8::Value> val, - mojo::MessagePipeHandle* out); -}; - -// We need to specialize the normal gin::Handle converter in order to handle -// converting |null| to a wrapper for an empty mojo::Handle. -template<> -struct Converter<gin::Handle<mojo::js::HandleWrapper> > { - static v8::Handle<v8::Value> ToV8( - v8::Isolate* isolate, const gin::Handle<mojo::js::HandleWrapper>& val) { - return val.ToV8(); - } - - static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, - gin::Handle<mojo::js::HandleWrapper>* out) { - if (val->IsNull()) { - *out = mojo::js::HandleWrapper::Create(isolate, MOJO_HANDLE_INVALID); - return true; - } - - mojo::js::HandleWrapper* object = NULL; - if (!Converter<mojo::js::HandleWrapper*>::FromV8(isolate, val, &object)) { - return false; - } - *out = gin::Handle<mojo::js::HandleWrapper>(val, object); - return true; - } -}; - -} // namespace gin - -#endif // MOJO_EDK_JS_HANDLE_H_ diff --git a/mojo/edk/js/handle_close_observer.h b/mojo/edk/js/handle_close_observer.h deleted file mode 100644 index 3e537fd..0000000 --- a/mojo/edk/js/handle_close_observer.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 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_EDK_JS_HANDLE_CLOSE_OBSERVER_H_ -#define MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_ - -namespace mojo { -namespace js { - -class HandleCloseObserver { - public: - virtual void OnWillCloseHandle() = 0; - - protected: - virtual ~HandleCloseObserver() {} -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_HANDLE_CLOSE_OBSERVER_H_ diff --git a/mojo/edk/js/handle_unittest.cc b/mojo/edk/js/handle_unittest.cc deleted file mode 100644 index 53f474e..0000000 --- a/mojo/edk/js/handle_unittest.cc +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2014 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 "base/macros.h" -#include "mojo/edk/js/handle.h" -#include "mojo/edk/js/handle_close_observer.h" -#include "mojo/public/cpp/system/core.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace js { - -class HandleWrapperTest : public testing::Test, - public HandleCloseObserver { - public: - HandleWrapperTest() : closes_observed_(0) {} - - void OnWillCloseHandle() override { closes_observed_++; } - - protected: - int closes_observed_; - - private: - DISALLOW_COPY_AND_ASSIGN(HandleWrapperTest); -}; - -class TestHandleWrapper : public HandleWrapper { - public: - explicit TestHandleWrapper(MojoHandle handle) : HandleWrapper(handle) {} - - private: - DISALLOW_COPY_AND_ASSIGN(TestHandleWrapper); -}; - -// Test that calling Close() on a HandleWrapper for an invalid handle does not -// notify observers. -TEST_F(HandleWrapperTest, CloseWithInvalidHandle) { - { - TestHandleWrapper wrapper(MOJO_HANDLE_INVALID); - wrapper.AddCloseObserver(this); - ASSERT_EQ(0, closes_observed_); - wrapper.Close(); - EXPECT_EQ(0, closes_observed_); - } - EXPECT_EQ(0, closes_observed_); -} - -// Test that destroying a HandleWrapper for an invalid handle does not notify -// observers. -TEST_F(HandleWrapperTest, DestroyWithInvalidHandle) { - { - TestHandleWrapper wrapper(MOJO_HANDLE_INVALID); - wrapper.AddCloseObserver(this); - ASSERT_EQ(0, closes_observed_); - } - EXPECT_EQ(0, closes_observed_); -} - -// Test that calling Close on a HandleWrapper for a valid handle notifies -// observers once. -TEST_F(HandleWrapperTest, CloseWithValidHandle) { - { - mojo::MessagePipe pipe; - TestHandleWrapper wrapper(pipe.handle0.release().value()); - wrapper.AddCloseObserver(this); - ASSERT_EQ(0, closes_observed_); - wrapper.Close(); - EXPECT_EQ(1, closes_observed_); - // Check that calling close again doesn't notify observers. - wrapper.Close(); - EXPECT_EQ(1, closes_observed_); - } - // Check that destroying a closed HandleWrapper doesn't notify observers. - EXPECT_EQ(1, closes_observed_); -} - -// Test that destroying a HandleWrapper for a valid handle notifies observers. -TEST_F(HandleWrapperTest, DestroyWithValidHandle) { - { - mojo::MessagePipe pipe; - TestHandleWrapper wrapper(pipe.handle0.release().value()); - wrapper.AddCloseObserver(this); - ASSERT_EQ(0, closes_observed_); - } - EXPECT_EQ(1, closes_observed_); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/mojo_runner_delegate.cc b/mojo/edk/js/mojo_runner_delegate.cc deleted file mode 100644 index 152b12c..0000000 --- a/mojo/edk/js/mojo_runner_delegate.cc +++ /dev/null @@ -1,78 +0,0 @@ -// 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/edk/js/mojo_runner_delegate.h" - -#include "base/bind.h" -#include "base/path_service.h" -#include "gin/converter.h" -#include "gin/modules/console.h" -#include "gin/modules/module_registry.h" -#include "gin/modules/timer.h" -#include "gin/try_catch.h" -#include "mojo/edk/js/core.h" -#include "mojo/edk/js/handle.h" -#include "mojo/edk/js/support.h" -#include "mojo/edk/js/threading.h" - -namespace mojo { -namespace js { - -namespace { - -// TODO(abarth): Rather than loading these modules from the file system, we -// should load them from the network via Mojo IPC. -std::vector<base::FilePath> GetModuleSearchPaths() { - std::vector<base::FilePath> search_paths(2); - PathService::Get(base::DIR_SOURCE_ROOT, &search_paths[0]); - PathService::Get(base::DIR_EXE, &search_paths[1]); - search_paths[1] = search_paths[1].AppendASCII("gen"); - return search_paths; -} - -void StartCallback(base::WeakPtr<gin::Runner> runner, - MojoHandle pipe, - v8::Handle<v8::Value> module) { - v8::Isolate* isolate = runner->GetContextHolder()->isolate(); - v8::Handle<v8::Function> start; - CHECK(gin::ConvertFromV8(isolate, module, &start)); - - v8::Handle<v8::Value> args[] = { - gin::ConvertToV8(isolate, Handle(pipe)) }; - runner->Call(start, runner->global(), 1, args); -} - -} // namespace - -MojoRunnerDelegate::MojoRunnerDelegate() - : ModuleRunnerDelegate(GetModuleSearchPaths()) { - AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); - AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule); - AddBuiltinModule(js::Core::kModuleName, js::Core::GetModule); - AddBuiltinModule(js::Support::kModuleName, js::Support::GetModule); - AddBuiltinModule(js::Threading::kModuleName, js::Threading::GetModule); -} - -MojoRunnerDelegate::~MojoRunnerDelegate() { -} - -void MojoRunnerDelegate::Start(gin::Runner* runner, - MojoHandle pipe, - const std::string& module) { - gin::Runner::Scope scope(runner); - gin::ModuleRegistry* registry = - gin::ModuleRegistry::From(runner->GetContextHolder()->context()); - registry->LoadModule(runner->GetContextHolder()->isolate(), module, - base::Bind(StartCallback, runner->GetWeakPtr(), pipe)); - AttemptToLoadMoreModules(runner); -} - -void MojoRunnerDelegate::UnhandledException(gin::ShellRunner* runner, - gin::TryCatch& try_catch) { - gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch); - LOG(ERROR) << try_catch.GetStackTrace(); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/mojo_runner_delegate.h b/mojo/edk/js/mojo_runner_delegate.h deleted file mode 100644 index 423eefb..0000000 --- a/mojo/edk/js/mojo_runner_delegate.h +++ /dev/null @@ -1,33 +0,0 @@ -// 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_EDK_JS_MOJO_RUNNER_DELEGATE_H_ -#define MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_ - -#include "base/macros.h" -#include "gin/modules/module_runner_delegate.h" -#include "mojo/public/c/system/core.h" - -namespace mojo { -namespace js { - -class MojoRunnerDelegate : public gin::ModuleRunnerDelegate { - public: - MojoRunnerDelegate(); - ~MojoRunnerDelegate() override; - - void Start(gin::Runner* runner, MojoHandle pipe, const std::string& module); - - private: - // From ModuleRunnerDelegate: - void UnhandledException(gin::ShellRunner* runner, - gin::TryCatch& try_catch) override; - - DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate); -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_MOJO_RUNNER_DELEGATE_H_ diff --git a/mojo/edk/js/support.cc b/mojo/edk/js/support.cc deleted file mode 100644 index 7d44024..0000000 --- a/mojo/edk/js/support.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 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/edk/js/support.h" - -#include "base/bind.h" -#include "gin/arguments.h" -#include "gin/converter.h" -#include "gin/function_template.h" -#include "gin/object_template_builder.h" -#include "gin/per_isolate_data.h" -#include "gin/public/wrapper_info.h" -#include "gin/wrappable.h" -#include "mojo/edk/js/handle.h" -#include "mojo/edk/js/waiting_callback.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -namespace js { - -namespace { - -WaitingCallback* AsyncWait(const gin::Arguments& args, - gin::Handle<HandleWrapper> handle, - MojoHandleSignals signals, - v8::Handle<v8::Function> callback) { - return WaitingCallback::Create(args.isolate(), callback, handle, signals) - .get(); -} - -void CancelWait(WaitingCallback* waiting_callback) { - waiting_callback->Cancel(); -} - -gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; - -} // namespace - -const char Support::kModuleName[] = "mojo/public/js/support"; - -v8::Local<v8::Value> Support::GetModule(v8::Isolate* isolate) { - gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); - v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( - &g_wrapper_info); - - if (templ.IsEmpty()) { - templ = gin::ObjectTemplateBuilder(isolate) - .SetMethod("asyncWait", AsyncWait) - .SetMethod("cancelWait", CancelWait) - .Build(); - - data->SetObjectTemplate(&g_wrapper_info, templ); - } - - return templ->NewInstance(); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/support.h b/mojo/edk/js/support.h deleted file mode 100644 index b49dd23..0000000 --- a/mojo/edk/js/support.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 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_EDK_JS_SUPPORT_H_ -#define MOJO_EDK_JS_SUPPORT_H_ - -#include "v8/include/v8.h" - -namespace mojo { -namespace js { - -class Support { - public: - static const char kModuleName[]; - static v8::Local<v8::Value> GetModule(v8::Isolate* isolate); -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_SUPPORT_H_ diff --git a/mojo/edk/js/test/BUILD.gn b/mojo/edk/js/test/BUILD.gn deleted file mode 100644 index badc3ad..0000000 --- a/mojo/edk/js/test/BUILD.gn +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2014 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. - -test("js_unittests") { - deps = [ - "../../js", - "../../js:js_unittests", - "../../test:run_all_unittests", - "../../test:test_support", - "../../../public/cpp/environment", - "../../../public/cpp/system", - "../../../public/cpp/utility", - "../../../public/interfaces/bindings/tests:test_interfaces", - "//base", - "//gin:gin_test", - "//mojo/environment:chromium", - ] - - sources = [ - "run_js_tests.cc", - ] -} - -test("js_integration_tests") { - deps = [ - "../../js", - "../../js/tests:js_to_cpp_tests", - "../../test:run_all_unittests", - "../../test:test_support", - "../../../public/cpp/bindings", - "../../../public/interfaces/bindings/tests:test_interfaces", - "//base", - "//gin:gin_test", - "//mojo/environment:chromium", - ] - - sources = [ - "run_js_integration_tests.cc", - ] -} diff --git a/mojo/edk/js/test/hexdump.js b/mojo/edk/js/test/hexdump.js deleted file mode 100644 index b36c47f..0000000 --- a/mojo/edk/js/test/hexdump.js +++ /dev/null @@ -1,34 +0,0 @@ -// 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(function() { - function hexify(value, length) { - var hex = value.toString(16); - while (hex.length < length) - hex = "0" + hex; - return hex; - } - - function dumpArray(bytes) { - var dumped = ""; - for (var i = 0; i < bytes.length; ++i) { - dumped += hexify(bytes[i], 2); - - if (i % 16 == 15) { - dumped += "\n"; - continue; - } - - if (i % 2 == 1) - dumped += " "; - if (i % 8 == 7) - dumped += " "; - } - return dumped; - } - - var exports = {}; - exports.dumpArray = dumpArray; - return exports; -}); diff --git a/mojo/edk/js/test/run_js_integration_tests.cc b/mojo/edk/js/test/run_js_integration_tests.cc deleted file mode 100644 index 1a6f1d6..0000000 --- a/mojo/edk/js/test/run_js_integration_tests.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 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 "base/files/file_path.h" -#include "base/path_service.h" -#include "gin/modules/console.h" -#include "gin/modules/module_registry.h" -#include "gin/modules/timer.h" -#include "gin/test/file_runner.h" -#include "gin/test/gtest.h" -#include "mojo/edk/js/core.h" -#include "mojo/edk/js/support.h" -#include "mojo/edk/js/threading.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace js { -namespace { - -class TestRunnerDelegate : public gin::FileRunnerDelegate { - public: - TestRunnerDelegate() { - AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); - AddBuiltinModule(Core::kModuleName, Core::GetModule); - AddBuiltinModule(gin::TimerModule::kName, gin::TimerModule::GetModule); - AddBuiltinModule(Threading::kModuleName, Threading::GetModule); - } - private: - DISALLOW_COPY_AND_ASSIGN(TestRunnerDelegate); -}; - -void RunTest(std::string test, bool addSupportModule) { - base::FilePath path; - PathService::Get(base::DIR_SOURCE_ROOT, &path); - path = path.AppendASCII("mojo") - .AppendASCII("edk") - .AppendASCII("js") - .AppendASCII("tests") - .AppendASCII(test); - TestRunnerDelegate delegate; - if (addSupportModule) - delegate.AddBuiltinModule(Support::kModuleName, Support::GetModule); - gin::RunTestFromFile(path, &delegate, true); -} - -TEST(JSTest, connection) { - RunTest("connection_tests.js", false); -} - -TEST(JSTest, sample_service) { - RunTest("sample_service_tests.js", true); -} - -} // namespace -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/test/run_js_tests.cc b/mojo/edk/js/test/run_js_tests.cc deleted file mode 100644 index b574902..0000000 --- a/mojo/edk/js/test/run_js_tests.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 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 "base/files/file_path.h" -#include "base/path_service.h" -#include "gin/modules/console.h" -#include "gin/modules/module_registry.h" -#include "gin/test/file_runner.h" -#include "gin/test/gtest.h" -#include "mojo/edk/js/core.h" -#include "mojo/edk/js/support.h" -#include "mojo/public/cpp/environment/environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace js { -namespace { - -class TestRunnerDelegate : public gin::FileRunnerDelegate { - public: - TestRunnerDelegate() { - AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); - AddBuiltinModule(Core::kModuleName, Core::GetModule); - AddBuiltinModule(Support::kModuleName, Support::GetModule); - } - - private: - DISALLOW_COPY_AND_ASSIGN(TestRunnerDelegate); -}; - -void RunTest(std::string test, bool run_until_idle) { - base::FilePath path; - PathService::Get(base::DIR_SOURCE_ROOT, &path); - path = path.AppendASCII("mojo") - .AppendASCII("public") - .AppendASCII("js") - .AppendASCII(test); - TestRunnerDelegate delegate; - gin::RunTestFromFile(path, &delegate, run_until_idle); -} - -// TODO(abarth): Should we autogenerate these stubs from GYP? -TEST(JSTest, core) { - RunTest("core_unittests.js", true); -} - -TEST(JSTest, codec) { - RunTest("codec_unittests.js", true); -} - -TEST(JSTest, struct) { - RunTest("struct_unittests.js", true); -} - -TEST(JSTest, validation) { - RunTest("validation_unittests.js", true); -} - -} // namespace -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/tests/BUILD.gn b/mojo/edk/js/tests/BUILD.gn deleted file mode 100644 index c9711c7..0000000 --- a/mojo/edk/js/tests/BUILD.gn +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2014 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. - -import("../../mojo_edk.gni") -import("../../../public/tools/bindings/mojom.gni") - -mojo_edk_source_set("js_to_cpp_tests") { - testonly = true - - deps = [ - ":js_to_cpp_bindings", - "//gin:gin_test", - ] - - mojo_edk_deps = [ - "mojo/edk/js", - "mojo/edk/test:test_support", - ] - - mojo_sdk_deps = [ - "mojo/public/cpp/bindings", - "mojo/public/cpp/system", - "mojo/public/interfaces/bindings/tests:test_interfaces", - ] - - sources = [ - "js_to_cpp_tests.cc", - ] -} - -mojom("js_to_cpp_bindings") { - sources = [ - "js_to_cpp.mojom", - ] -} diff --git a/mojo/edk/js/tests/connection_tests.js b/mojo/edk/js/tests/connection_tests.js deleted file mode 100644 index 17009d9..0000000 --- a/mojo/edk/js/tests/connection_tests.js +++ /dev/null @@ -1,264 +0,0 @@ -// 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. - -// Mock out the support module to avoid depending on the message loop. -define("mojo/public/js/support", ["timer"], function(timer) { - var waitingCallbacks = []; - - function WaitCookie(id) { - this.id = id; - } - - function asyncWait(handle, flags, callback) { - var id = waitingCallbacks.length; - waitingCallbacks.push(callback); - return new WaitCookie(id); - } - - function cancelWait(cookie) { - waitingCallbacks[cookie.id] = null; - } - - function numberOfWaitingCallbacks() { - var count = 0; - for (var i = 0; i < waitingCallbacks.length; ++i) { - if (waitingCallbacks[i]) - ++count; - } - return count; - } - - function pumpOnce(result) { - var callbacks = waitingCallbacks; - waitingCallbacks = []; - for (var i = 0; i < callbacks.length; ++i) { - if (callbacks[i]) - callbacks[i](result); - } - } - - // Queue up a pumpOnce call to execute after the stack unwinds. Use - // this to trigger a pump after all Promises are executed. - function queuePump(result) { - timer.createOneShot(0, pumpOnce.bind(undefined, result)); - } - - var exports = {}; - exports.asyncWait = asyncWait; - exports.cancelWait = cancelWait; - exports.numberOfWaitingCallbacks = numberOfWaitingCallbacks; - exports.pumpOnce = pumpOnce; - exports.queuePump = queuePump; - return exports; -}); - -define([ - "gin/test/expect", - "mojo/public/js/support", - "mojo/public/js/core", - "mojo/public/js/connection", - "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom", - "mojo/public/interfaces/bindings/tests/sample_service.mojom", - "mojo/public/js/threading", - "gc", -], function(expect, - mockSupport, - core, - connection, - sample_interfaces, - sample_service, - threading, - gc) { - testClientServer(); - testWriteToClosedPipe(); - testRequestResponse().then(function() { - this.result = "PASS"; - gc.collectGarbage(); // should not crash - threading.quit(); - }.bind(this)).catch(function(e) { - this.result = "FAIL: " + (e.stack || e); - threading.quit(); - }.bind(this)); - - function createPeerConnection(handle, stubClass, proxyClass) { - var c = new connection.Connection(handle, stubClass, proxyClass); - c.local.peer = c.remote; - c.remote.peer = c.local; - return c; - } - - function testClientServer() { - var receivedFrobinate = false; - var receivedDidFrobinate = false; - - // ServiceImpl ------------------------------------------------------------ - - function ServiceImpl() { - } - - ServiceImpl.prototype = Object.create( - sample_service.Service.stubClass.prototype); - - ServiceImpl.prototype.frobinate = function(foo, baz, port) { - receivedFrobinate = true; - - expect(foo.name).toBe("Example name"); - expect(baz).toBeTruthy(); - expect(core.close(port)).toBe(core.RESULT_OK); - - this.peer.didFrobinate(42); - }; - - // ServiceClientImpl ------------------------------------------------------ - - function ServiceClientImpl() { - } - - ServiceClientImpl.prototype = - Object.create(sample_service.ServiceClient.stubClass.prototype); - - ServiceClientImpl.prototype.didFrobinate = function(result) { - receivedDidFrobinate = true; - - expect(result).toBe(42); - }; - - var pipe = core.createMessagePipe(); - var anotherPipe = core.createMessagePipe(); - var sourcePipe = core.createMessagePipe(); - - var connection0 = createPeerConnection( - pipe.handle0, ServiceImpl, sample_service.ServiceClient.proxyClass); - - var connection1 = createPeerConnection( - pipe.handle1, ServiceClientImpl, sample_service.Service.proxyClass); - - var foo = new sample_service.Foo(); - foo.bar = new sample_service.Bar(); - foo.name = "Example name"; - foo.source = sourcePipe.handle0; - connection1.remote.frobinate(foo, true, anotherPipe.handle0); - - mockSupport.pumpOnce(core.RESULT_OK); - - expect(receivedFrobinate).toBeTruthy(); - expect(receivedDidFrobinate).toBeTruthy(); - - connection0.close(); - connection1.close(); - - expect(mockSupport.numberOfWaitingCallbacks()).toBe(0); - - // sourcePipe.handle0 was closed automatically when sent over IPC. - expect(core.close(sourcePipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); - // sourcePipe.handle1 hasn't been closed yet. - expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK); - - // anotherPipe.handle0 was closed automatically when sent over IPC. - expect(core.close(anotherPipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); - // anotherPipe.handle1 hasn't been closed yet. - expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK); - - // The Connection object is responsible for closing these handles. - expect(core.close(pipe.handle0)).toBe(core.RESULT_INVALID_ARGUMENT); - expect(core.close(pipe.handle1)).toBe(core.RESULT_INVALID_ARGUMENT); - } - - function testWriteToClosedPipe() { - var pipe = core.createMessagePipe(); - - var connection1 = createPeerConnection( - pipe.handle1, function() {}, sample_service.Service.proxyClass); - - // Close the other end of the pipe. - core.close(pipe.handle0); - - // Not observed yet because we haven't pumped events yet. - expect(connection1.encounteredError()).toBeFalsy(); - - var foo = new sample_service.Foo(); - foo.bar = new sample_service.Bar(); - // TODO(darin): crbug.com/357043: pass null in place of |foo| here. - connection1.remote.frobinate(foo, true, null); - - // Write failures are not reported. - expect(connection1.encounteredError()).toBeFalsy(); - - // Pump events, and then we should start observing the closed pipe. - mockSupport.pumpOnce(core.RESULT_OK); - - expect(connection1.encounteredError()).toBeTruthy(); - - connection1.close(); - } - - function testRequestResponse() { - - // ProviderImpl ------------------------------------------------------------ - - function ProviderImpl() { - } - - ProviderImpl.prototype = - Object.create(sample_interfaces.Provider.stubClass.prototype); - - ProviderImpl.prototype.echoString = function(a) { - mockSupport.queuePump(core.RESULT_OK); - return Promise.resolve({a: a}); - }; - - ProviderImpl.prototype.echoStrings = function(a, b) { - mockSupport.queuePump(core.RESULT_OK); - return Promise.resolve({a: a, b: b}); - }; - - // ProviderClientImpl ------------------------------------------------------ - - function ProviderClientImpl() { - } - - ProviderClientImpl.prototype = - Object.create(sample_interfaces.ProviderClient.stubClass.prototype); - - var pipe = core.createMessagePipe(); - - var connection0 = createPeerConnection( - pipe.handle0, - ProviderImpl, - sample_interfaces.ProviderClient.proxyClass); - - var connection1 = createPeerConnection( - pipe.handle1, - ProviderClientImpl, - sample_interfaces.Provider.proxyClass); - - var origReadMessage = core.readMessage; - // echoString - mockSupport.queuePump(core.RESULT_OK); - return connection1.remote.echoString("hello").then(function(response) { - expect(response.a).toBe("hello"); - }).then(function() { - // echoStrings - mockSupport.queuePump(core.RESULT_OK); - return connection1.remote.echoStrings("hello", "world"); - }).then(function(response) { - expect(response.a).toBe("hello"); - expect(response.b).toBe("world"); - }).then(function() { - // Mock a read failure, expect it to fail. - core.readMessage = function() { - return { result: core.RESULT_UNKNOWN }; - }; - mockSupport.queuePump(core.RESULT_OK); - return connection1.remote.echoString("goodbye"); - }).then(function() { - throw Error("Expected echoString to fail."); - }, function(error) { - expect(error.message).toBe("Connection error: " + core.RESULT_UNKNOWN); - - // Clean up. - core.readMessage = origReadMessage; - }); - } -}); diff --git a/mojo/edk/js/tests/js_to_cpp.mojom b/mojo/edk/js/tests/js_to_cpp.mojom deleted file mode 100644 index 69f67b6..0000000 --- a/mojo/edk/js/tests/js_to_cpp.mojom +++ /dev/null @@ -1,53 +0,0 @@ -module js_to_cpp; - -// This struct encompasses all of the basic types, so that they -// may be sent from C++ to JS and back for validation. -struct EchoArgs { - int64 si64; - int32 si32; - int16 si16; - int8 si8; - uint64 ui64; - uint32 ui32; - uint16 ui16; - uint8 ui8; - float float_val; - float float_inf; - float float_nan; - double double_val; - double double_inf; - double double_nan; - string? name; - array<string>? string_array; - handle<message_pipe>? message_handle; - handle<data_pipe_consumer>? data_handle; -}; - -struct EchoArgsList { - EchoArgsList? next; - EchoArgs? item; -}; - -// Note: For messages which control test flow, pick numbers that are unlikely -// to be hit as a result of our deliberate corruption of response messages. -interface CppSide { - // Sent for all tests to notify that the JS side is now ready. - StartTest@88888888(); - - // Indicates end for echo, bit-flip, and back-pointer tests. - TestFinished@99999999(); - - // Responses from specific tests. - PingResponse(); - EchoResponse(EchoArgsList list); - BitFlipResponse(EchoArgsList arg); - BackPointerResponse(EchoArgsList arg); -}; - -[Client=CppSide] -interface JsSide { - Ping(); - Echo(int32 numIterations, EchoArgs arg); - BitFlip(EchoArgs arg); - BackPointer(EchoArgs arg); -}; diff --git a/mojo/edk/js/tests/js_to_cpp_tests.cc b/mojo/edk/js/tests/js_to_cpp_tests.cc deleted file mode 100644 index 1da70c2..0000000 --- a/mojo/edk/js/tests/js_to_cpp_tests.cc +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2014 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 "base/at_exit.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "gin/array_buffer.h" -#include "gin/public/isolate_holder.h" -#include "mojo/edk/js/mojo_runner_delegate.h" -#include "mojo/edk/js/tests/js_to_cpp.mojom.h" -#include "mojo/edk/test/test_utils.h" -#include "mojo/public/cpp/system/core.h" -#include "mojo/public/cpp/system/macros.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace js { - -// Global value updated by some checks to prevent compilers from optimizing -// reads out of existence. -uint32 g_waste_accumulator = 0; - -namespace { - -// Negative numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const int8 kExpectedInt8Value = -65; -const int16 kExpectedInt16Value = -16961; -const int32 kExpectedInt32Value = -1145258561; -const int64 kExpectedInt64Value = -77263311946305LL; - -// Positive numbers with different values in each byte, the last of -// which can survive promotion to double and back. -const uint8 kExpectedUInt8Value = 65; -const uint16 kExpectedUInt16Value = 16961; -const uint32 kExpectedUInt32Value = 1145258561; -const uint64 kExpectedUInt64Value = 77263311946305LL; - -// Double/float values, including special case constants. -const double kExpectedDoubleVal = 3.14159265358979323846; -const double kExpectedDoubleInf = std::numeric_limits<double>::infinity(); -const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN(); -const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal); -const float kExpectedFloatInf = std::numeric_limits<float>::infinity(); -const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN(); - -// NaN has the property that it is not equal to itself. -#define EXPECT_NAN(x) EXPECT_NE(x, x) - -void CheckDataPipe(MojoHandle data_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = MojoReadData( - data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE); - EXPECT_EQ(MOJO_RESULT_OK, result); - EXPECT_EQ(64u, buffer_size); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(i, buffer[i]); - } -} - -void CheckMessagePipe(MojoHandle message_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = MojoReadMessage( - message_pipe_handle, buffer, &buffer_size, 0, 0, 0); - EXPECT_EQ(MOJO_RESULT_OK, result); - EXPECT_EQ(64u, buffer_size); - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(255 - i, buffer[i]); - } -} - -js_to_cpp::EchoArgsPtr BuildSampleEchoArgs() { - js_to_cpp::EchoArgsPtr args(js_to_cpp::EchoArgs::New()); - args->si64 = kExpectedInt64Value; - args->si32 = kExpectedInt32Value; - args->si16 = kExpectedInt16Value; - args->si8 = kExpectedInt8Value; - args->ui64 = kExpectedUInt64Value; - args->ui32 = kExpectedUInt32Value; - args->ui16 = kExpectedUInt16Value; - args->ui8 = kExpectedUInt8Value; - args->float_val = kExpectedFloatVal; - args->float_inf = kExpectedFloatInf; - args->float_nan = kExpectedFloatNan; - args->double_val = kExpectedDoubleVal; - args->double_inf = kExpectedDoubleInf; - args->double_nan = kExpectedDoubleNan; - args->name = "coming"; - Array<String> string_array(3); - string_array[0] = "one"; - string_array[1] = "two"; - string_array[2] = "three"; - args->string_array = string_array.Pass(); - return args.Pass(); -} - -void CheckSampleEchoArgs(const js_to_cpp::EchoArgs& arg) { - EXPECT_EQ(kExpectedInt64Value, arg.si64); - EXPECT_EQ(kExpectedInt32Value, arg.si32); - EXPECT_EQ(kExpectedInt16Value, arg.si16); - EXPECT_EQ(kExpectedInt8Value, arg.si8); - EXPECT_EQ(kExpectedUInt64Value, arg.ui64); - EXPECT_EQ(kExpectedUInt32Value, arg.ui32); - EXPECT_EQ(kExpectedUInt16Value, arg.ui16); - EXPECT_EQ(kExpectedUInt8Value, arg.ui8); - EXPECT_EQ(kExpectedFloatVal, arg.float_val); - EXPECT_EQ(kExpectedFloatInf, arg.float_inf); - EXPECT_NAN(arg.float_nan); - EXPECT_EQ(kExpectedDoubleVal, arg.double_val); - EXPECT_EQ(kExpectedDoubleInf, arg.double_inf); - EXPECT_NAN(arg.double_nan); - EXPECT_EQ(std::string("coming"), arg.name.get()); - EXPECT_EQ(std::string("one"), arg.string_array[0].get()); - EXPECT_EQ(std::string("two"), arg.string_array[1].get()); - EXPECT_EQ(std::string("three"), arg.string_array[2].get()); - CheckDataPipe(arg.data_handle.get().value()); - CheckMessagePipe(arg.message_handle.get().value()); -} - -void CheckSampleEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckSampleEchoArgs(*list->item); - CheckSampleEchoArgsList(list->next); -} - -// More forgiving checks are needed in the face of potentially corrupt -// messages. The values don't matter so long as all accesses are within -// bounds. -void CheckCorruptedString(const String& arg) { - if (arg.is_null()) - return; - for (size_t i = 0; i < arg.size(); ++i) - g_waste_accumulator += arg[i]; -} - -void CheckCorruptedStringArray(const Array<String>& string_array) { - if (string_array.is_null()) - return; - for (size_t i = 0; i < string_array.size(); ++i) - CheckCorruptedString(string_array[i]); -} - -void CheckCorruptedDataPipe(MojoHandle data_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = MojoReadData( - data_pipe_handle, buffer, &buffer_size, MOJO_READ_DATA_FLAG_NONE); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < buffer_size; ++i) - g_waste_accumulator += buffer[i]; -} - -void CheckCorruptedMessagePipe(MojoHandle message_pipe_handle) { - unsigned char buffer[100]; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - MojoResult result = MojoReadMessage( - message_pipe_handle, buffer, &buffer_size, 0, 0, 0); - if (result != MOJO_RESULT_OK) - return; - for (uint32_t i = 0; i < buffer_size; ++i) - g_waste_accumulator += buffer[i]; -} - -void CheckCorruptedEchoArgs(const js_to_cpp::EchoArgsPtr& arg) { - if (arg.is_null()) - return; - CheckCorruptedString(arg->name); - CheckCorruptedStringArray(arg->string_array); - if (arg->data_handle.is_valid()) - CheckCorruptedDataPipe(arg->data_handle.get().value()); - if (arg->message_handle.is_valid()) - CheckCorruptedMessagePipe(arg->message_handle.get().value()); -} - -void CheckCorruptedEchoArgsList(const js_to_cpp::EchoArgsListPtr& list) { - if (list.is_null()) - return; - CheckCorruptedEchoArgs(list->item); - CheckCorruptedEchoArgsList(list->next); -} - -// Base Provider implementation class. It's expected that tests subclass and -// override the appropriate Provider functions. When test is done quit the -// run_loop(). -class CppSideConnection : public js_to_cpp::CppSide { - public: - CppSideConnection() : - run_loop_(NULL), - js_side_(NULL), - mishandled_messages_(0) { - } - ~CppSideConnection() override {} - - void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; } - base::RunLoop* run_loop() { return run_loop_; } - - void set_js_side(js_to_cpp::JsSide* js_side) { js_side_ = js_side; } - js_to_cpp::JsSide* js_side() { return js_side_; } - - // js_to_cpp::CppSide: - void StartTest() override { NOTREACHED(); } - - void TestFinished() override { NOTREACHED(); } - - void PingResponse() override { mishandled_messages_ += 1; } - - void EchoResponse(js_to_cpp::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override { - mishandled_messages_ += 1; - } - - protected: - base::RunLoop* run_loop_; - js_to_cpp::JsSide* js_side_; - int mishandled_messages_; - - private: - DISALLOW_COPY_AND_ASSIGN(CppSideConnection); -}; - -// Trivial test to verify a message sent from JS is received. -class PingCppSideConnection : public CppSideConnection { - public: - PingCppSideConnection() : got_message_(false) {} - ~PingCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->Ping(); } - - void PingResponse() override { - got_message_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return got_message_ && !mishandled_messages_; - } - - private: - bool got_message_; - DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection); -}; - -// Test that parameters are passed with correct values. -class EchoCppSideConnection : public CppSideConnection { - public: - EchoCppSideConnection() : - message_count_(0), - termination_seen_(false) { - } - ~EchoCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { - js_side_->Echo(kExpectedMessageCount, BuildSampleEchoArgs()); - } - - void EchoResponse(js_to_cpp::EchoArgsListPtr list) override { - const js_to_cpp::EchoArgsPtr& special_arg = list->item; - message_count_ += 1; - EXPECT_EQ(-1, special_arg->si64); - EXPECT_EQ(-1, special_arg->si32); - EXPECT_EQ(-1, special_arg->si16); - EXPECT_EQ(-1, special_arg->si8); - EXPECT_EQ(std::string("going"), special_arg->name.To<std::string>()); - CheckSampleEchoArgsList(list->next); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_ && - !mishandled_messages_ && - message_count_ == kExpectedMessageCount; - } - - private: - static const int kExpectedMessageCount = 10; - int message_count_; - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection); -}; - -// Test that corrupted messages don't wreak havoc. -class BitFlipCppSideConnection : public CppSideConnection { - public: - BitFlipCppSideConnection() : termination_seen_(false) {} - ~BitFlipCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BitFlip(BuildSampleEchoArgs()); } - - void BitFlipResponse(js_to_cpp::EchoArgsListPtr list) override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_; - } - - private: - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(BitFlipCppSideConnection); -}; - -// Test that severely random messages don't wreak havoc. -class BackPointerCppSideConnection : public CppSideConnection { - public: - BackPointerCppSideConnection() : termination_seen_(false) {} - ~BackPointerCppSideConnection() override {} - - // js_to_cpp::CppSide: - void StartTest() override { js_side_->BackPointer(BuildSampleEchoArgs()); } - - void BackPointerResponse(js_to_cpp::EchoArgsListPtr list) override { - CheckCorruptedEchoArgsList(list); - } - - void TestFinished() override { - termination_seen_ = true; - run_loop()->Quit(); - } - - bool DidSucceed() { - return termination_seen_; - } - - private: - bool termination_seen_; - DISALLOW_COPY_AND_ASSIGN(BackPointerCppSideConnection); -}; - -} // namespace - -class JsToCppTest : public testing::Test { - public: - JsToCppTest() {} - - void RunTest(const std::string& test, CppSideConnection* cpp_side) { - cpp_side->set_run_loop(&run_loop_); - - MessagePipe pipe; - js_to_cpp::JsSidePtr js_side = - MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass()); - js_side.set_client(cpp_side); - - js_side.internal_state()->router_for_testing()->EnableTestingMode(); - - cpp_side->set_js_side(js_side.get()); - - gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode, - gin::ArrayBufferAllocator::SharedInstance()); - gin::IsolateHolder instance; - MojoRunnerDelegate delegate; - gin::ShellRunner runner(&delegate, instance.isolate()); - delegate.Start(&runner, pipe.handle1.release().value(), test); - - run_loop_.Run(); - } - - private: - base::ShadowingAtExitManager at_exit_; - base::MessageLoop loop; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(JsToCppTest); -}; - -TEST_F(JsToCppTest, Ping) { - PingCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, Echo) { - EchoCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, BitFlip) { - BitFlipCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -TEST_F(JsToCppTest, BackPointer) { - BackPointerCppSideConnection cpp_side_connection; - RunTest("mojo/edk/js/tests/js_to_cpp_tests", &cpp_side_connection); - EXPECT_TRUE(cpp_side_connection.DidSucceed()); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/tests/js_to_cpp_tests.js b/mojo/edk/js/tests/js_to_cpp_tests.js deleted file mode 100644 index 140ad4c..0000000 --- a/mojo/edk/js/tests/js_to_cpp_tests.js +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright 2014 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/edk/js/tests/js_to_cpp_tests', [ - 'console', - 'mojo/edk/js/tests/js_to_cpp.mojom', - 'mojo/public/js/connection', - 'mojo/public/js/connector', - 'mojo/public/js/core', -], function (console, jsToCpp, connection, connector, core) { - var retainedConnection; - var sampleData; - var sampleMessage; - var BAD_VALUE = 13; - var DATA_PIPE_PARAMS = { - flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, - elementNumBytes: 1, - capacityNumBytes: 64 - }; - - function JsSideConnection() { - } - - JsSideConnection.prototype = - Object.create(jsToCpp.JsSide.stubClass.prototype); - - JsSideConnection.prototype.ping = function (arg) { - this.cppSide_.pingResponse(); - }; - - JsSideConnection.prototype.echo = function (numIterations, arg) { - var dataPipe1; - var dataPipe2; - var i; - var messagePipe1; - var messagePipe2; - var specialArg; - - // Ensure expected negative values are negative. - if (arg.si64 > 0) - arg.si64 = BAD_VALUE; - - if (arg.si32 > 0) - arg.si32 = BAD_VALUE; - - if (arg.si16 > 0) - arg.si16 = BAD_VALUE; - - if (arg.si8 > 0) - arg.si8 = BAD_VALUE; - - for (i = 0; i < numIterations; ++i) { - dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS); - dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS); - messagePipe1 = core.createMessagePipe(); - messagePipe2 = core.createMessagePipe(); - - arg.data_handle = dataPipe1.consumerHandle; - arg.message_handle = messagePipe1.handle1; - - specialArg = new jsToCpp.EchoArgs(); - specialArg.si64 = -1; - specialArg.si32 = -1; - specialArg.si16 = -1; - specialArg.si8 = -1; - specialArg.name = 'going'; - specialArg.data_handle = dataPipe2.consumerHandle; - specialArg.message_handle = messagePipe2.handle1; - - writeDataPipe(dataPipe1, sampleData); - writeDataPipe(dataPipe2, sampleData); - writeMessagePipe(messagePipe1, sampleMessage); - writeMessagePipe(messagePipe2, sampleMessage); - - this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg)); - - core.close(dataPipe1.producerHandle); - core.close(dataPipe2.producerHandle); - core.close(messagePipe1.handle0); - core.close(messagePipe2.handle0); - } - this.cppSide_.testFinished(); - }; - - JsSideConnection.prototype.bitFlip = function (arg) { - var iteration = 0; - var dataPipe; - var messagePipe; - var proto = connector.Connector.prototype; - var stopSignalled = false; - - proto.realAccept = proto.accept; - proto.accept = function (message) { - var offset = iteration / 8; - var mask; - var value; - if (offset < message.buffer.arrayBuffer.byteLength) { - mask = 1 << (iteration % 8); - value = message.buffer.getUint8(offset) ^ mask; - message.buffer.setUint8(offset, value); - return this.realAccept(message); - } - stopSignalled = true; - return false; - }; - - while (!stopSignalled) { - dataPipe = core.createDataPipe(DATA_PIPE_PARAMS); - messagePipe = core.createMessagePipe(); - writeDataPipe(dataPipe, sampleData); - writeMessagePipe(messagePipe, sampleMessage); - arg.data_handle = dataPipe.consumerHandle; - arg.message_handle = messagePipe.handle1; - - this.cppSide_.bitFlipResponse(createEchoArgsList(arg)); - - core.close(dataPipe.producerHandle); - core.close(messagePipe.handle0); - iteration += 1; - } - - proto.accept = proto.realAccept; - proto.realAccept = null; - this.cppSide_.testFinished(); - }; - - JsSideConnection.prototype.backPointer = function (arg) { - var iteration = 0; - var dataPipe; - var messagePipe; - var proto = connector.Connector.prototype; - var stopSignalled = false; - - proto.realAccept = proto.accept; - proto.accept = function (message) { - var delta = 8 * (1 + iteration % 32); - var offset = 8 * ((iteration / 32) | 0); - if (offset < message.buffer.arrayBuffer.byteLength - 4) { - message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true); - message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true); - return this.realAccept(message); - } - stopSignalled = true; - return false; - }; - - while (!stopSignalled) { - dataPipe = core.createDataPipe(DATA_PIPE_PARAMS); - messagePipe = core.createMessagePipe(); - writeDataPipe(dataPipe, sampleData); - writeMessagePipe(messagePipe, sampleMessage); - arg.data_handle = dataPipe.consumerHandle; - arg.message_handle = messagePipe.handle1; - - this.cppSide_.backPointerResponse(createEchoArgsList(arg)); - - core.close(dataPipe.producerHandle); - core.close(messagePipe.handle0); - iteration += 1; - } - - proto.accept = proto.realAccept; - proto.realAccept = null; - this.cppSide_.testFinished(); - }; - - function writeDataPipe(pipe, data) { - var writeResult = core.writeData( - pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE); - - if (writeResult.result != core.RESULT_OK) { - console.log('ERROR: Data pipe write result was ' + writeResult.result); - return false; - } - if (writeResult.numBytes != data.length) { - console.log('ERROR: Data pipe write length was ' + writeResult.numBytes); - return false; - } - return true; - } - - function writeMessagePipe(pipe, arrayBuffer) { - var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0); - if (result != core.RESULT_OK) { - console.log('ERROR: Message pipe write result was ' + result); - return false; - } - return true; - } - - function createEchoArgsListElement(item, next) { - var list = new jsToCpp.EchoArgsList(); - list.item = item; - list.next = next; - return list; - } - - function createEchoArgsList() { - var genuineArray = Array.prototype.slice.call(arguments); - return genuineArray.reduceRight(function (previous, current) { - return createEchoArgsListElement(current, previous); - }, null); - } - - function createCppSideConnection(handle, stubClass, proxyClass) { - var c = new connection.Connection(handle, stubClass, proxyClass); - c.local.cppSide_ = c.remote; - return c; - } - - return function(handle) { - var i; - sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); - for (i = 0; i < sampleData.length; ++i) { - sampleData[i] = i; - } - sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes); - for (i = 0; i < sampleMessage.length; ++i) { - sampleMessage[i] = 255 - i; - } - retainedConnection = createCppSideConnection( - handle, JsSideConnection,jsToCpp.CppSide.proxyClass); - retainedConnection.remote.startTest(); - }; -}); diff --git a/mojo/edk/js/tests/sample_service_tests.js b/mojo/edk/js/tests/sample_service_tests.js deleted file mode 100644 index 2afdf3e..0000000 --- a/mojo/edk/js/tests/sample_service_tests.js +++ /dev/null @@ -1,171 +0,0 @@ -// 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([ - "console", - "mojo/edk/js/test/hexdump", - "gin/test/expect", - "mojo/public/interfaces/bindings/tests/sample_service.mojom", - "mojo/public/interfaces/bindings/tests/sample_import.mojom", - "mojo/public/interfaces/bindings/tests/sample_import2.mojom", - "mojo/public/js/core", - ], function(console, hexdump, expect, sample, imported, imported2, core) { - - var global = this; - - // Set this variable to true to print the binary message in hex. - var dumpMessageAsHex = false; - - function makeFoo() { - var bar = new sample.Bar(); - bar.alpha = 20; - bar.beta = 40; - bar.gamma = 60; - bar.type = sample.Bar.Type.VERTICAL; - - var extra_bars = new Array(3); - for (var i = 0; i < extra_bars.length; ++i) { - var base = i * 100; - var type = i % 2 ? - sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL; - extra_bars[i] = new sample.Bar(); - extra_bars[i].alpha = base; - extra_bars[i].beta = base + 20; - extra_bars[i].gamma = base + 40; - extra_bars[i].type = type; - } - - var data = new Array(10); - for (var i = 0; i < data.length; ++i) { - data[i] = data.length - i; - } - - var source = 0xFFFF; // Invent a dummy handle. - - var foo = new sample.Foo(); - foo.name = "foopy"; - foo.x = 1; - foo.y = 2; - foo.a = false; - foo.b = true; - foo.c = false; - foo.bar = bar; - foo.extra_bars = extra_bars; - foo.data = data; - foo.source = source; - return foo; - } - - // Check that the given |Foo| is identical to the one made by |MakeFoo()|. - function checkFoo(foo) { - expect(foo.name).toBe("foopy"); - expect(foo.x).toBe(1); - expect(foo.y).toBe(2); - expect(foo.a).toBeFalsy(); - expect(foo.b).toBeTruthy(); - expect(foo.c).toBeFalsy(); - expect(foo.bar.alpha).toBe(20); - expect(foo.bar.beta).toBe(40); - expect(foo.bar.gamma).toBe(60); - expect(foo.bar.type).toBe(sample.Bar.Type.VERTICAL); - - expect(foo.extra_bars.length).toBe(3); - for (var i = 0; i < foo.extra_bars.length; ++i) { - var base = i * 100; - var type = i % 2 ? - sample.Bar.Type.VERTICAL : sample.Bar.Type.HORIZONTAL; - expect(foo.extra_bars[i].alpha).toBe(base); - expect(foo.extra_bars[i].beta).toBe(base + 20); - expect(foo.extra_bars[i].gamma).toBe(base + 40); - expect(foo.extra_bars[i].type).toBe(type); - } - - expect(foo.data.length).toBe(10); - for (var i = 0; i < foo.data.length; ++i) - expect(foo.data[i]).toBe(foo.data.length - i); - - expect(foo.source).toBe(0xFFFF); - } - - // Check that values are set to the defaults if we don't override them. - function checkDefaultValues() { - var bar = new sample.Bar(); - expect(bar.alpha).toBe(255); - expect(bar.type).toBe(sample.Bar.Type.VERTICAL); - - var foo = new sample.Foo(); - expect(foo.name).toBe("Fooby"); - expect(foo.a).toBeTruthy(); - expect(foo.data).toBeNull(); - - var defaults = new sample.DefaultsTest(); - expect(defaults.a0).toBe(-12); - expect(defaults.a1).toBe(sample.kTwelve); - expect(defaults.a2).toBe(1234); - expect(defaults.a3).toBe(34567); - expect(defaults.a4).toBe(123456); - expect(defaults.a5).toBe(3456789012); - expect(defaults.a6).toBe(-111111111111); - // JS doesn't have a 64 bit integer type so this is just checking that the - // expected and actual values have the same closest double value. - expect(defaults.a7).toBe(9999999999999999999); - expect(defaults.a8).toBe(0x12345); - expect(defaults.a9).toBe(-0x12345); - expect(defaults.a10).toBe(1234); - expect(defaults.a11).toBe(true); - expect(defaults.a12).toBe(false); - expect(defaults.a13).toBe(123.25); - expect(defaults.a14).toBe(1234567890.123); - expect(defaults.a15).toBe(1E10); - expect(defaults.a16).toBe(-1.2E+20); - expect(defaults.a17).toBe(1.23E-20); - expect(defaults.a20).toBe(sample.Bar.Type.BOTH); - expect(defaults.a21).toBeNull(); - expect(defaults.a22).toBeTruthy(); - expect(defaults.a22.shape).toBe(imported.Shape.RECTANGLE); - expect(defaults.a22.color).toBe(imported2.Color.BLACK); - expect(defaults.a21).toBeNull(); - expect(defaults.a23).toBe(0xFFFFFFFFFFFFFFFF); - expect(defaults.a24).toBe(0x123456789); - expect(defaults.a25).toBe(-0x123456789); - } - - function ServiceImpl() { - } - - ServiceImpl.prototype = Object.create(sample.Service.stubClass.prototype); - - ServiceImpl.prototype.frobinate = function(foo, baz, port) { - checkFoo(foo); - expect(baz).toBe(sample.Service.BazOptions.EXTRA); - expect(core.isHandle(port)).toBeTruthy(); - global.result = "PASS"; - }; - - function SimpleMessageReceiver() { - } - - SimpleMessageReceiver.prototype.accept = function(message) { - if (dumpMessageAsHex) { - var uint8Array = new Uint8Array(message.buffer.arrayBuffer); - console.log(hexdump.dumpArray(uint8Array)); - } - // Imagine some IPC happened here. - var serviceImpl = new ServiceImpl(); - serviceImpl.accept(message); - }; - - var serviceProxy = new sample.Service.proxyClass; - serviceProxy.receiver_ = new SimpleMessageReceiver; - - checkDefaultValues(); - - var foo = makeFoo(); - checkFoo(foo); - - var pipe = core.createMessagePipe(); - serviceProxy.frobinate(foo, sample.Service.BazOptions.EXTRA, pipe.handle0); - expect(core.close(pipe.handle0)).toBe(core.RESULT_OK); - expect(core.close(pipe.handle1)).toBe(core.RESULT_OK); -}); diff --git a/mojo/edk/js/threading.cc b/mojo/edk/js/threading.cc deleted file mode 100644 index b571e3e..0000000 --- a/mojo/edk/js/threading.cc +++ /dev/null @@ -1,47 +0,0 @@ -// 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/edk/js/threading.h" - -#include "base/message_loop/message_loop.h" -#include "gin/object_template_builder.h" -#include "gin/per_isolate_data.h" -#include "mojo/edk/js/handle.h" - -namespace mojo { -namespace js { - -namespace { - -void Quit() { - base::MessageLoop::current()->QuitNow(); -} - -gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; - -} // namespace - -const char Threading::kModuleName[] = "mojo/public/js/threading"; - -v8::Local<v8::Value> Threading::GetModule(v8::Isolate* isolate) { - gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); - v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( - &g_wrapper_info); - - if (templ.IsEmpty()) { - templ = gin::ObjectTemplateBuilder(isolate) - .SetMethod("quit", Quit) - .Build(); - - data->SetObjectTemplate(&g_wrapper_info, templ); - } - - return templ->NewInstance(); -} - -Threading::Threading() { -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/threading.h b/mojo/edk/js/threading.h deleted file mode 100644 index 7cf0d53..0000000 --- a/mojo/edk/js/threading.h +++ /dev/null @@ -1,25 +0,0 @@ -// 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_EDK_JS_THREADING_H_ -#define MOJO_EDK_JS_THREADING_H_ - -#include "gin/public/wrapper_info.h" -#include "v8/include/v8.h" - -namespace mojo { -namespace js { - -class Threading { - public: - static const char kModuleName[]; - static v8::Local<v8::Value> GetModule(v8::Isolate* isolate); - private: - Threading(); -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_THREADING_H_ diff --git a/mojo/edk/js/waiting_callback.cc b/mojo/edk/js/waiting_callback.cc deleted file mode 100644 index d5c48c5..0000000 --- a/mojo/edk/js/waiting_callback.cc +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2014 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/edk/js/waiting_callback.h" - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "gin/per_context_data.h" -#include "mojo/public/cpp/environment/environment.h" - -namespace mojo { -namespace js { - -namespace { - -v8::Handle<v8::String> GetHiddenPropertyName(v8::Isolate* isolate) { - return gin::StringToSymbol(isolate, "::mojo::js::WaitingCallback"); -} - -} // namespace - -gin::WrapperInfo WaitingCallback::kWrapperInfo = { gin::kEmbedderNativeGin }; - -// static -gin::Handle<WaitingCallback> WaitingCallback::Create( - v8::Isolate* isolate, - v8::Handle<v8::Function> callback, - gin::Handle<HandleWrapper> handle_wrapper, - MojoHandleSignals signals) { - gin::Handle<WaitingCallback> waiting_callback = gin::CreateHandle( - isolate, new WaitingCallback(isolate, callback, handle_wrapper)); - waiting_callback->wait_id_ = Environment::GetDefaultAsyncWaiter()->AsyncWait( - handle_wrapper->get().value(), - signals, - MOJO_DEADLINE_INDEFINITE, - &WaitingCallback::CallOnHandleReady, - waiting_callback.get()); - return waiting_callback; -} - -void WaitingCallback::Cancel() { - if (!wait_id_) - return; - - handle_wrapper_->RemoveCloseObserver(this); - handle_wrapper_ = NULL; - Environment::GetDefaultAsyncWaiter()->CancelWait(wait_id_); - wait_id_ = 0; -} - -WaitingCallback::WaitingCallback(v8::Isolate* isolate, - v8::Handle<v8::Function> callback, - gin::Handle<HandleWrapper> handle_wrapper) - : wait_id_(0), handle_wrapper_(handle_wrapper.get()), weak_factory_(this) { - handle_wrapper_->AddCloseObserver(this); - v8::Handle<v8::Context> context = isolate->GetCurrentContext(); - runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr(); - GetWrapper(isolate)->SetHiddenValue(GetHiddenPropertyName(isolate), callback); -} - -WaitingCallback::~WaitingCallback() { - Cancel(); -} - -// static -void WaitingCallback::CallOnHandleReady(void* closure, MojoResult result) { - static_cast<WaitingCallback*>(closure)->OnHandleReady(result); -} - -void WaitingCallback::ClearWaitId() { - wait_id_ = 0; - handle_wrapper_->RemoveCloseObserver(this); - handle_wrapper_ = nullptr; -} - -void WaitingCallback::OnHandleReady(MojoResult result) { - ClearWaitId(); - CallCallback(result); -} - -void WaitingCallback::CallCallback(MojoResult result) { - // ClearWaitId must already have been called. - DCHECK(!wait_id_); - DCHECK(!handle_wrapper_); - - if (!runner_) - return; - - gin::Runner::Scope scope(runner_.get()); - v8::Isolate* isolate = runner_->GetContextHolder()->isolate(); - - v8::Handle<v8::Value> hidden_value = - GetWrapper(isolate)->GetHiddenValue(GetHiddenPropertyName(isolate)); - v8::Handle<v8::Function> callback; - CHECK(gin::ConvertFromV8(isolate, hidden_value, &callback)); - - v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, result) }; - runner_->Call(callback, runner_->global(), 1, args); -} - -void WaitingCallback::OnWillCloseHandle() { - Environment::GetDefaultAsyncWaiter()->CancelWait(wait_id_); - - // This may be called from GC, so we can't execute Javascript now, call - // ClearWaitId explicitly, and CallCallback asynchronously. - ClearWaitId(); - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&WaitingCallback::CallCallback, weak_factory_.GetWeakPtr(), - MOJO_RESULT_INVALID_ARGUMENT)); -} - -} // namespace js -} // namespace mojo diff --git a/mojo/edk/js/waiting_callback.h b/mojo/edk/js/waiting_callback.h deleted file mode 100644 index 5a9dfaf..0000000 --- a/mojo/edk/js/waiting_callback.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2014 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_EDK_JS_WAITING_CALLBACK_H_ -#define MOJO_EDK_JS_WAITING_CALLBACK_H_ - -#include "base/memory/weak_ptr.h" -#include "gin/handle.h" -#include "gin/runner.h" -#include "gin/wrappable.h" -#include "mojo/edk/js/handle.h" -#include "mojo/edk/js/handle_close_observer.h" -#include "mojo/public/c/environment/async_waiter.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -namespace js { - -class WaitingCallback : public gin::Wrappable<WaitingCallback>, - public HandleCloseObserver { - public: - static gin::WrapperInfo kWrapperInfo; - - // Creates a new WaitingCallback. - static gin::Handle<WaitingCallback> Create( - v8::Isolate* isolate, - v8::Handle<v8::Function> callback, - gin::Handle<HandleWrapper> handle_wrapper, - MojoHandleSignals signals); - - // Cancels the callback. Does nothing if a callback is not pending. This is - // implicitly invoked from the destructor but can be explicitly invoked as - // necessary. - void Cancel(); - - private: - WaitingCallback(v8::Isolate* isolate, - v8::Handle<v8::Function> callback, - gin::Handle<HandleWrapper> handle_wrapper); - ~WaitingCallback() override; - - // Callback from MojoAsyncWaiter. |closure| is the WaitingCallback. - static void CallOnHandleReady(void* closure, MojoResult result); - - // Invoked from CallOnHandleReady() (CallOnHandleReady() must be static). - void OnHandleReady(MojoResult result); - - // Invoked by the HandleWrapper if the handle is closed while this wait is - // still in progress. - void OnWillCloseHandle() override; - - void ClearWaitId(); - void CallCallback(MojoResult result); - - base::WeakPtr<gin::Runner> runner_; - MojoAsyncWaitID wait_id_; - - HandleWrapper* handle_wrapper_; - base::WeakPtrFactory<WaitingCallback> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(WaitingCallback); -}; - -} // namespace js -} // namespace mojo - -#endif // MOJO_EDK_JS_WAITING_CALLBACK_H_ |