diff options
author | aa <aa@chromium.org> | 2014-10-30 17:56:01 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-31 00:56:23 +0000 |
commit | a158c0118feb755acff2d601bf436072ef4d90e5 (patch) | |
tree | e8146587f3f85f69a03be66f2f2753d5752b528b /mojo | |
parent | e6e040a21c78c9097600312d761c0295fa9312f1 (diff) | |
download | chromium_src-a158c0118feb755acff2d601bf436072ef4d90e5.zip chromium_src-a158c0118feb755acff2d601bf436072ef4d90e5.tar.gz chromium_src-a158c0118feb755acff2d601bf436072ef4d90e5.tar.bz2 |
Update mojo sdk to rev e083961bf11fd0c94d40be8853761da529b6d444
This relands https://codereview.chromium.org/683583002/
TBR=jamesr@chromium.org
Review URL: https://codereview.chromium.org/695583002
Cr-Commit-Position: refs/heads/master@{#302203}
Diffstat (limited to 'mojo')
55 files changed, 1344 insertions, 187 deletions
diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc index 0318f2f..ac20056 100644 --- a/mojo/edk/system/channel_endpoint.cc +++ b/mojo/edk/system/channel_endpoint.cc @@ -65,34 +65,6 @@ void ChannelEndpoint::DetachFromMessagePipe() { } } -void ChannelEndpoint::AttachToChannel(Channel* channel, - ChannelEndpointId local_id) { - DCHECK(channel); - DCHECK(local_id.is_valid()); - - base::AutoLock locker(lock_); - DCHECK(!channel_); - DCHECK(!local_id_.is_valid()); - channel_ = channel; - local_id_ = local_id; -} - -void ChannelEndpoint::Run(ChannelEndpointId remote_id) { - DCHECK(remote_id.is_valid()); - - base::AutoLock locker(lock_); - if (!channel_) - return; - - DCHECK(!remote_id_.is_valid()); - remote_id_ = remote_id; - - while (!paused_message_queue_.IsEmpty()) { - LOG_IF(WARNING, !WriteMessageNoLock(paused_message_queue_.GetMessage())) - << "Failed to write enqueue message to channel"; - } -} - void ChannelEndpoint::AttachAndRun(Channel* channel, ChannelEndpointId local_id, ChannelEndpointId remote_id) { diff --git a/mojo/edk/system/channel_endpoint.h b/mojo/edk/system/channel_endpoint.h index 5650c2f..5953ce5 100644 --- a/mojo/edk/system/channel_endpoint.h +++ b/mojo/edk/system/channel_endpoint.h @@ -131,10 +131,6 @@ class MOJO_SYSTEM_IMPL_EXPORT ChannelEndpoint // Methods called by |Channel|: - // TODO(vtl): Remove these once we've switched over to |AttachAndRun()|. - void AttachToChannel(Channel* channel, ChannelEndpointId local_id); - void Run(ChannelEndpointId remote_id); - // Called by |Channel| when it takes a reference to this object. It will send // all queue messages (in |paused_message_queue_|). // TODO(vtl): Maybe rename this "OnAttach"? diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc index 6f653d9..f676c7f 100644 --- a/mojo/edk/system/remote_message_pipe_unittest.cc +++ b/mojo/edk/system/remote_message_pipe_unittest.cc @@ -479,6 +479,73 @@ TEST_F(RemoteMessagePipeTest, Multiplex) { mp3->Close(0); } +TEST_F(RemoteMessagePipeTest, CloseBeforeAttachAndRun) { + static const char kHello[] = "hello"; + char buffer[100] = {0}; + uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); + Waiter waiter; + HandleSignalsState hss; + uint32_t context = 0; + + // Connect message pipes. MP 0, port 1 will be attached to channel 0 and + // connected to MP 1, port 0, which will be attached to channel 1. This leaves + // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints. + + scoped_refptr<ChannelEndpoint> ep0; + scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0)); + + // Write to MP 0, port 0. + EXPECT_EQ(MOJO_RESULT_OK, + mp0->WriteMessage(0, + UserPointer<const void>(kHello), + sizeof(kHello), + nullptr, + MOJO_WRITE_MESSAGE_FLAG_NONE)); + + // Close MP 0, port 0 before it's even been attached to the channel and run. + mp0->Close(0); + + BootstrapChannelEndpointNoWait(0, ep0); + + scoped_refptr<ChannelEndpoint> ep1; + scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1)); + + // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do + // it later, it might already be readable.) + waiter.Init(); + ASSERT_EQ( + MOJO_RESULT_OK, + mp1->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr)); + + BootstrapChannelEndpointNoWait(1, ep1); + + // Wait. + EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context)); + EXPECT_EQ(123u, context); + hss = HandleSignalsState(); + // Note: MP 1, port 1 should definitely should be readable, but it may or may + // not appear as writable (there's a race, and it may not have noticed that + // the other side was closed yet -- e.g., inserting a sleep here would make it + // much more likely to notice that it's no longer writable). + mp1->RemoveWaiter(1, &waiter, &hss); + EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE)); + EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE)); + + // Read from MP 1, port 1. + EXPECT_EQ(MOJO_RESULT_OK, + mp1->ReadMessage(1, + UserPointer<void>(buffer), + MakeUserPointer(&buffer_size), + nullptr, + nullptr, + MOJO_READ_MESSAGE_FLAG_NONE)); + EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size)); + EXPECT_STREQ(kHello, buffer); + + // And MP 1, port 1. + mp1->Close(1); +} + TEST_F(RemoteMessagePipeTest, CloseBeforeConnect) { static const char kHello[] = "hello"; char buffer[100] = {0}; diff --git a/mojo/public/BUILD.gn b/mojo/public/BUILD.gn index 5aa0de2..b661383 100644 --- a/mojo/public/BUILD.gn +++ b/mojo/public/BUILD.gn @@ -38,6 +38,7 @@ group("sdk") { "//mojo/public/cpp/environment:standalone", "//mojo/public/cpp/utility", "//mojo/public/interfaces/application", + "//mojo/public/js/bindings", ] } diff --git a/mojo/public/VERSION b/mojo/public/VERSION index e43242f..a01bc1f 100644 --- a/mojo/public/VERSION +++ b/mojo/public/VERSION @@ -1 +1 @@ -e0416d1cfdcc669756d29802aa8644586273f5c7
\ No newline at end of file +adfaabce5ababa65f5df2becab1d589d290f0fab
\ No newline at end of file diff --git a/mojo/public/cpp/application/BUILD.gn b/mojo/public/cpp/application/BUILD.gn index c7f0da6..3bfbb62 100644 --- a/mojo/public/cpp/application/BUILD.gn +++ b/mojo/public/cpp/application/BUILD.gn @@ -45,3 +45,16 @@ source_set("standalone") { "//mojo/public/cpp/utility", ] } + +source_set("test_support") { + testonly = true + deps = [ + ":application", + "//testing/gtest", + ] + + sources = [ + "application_test_base.h", + "lib/application_test_base.cc", + ] +} diff --git a/mojo/public/cpp/application/DEPS b/mojo/public/cpp/application/DEPS index a59df1d..503eebc 100644 --- a/mojo/public/cpp/application/DEPS +++ b/mojo/public/cpp/application/DEPS @@ -4,3 +4,8 @@ include_rules = [ "+mojo/public/interfaces/application", "+mojo/public/interfaces/service_provider", ] +specific_include_rules = { + r"application_test_base\.h": [ + "+testing/gtest/include/gtest", + ], +}
\ No newline at end of file diff --git a/mojo/public/cpp/application/application_impl.h b/mojo/public/cpp/application/application_impl.h index f4febd5..dbc8554d 100644 --- a/mojo/public/cpp/application/application_impl.h +++ b/mojo/public/cpp/application/application_impl.h @@ -61,6 +61,7 @@ class ApplicationImpl : public InterfaceImpl<Application> { // Returns any initial configuration arguments, passed by the Shell. const std::vector<std::string>& args() const { return args_; } + bool HasArg(const std::string& arg) const; // Establishes a new connection to an application. Caller does not own. ApplicationConnection* ConnectToApplication(const String& application_url); diff --git a/mojo/public/cpp/application/application_test_base.h b/mojo/public/cpp/application/application_test_base.h new file mode 100644 index 0000000..7fe38d2 --- /dev/null +++ b/mojo/public/cpp/application/application_test_base.h @@ -0,0 +1,50 @@ +// 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_PUBLIC_CPP_APPLICATION_APPLICATION_TEST_BASE_H_ +#define MOJO_PUBLIC_CPP_APPLICATION_APPLICATION_TEST_BASE_H_ + +#include "mojo/public/cpp/bindings/array.h" +#include "mojo/public/cpp/bindings/string.h" +#include "mojo/public/cpp/system/macros.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { + +class ApplicationDelegate; +class ApplicationImpl; + +namespace test { + +// A GTEST base class for application testing executed in mojo_shell. +class ApplicationTestBase : public testing::Test { + public: + explicit ApplicationTestBase(Array<String> args); + ~ApplicationTestBase() override; + + protected: + ApplicationImpl* application_impl() { return application_impl_; } + + // Get the ApplicationDelegate for the application to be tested. + virtual ApplicationDelegate* GetApplicationDelegate() = 0; + + // testing::Test: + void SetUp() override; + void TearDown() override; + + private: + // The command line arguments supplied to each test application instance. + Array<String> args_; + + // The application implementation instance, reconstructed for each test. + ApplicationImpl* application_impl_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ApplicationTestBase); +}; + +} // namespace test + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_APPLICATION_APPLICATION_TEST_BASE_H_ diff --git a/mojo/public/cpp/application/lib/DEPS b/mojo/public/cpp/application/lib/DEPS index 4ed133f1..5b15979 100644 --- a/mojo/public/cpp/application/lib/DEPS +++ b/mojo/public/cpp/application/lib/DEPS @@ -1,5 +1,8 @@ specific_include_rules = { r"application_runner\.cc": [ - "+mojo/public/cpp/utility" + "+mojo/public/cpp/utility", + ], + r"application_test_base\.cc": [ + "+mojo/public/cpp/utility", ], } diff --git a/mojo/public/cpp/application/lib/application_impl.cc b/mojo/public/cpp/application/lib/application_impl.cc index 30b04e9..18c78b0 100644 --- a/mojo/public/cpp/application/lib/application_impl.cc +++ b/mojo/public/cpp/application/lib/application_impl.cc @@ -36,6 +36,10 @@ ApplicationImpl::ApplicationImpl(ApplicationDelegate* delegate, BindShell(MakeScopedHandle(MessagePipeHandle(shell_handle))); } +bool ApplicationImpl::HasArg(const std::string& arg) const { + return std::find(args_.begin(), args_.end(), arg) != args_.end(); +} + void ApplicationImpl::ClearConnections() { for (ServiceRegistryList::iterator i(incoming_service_registries_.begin()); i != incoming_service_registries_.end(); diff --git a/mojo/public/cpp/application/lib/application_test_base.cc b/mojo/public/cpp/application/lib/application_test_base.cc new file mode 100644 index 0000000..76e1c95 --- /dev/null +++ b/mojo/public/cpp/application/lib/application_test_base.cc @@ -0,0 +1,94 @@ +// 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/public/cpp/application/application_test_base.h" + +#include "mojo/public/c/system/main.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" +#include "mojo/public/cpp/environment/logging.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "mojo/public/cpp/utility/lib/thread_local.h" +#include "mojo/public/cpp/utility/run_loop.h" + +namespace mojo { +namespace test { + +namespace { + +// This global shell handle is needed for repeated use by test applications. +MessagePipeHandle test_shell_handle; + +// TODO(msw): Support base::MessageLoop environments. +internal::ThreadLocalPointer<RunLoop> test_run_loop; + +} // namespace + +ApplicationTestBase::ApplicationTestBase(Array<String> args) + : args_(args.Pass()), application_impl_(nullptr) { +} + +ApplicationTestBase::~ApplicationTestBase() { +} + +void ApplicationTestBase::SetUp() { + // A run loop is needed for ApplicationImpl initialization and communication. + test_run_loop.Set(new RunLoop()); + + // New applications are constructed for each test to avoid persisting state. + MOJO_CHECK(test_shell_handle.is_valid()); + application_impl_ = new ApplicationImpl(GetApplicationDelegate(), + MakeScopedHandle(test_shell_handle)); + + // Fake application initialization with the given command line arguments. + application_impl_->Initialize(args_.Clone()); +} + +void ApplicationTestBase::TearDown() { + test_shell_handle = application_impl_->UnbindShell().release(); + delete application_impl_; + delete test_run_loop.Get(); + test_run_loop.Set(nullptr); +} + +} // namespace test +} // namespace mojo + +// TODO(msw): Split this into an application_test_main.cc. +MojoResult MojoMain(MojoHandle shell_handle) { + mojo::Environment environment; + + { + // This RunLoop is used for init, and then destroyed before running tests. + mojo::RunLoop run_loop; + + // Construct an ApplicationImpl just for the GTEST commandline arguments. + // GTEST command line arguments are supported amid application arguments: + // $ mojo_shell 'mojo:example_apptest arg1 --gtest_filter=foo arg2' + mojo::ApplicationDelegate dummy_application_delegate; + mojo::ApplicationImpl app(&dummy_application_delegate, shell_handle); + MOJO_CHECK(app.WaitForInitialize()); + + // InitGoogleTest expects (argc + 1) elements, including a terminating NULL. + // It also removes GTEST arguments from |argv| and updates the |argc| count. + // TODO(msw): Provide tests access to these actual command line arguments. + const std::vector<std::string>& args = app.args(); + MOJO_CHECK(args.size() < + static_cast<size_t>(std::numeric_limits<int>::max())); + int argc = static_cast<int>(args.size()); + std::vector<const char*> argv(argc + 1); + for (int i = 0; i < argc; ++i) + argv[i] = args[i].c_str(); + argv[argc] = nullptr; + testing::InitGoogleTest(&argc, const_cast<char**>(&(argv[0]))); + mojo::test::test_shell_handle = app.UnbindShell().release(); + } + + int result = RUN_ALL_TESTS(); + + MojoResult close_result = MojoClose(mojo::test::test_shell_handle.value()); + MOJO_CHECK(close_result == MOJO_RESULT_OK); + + return (result == 0) ? MOJO_RESULT_OK : MOJO_RESULT_UNKNOWN; +} diff --git a/mojo/public/gles2/BUILD.gn b/mojo/public/gles2/BUILD.gn index 725b146..5c21e78 100644 --- a/mojo/public/gles2/BUILD.gn +++ b/mojo/public/gles2/BUILD.gn @@ -18,7 +18,11 @@ group("for_shared_library") { public_configs = [ "//third_party/khronos:khronos_headers" ] public_deps = [ "//mojo/public/c/gles2" ] - deps = [ "//mojo/public/platform/native:gles2_thunks" ] + if (is_component_build) { + deps = [ "//mojo/gles2" ] + } else { + deps = [ "//mojo/public/platform/native:gles2_thunks" ] + } } group("for_component") { diff --git a/mojo/public/go/system/core.go b/mojo/public/go/system/core.go index d8735ae..cf6ae99 100644 --- a/mojo/public/go/system/core.go +++ b/mojo/public/go/system/core.go @@ -4,18 +4,76 @@ package system -import "mojo/public/go/system/impl" +import ( + "unsafe" + t "mojo/public/go/system/impl" +) + +// Core is an interface that defines the set of Mojo system APIs. type Core interface { - GetTimeTicksNow() int64 -} + // GetTimeTicksNow returns a monotonically increasing platform + // dependent tick count representing "right now". Resolution + // depends on the systemconfiguration. + GetTimeTicksNow() t.MojoTimeTicks -var core *impl.CoreImpl + // Close closes the given handle. + Close(handle t.MojoHandle) (result t.MojoResult) -func init() { - core = &impl.CoreImpl{} -} + // Wait waits on the given handle until a signal indicated by signals + // is satisfied or it becomes known that no signal indicated by + // signals will ever be satisified or until deadline has passed. + Wait(handle t.MojoHandle, signal t.MojoHandleSignals, deadline t.MojoDeadline) (result t.MojoResult) + + // WaitMany behaves as if Wait were called on each handle/signal pair + // simultaneously and completing when the first Wait would complete. + WaitMany(handles []t.MojoHandle, signals []t.MojoHandleSignals, deadline t.MojoDeadline) (result t.MojoResult) + + // CreateMessagePipe creates a message pipe which is a bidirectional + // communication channel for framed data (i.e., messages). Messages + // can contain plain data and/or Mojo handles. On success, it returns + // handles to the two endpoints of the message pipe. + CreateMessagePipe(opts *t.MessagePipeOptions) (result t.MojoResult, handle0 t.MojoHandle, handle1 t.MojoHandle) + + // WriteMessage writes message data and optional attached handles to + // the message pipe endpoint given by handle. On success the attached + // handles will no longer be valid (ie: the receiver will receive + // equivalent but logically different handles). + WriteMessage(handle t.MojoHandle, msg []byte, attached []t.MojoHandle, flags t.MojoWriteMessageFlags) (result t.MojoResult) + + // ReadMessage reads a message from the message pipe endpoint given + // by handle with the specified flags. Returns the message data and + // attached handles that were received and the number of bytes and + // attached handles in the "next" message. + ReadMessage(handle t.MojoHandle, flags t.MojoReadMessageFlags) (result t.MojoResult, msg []byte, attached []t.MojoHandle, numBytes uint32, numHandles uint32) -func GetCore() Core { - return core -}
\ No newline at end of file + // CreateDataPipe creates a data pipe which is a unidirectional + // communication channel for unframed data. On success, returns a + // handle to the producer and consumer of the data pipe. + CreateDataPipe(opts *t.DataPipeOptions) (result t.MojoResult, producer t.MojoHandle, consumer t.MojoHandle) + + // WriteData writes data to the data pipe producer handle with the + // given flags. On success, returns the number of bytes that were + // actually written. + WriteData(producer t.MojoHandle, data []byte, flags t.MojoWriteDataFlags) (result t.MojoResult, numBytes uint32) + + // ReadData reads data from the data pipe consumer handle with the + // given flags. On success, returns the data that was read. + ReadData(consumer t.MojoHandle, flags t.MojoReadDataFlags) (result t.MojoResult, data []byte) + + // CreateSharedBuffer creates a buffer of size numBytes that can be + // shared between applications. One must call MapBuffer to access + // the buffer. + CreateSharedBuffer(opts *t.SharedBufferOptions, numBytes uint64) (result t.MojoResult, handle t.MojoHandle) + + // DuplicateBufferHandle duplicates the handle to a buffer. + DuplicateBufferHandle(handle t.MojoHandle, opts *t.DuplicateBufferHandleOptions) (result t.MojoResult, duplicate t.MojoHandle) + + // MapBuffer maps the requested part of the shared buffer given by + // handle into memory with specified flags. On success, it returns + // a pointer to the requested shared buffer. + MapBuffer(handle t.MojoHandle, offset uint64, numBytes uint64, flags t.MojoMapBufferFlags) (result t.MojoResult, buffer unsafe.Pointer) + + // UnmapBuffer unmaps a buffer pointer that was returned by MapBuffer. + UnmapBuffer(buffer unsafe.Pointer) (result t.MojoResult) +} diff --git a/mojo/public/go/system/impl/core_impl.go b/mojo/public/go/system/impl/core_impl.go index b269583..601ebd2 100644 --- a/mojo/public/go/system/impl/core_impl.go +++ b/mojo/public/go/system/impl/core_impl.go @@ -7,10 +7,103 @@ package impl //#include "mojo/public/platform/native/system_thunks.h" //#include "mojo/public/c/system/main.h" import "C" +import "unsafe" +var core *CoreImpl + +func init() { + core = &CoreImpl{} +} + +// CoreImpl is an implementation of the Mojo system APIs. type CoreImpl struct { } -func (c *CoreImpl) GetTimeTicksNow() int64 { - return (int64)(C.MojoGetTimeTicksNow()) +func GetCore() *CoreImpl { + return core +} + +func (c *CoreImpl) GetTimeTicksNow() MojoTimeTicks { + return (MojoTimeTicks)(C.MojoGetTimeTicksNow()) +} + +func (c *CoreImpl) Close(handle MojoHandle) MojoResult { + return (MojoResult)(C.MojoClose(handle.cType())) +} + +func (c *CoreImpl) Wait(handle MojoHandle, signal MojoHandleSignals, deadline MojoDeadline) MojoResult { + return (MojoResult)(C.MojoWait(handle.cType(), signal.cType(), deadline.cType())) +} + +func (c *CoreImpl) WaitMany(handles []MojoHandle, signals []MojoHandleSignals, deadline MojoDeadline) MojoResult { + return (MojoResult)(C.MojoWaitMany(cArrayMojoHandle(handles), cArrayMojoHandleSignals(signals), (C.uint32_t)(len(handles)), deadline.cType())) +} + +func (c *CoreImpl) CreateMessagePipe(opts *MessagePipeOptions) (MojoResult, MojoHandle, MojoHandle) { + var handle0, handle1 C.MojoHandle + result := C.MojoCreateMessagePipe(opts.cType(), &handle0, &handle1) + return (MojoResult)(result), (MojoHandle)(handle0), (MojoHandle)(handle1) +} + +func (c *CoreImpl) WriteMessage(handle MojoHandle, msg []byte, attached []MojoHandle, flags MojoWriteMessageFlags) MojoResult { + return (MojoResult)(C.MojoWriteMessage(handle.cType(), cArrayBytes(msg), (C.uint32_t)(len(msg)), cArrayMojoHandle(attached), (C.uint32_t)(len(attached)), flags.cType())) +} + +func (c *CoreImpl) ReadMessage(handle MojoHandle, flags MojoReadMessageFlags) (MojoResult, []byte, []MojoHandle, uint32, uint32) { + var num_bytes, num_handles C.uint32_t + if result := C.MojoReadMessage(handle.cType(), nil, &num_bytes, nil, &num_handles, flags.cType()); result != C.MOJO_RESULT_RESOURCE_EXHAUSTED { + return (MojoResult)(result), nil, nil, 0, 0 + } + msg := make([]byte, (uint32)(num_bytes)) + attached := make([]MojoHandle, (uint32)(num_handles)) + result := C.MojoReadMessage(handle.cType(), cArrayBytes(msg), &num_bytes, cArrayMojoHandle(attached), &num_handles, (C.MojoReadMessageFlags)(flags)) + return (MojoResult)(result), msg, attached, (uint32)(num_bytes), (uint32)(num_handles) +} + +func (c *CoreImpl) CreateDataPipe(opts *DataPipeOptions) (MojoResult, MojoHandle, MojoHandle) { + var producer, consumer C.MojoHandle + result := C.MojoCreateDataPipe(opts.cType(), &producer, &consumer) + return (MojoResult)(result), (MojoHandle)(producer), (MojoHandle)(consumer) +} + +func (c *CoreImpl) WriteData(producer MojoHandle, data []byte, flags MojoWriteDataFlags) (MojoResult, uint32) { + num_bytes := (C.uint32_t)(len(data)) + result := C.MojoWriteData(producer.cType(), cArrayBytes(data), &num_bytes, flags.cType()) + return (MojoResult)(result), (uint32)(num_bytes) +} + +func (c *CoreImpl) ReadData(consumer MojoHandle, flags MojoReadDataFlags) (MojoResult, []byte) { + var num_bytes C.uint32_t + var result C.MojoResult + if result = C.MojoReadData(consumer.cType(), nil, &num_bytes, C.MOJO_READ_DATA_FLAG_QUERY); result != C.MOJO_RESULT_OK { + return (MojoResult)(result), nil + } + data := make([]byte, (uint32)(num_bytes)) + result = C.MojoReadData(consumer.cType(), cArrayBytes(data), &num_bytes, flags.cType()) + return (MojoResult)(result), data +} + +func (c *CoreImpl) CreateSharedBuffer(opts *SharedBufferOptions, numBytes uint64) (MojoResult, MojoHandle) { + var handle C.MojoHandle + result := C.MojoCreateSharedBuffer(opts.cType(), (C.uint64_t)(numBytes), &handle) + return (MojoResult)(result), (MojoHandle)(handle) +} + +func (c *CoreImpl) DuplicateBufferHandle(handle MojoHandle, opts *DuplicateBufferHandleOptions) (MojoResult, MojoHandle) { + var duplicate C.MojoHandle + result := C.MojoDuplicateBufferHandle(handle.cType(), opts.cType(), &duplicate) + return (MojoResult)(result), (MojoHandle)(duplicate) +} + +func (c *CoreImpl) MapBuffer(handle MojoHandle, offset uint64, numBytes uint64, flags MojoMapBufferFlags) (MojoResult, unsafe.Pointer) { + var bufPtr unsafe.Pointer + result := C.MojoMapBuffer(handle.cType(), (C.uint64_t)(offset), (C.uint64_t)(numBytes), &bufPtr, flags.cType()) + if result != C.MOJO_RESULT_OK { + return (MojoResult)(result), nil + } + return MOJO_RESULT_OK, bufPtr +} + +func (c *CoreImpl) UnmapBuffer(buffer unsafe.Pointer) MojoResult { + return (MojoResult)(C.MojoUnmapBuffer(buffer)) } diff --git a/mojo/public/go/system/impl/mojo_types.go b/mojo/public/go/system/impl/mojo_types.go new file mode 100644 index 0000000..9156a45 --- /dev/null +++ b/mojo/public/go/system/impl/mojo_types.go @@ -0,0 +1,212 @@ +// 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. + +package impl + +//#include "mojo/public/platform/native/system_thunks.h" +//#include "mojo/public/c/system/main.h" +import "C" +import ( + "math" + "unsafe" +) + +// Go equivalent definitions of the various system types defined in Mojo. +// mojo/public/c/system/types.h +// mojo/public/c/system/data_pipe.h +// mojo/public/c/system/message_pipe.h +// +type MojoTimeTicks int64 +type MojoHandle uint32 +type MojoResult int32 +type MojoDeadline uint64 +type MojoHandleSignals uint32 +type MojoWriteMessageFlags uint32 +type MojoReadMessageFlags uint32 +type MojoWriteDataFlags uint32 +type MojoReadDataFlags uint32 +type MojoCreateDataPipeOptionsFlags uint32 +type MojoCreateMessagePipeOptionsFlags uint32 +type MojoCreateSharedBufferOptionsFlags uint32 +type MojoDuplicateBufferHandleOptionsFlags uint32 +type MojoMapBufferFlags uint32 + +const ( + MOJO_DEADLINE_INDEFINITE MojoDeadline = math.MaxUint64 + MOJO_HANDLE_INVALID MojoHandle = 0 + MOJO_RESULT_OK MojoResult = 0 + MOJO_RESULT_CANCELLED = -1 + MOJO_RESULT_UNKNOWN = -2 + MOJO_RESULT_INVALID_ARGUMENT = -3 + MOJO_RESULT_DEADLINE_EXCEEDED = -4 + MOJO_RESULT_NOT_FOUND = -5 + MOJO_RESULT_ALREADY_EXISTS = -6 + MOJO_RESULT_PERMISSION_DENIED = -7 + MOJO_RESULT_RESOURCE_EXHAUSTED = -8 + MOJO_RESULT_FAILED_PRECONDITION = -9 + MOJO_RESULT_ABORTED = -10 + MOJO_RESULT_OUT_OF_RANGE = -11 + MOJO_RESULT_UNIMPLEMENTED = -12 + MOJO_RESULT_INTERNAL = -13 + MOJO_RESULT_UNAVAILABLE = -14 + MOJO_RESULT_DATA_LOSS = -15 + MOJO_RESULT_BUSY = -16 + MOJO_RESULT_SHOULD_WAIT = -17 + + MOJO_HANDLE_SIGNAL_NONE MojoHandleSignals = 0 + MOJO_HANDLE_SIGNAL_READABLE = 1 << 0 + MOJO_HANDLE_SIGNAL_WRITABLE = 1 << 1 + + MOJO_WRITE_MESSAGE_FLAG_NONE MojoWriteMessageFlags = 0 + MOJO_READ_MESSAGE_FLAG_NONE MojoReadMessageFlags = 0 + MOJO_READ_MESSAGE_FLAG_MAY_DISCARD = 1 << 0 + + MOJO_READ_DATA_FLAG_NONE MojoReadDataFlags = 0 + MOJO_READ_DATA_FLAG_ALL_OR_NONE = 1 << 0 + MOJO_READ_DATA_FLAG_DISCARD = 1 << 1 + MOJO_READ_DATA_FLAG_QUERY = 1 << 2 + MOJO_WRITE_DATA_FLAG_NONE MojoWriteDataFlags = 0 + MOJO_WRITE_DATA_FLAG_ALL_OR_NONE MojoWriteDataFlags = 1 << 0 + + MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE MojoCreateDataPipeOptionsFlags = 0 + MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD = 1 << 0 + MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE MojoCreateMessagePipeOptionsFlags = 0 + + MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE MojoCreateSharedBufferOptionsFlags = 0 + MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE MojoDuplicateBufferHandleOptionsFlags = 0 + MOJO_MAP_BUFFER_FLAG_NONE MojoMapBufferFlags = 0 +) + +// DataPipeOptions is used to specify creation parameters for a data pipe. +type DataPipeOptions struct { + flags MojoCreateDataPipeOptionsFlags + // The size of an element in bytes. All transactions and buffers will + // be an integral number of elements. + elemSize uint32 + // The capacity of the data pipe in bytes. Must be a multiple of elemSize. + capacity uint32 +} + +func (opts *DataPipeOptions) cType() *C.struct_MojoCreateDataPipeOptions { + if opts == nil { + return nil + } + var cOpts C.struct_MojoCreateDataPipeOptions + cOpts = C.struct_MojoCreateDataPipeOptions{ + (C.uint32_t)(unsafe.Sizeof(cOpts)), + opts.flags.cType(), + (C.uint32_t)(opts.elemSize), + (C.uint32_t)(opts.capacity), + } + return &cOpts +} + +// MessagePipeOptions is used to specify creation parameters for a message pipe. +type MessagePipeOptions struct { + flags MojoCreateMessagePipeOptionsFlags +} + +func (opts *MessagePipeOptions) cType() *C.struct_MojoCreateMessagePipeOptions { + if opts == nil { + return nil + } + var cOpts C.struct_MojoCreateMessagePipeOptions + cOpts = C.struct_MojoCreateMessagePipeOptions{ + (C.uint32_t)(unsafe.Sizeof(cOpts)), + opts.flags.cType(), + } + return &cOpts +} + +// SharedBufferOptions is used to specify creation parameters for a +// shared buffer. +type SharedBufferOptions struct { + flags MojoCreateSharedBufferOptionsFlags +} + +func (opts *SharedBufferOptions) cType() *C.struct_MojoCreateSharedBufferOptions { + if opts == nil { + return nil + } + var cOpts C.struct_MojoCreateSharedBufferOptions + cOpts = C.struct_MojoCreateSharedBufferOptions{ + (C.uint32_t)(unsafe.Sizeof(cOpts)), + opts.flags.cType(), + } + return &cOpts +} + +// DuplicateBufferHandleOptions is used to specify parameters in +// duplicating access to a shared buffer. +type DuplicateBufferHandleOptions struct { + flags MojoDuplicateBufferHandleOptionsFlags +} + +func (opts *DuplicateBufferHandleOptions) cType() *C.struct_MojoDuplicateBufferHandleOptions { + if opts == nil { + return nil + } + var cOpts C.struct_MojoDuplicateBufferHandleOptions + cOpts = C.struct_MojoDuplicateBufferHandleOptions{ + (C.uint32_t)(unsafe.Sizeof(cOpts)), + opts.flags.cType(), + } + return &cOpts +} + +// Convenience functions to convert Go types to their equivalent C types. +func (m MojoHandle) cType() C.MojoHandle { + return (C.MojoHandle)(m) +} +func (m MojoDeadline) cType() C.MojoDeadline { + return (C.MojoDeadline)(m) +} +func (m MojoHandleSignals) cType() C.MojoHandleSignals { + return (C.MojoHandleSignals)(m) +} +func (m MojoWriteMessageFlags) cType() C.MojoWriteMessageFlags { + return (C.MojoWriteMessageFlags)(m) +} +func (m MojoReadMessageFlags) cType() C.MojoReadMessageFlags { + return (C.MojoReadMessageFlags)(m) +} +func (m MojoWriteDataFlags) cType() C.MojoWriteDataFlags { + return (C.MojoWriteDataFlags)(m) +} +func (m MojoReadDataFlags) cType() C.MojoReadDataFlags { + return (C.MojoReadDataFlags)(m) +} +func (m MojoCreateDataPipeOptionsFlags) cType() C.MojoCreateDataPipeOptionsFlags { + return (C.MojoCreateDataPipeOptionsFlags)(m) +} +func (m MojoCreateMessagePipeOptionsFlags) cType() C.MojoCreateMessagePipeOptionsFlags { + return (C.MojoCreateMessagePipeOptionsFlags)(m) +} +func (m MojoCreateSharedBufferOptionsFlags) cType() C.MojoCreateSharedBufferOptionsFlags { + return (C.MojoCreateSharedBufferOptionsFlags)(m) +} +func (m MojoDuplicateBufferHandleOptionsFlags) cType() C.MojoDuplicateBufferHandleOptionsFlags { + return (C.MojoDuplicateBufferHandleOptionsFlags)(m) +} +func (m MojoMapBufferFlags) cType() C.MojoMapBufferFlags { + return (C.MojoMapBufferFlags)(m) +} +func cArrayMojoHandle(m []MojoHandle) *C.MojoHandle { + if len(m) == 0 { + return nil + } + return (*C.MojoHandle)(&m[0]) +} +func cArrayMojoHandleSignals(m []MojoHandleSignals) *C.MojoHandleSignals { + if len(m) == 0 { + return nil + } + return (*C.MojoHandleSignals)(&m[0]) +} +func cArrayBytes(m []byte) unsafe.Pointer { + if len(m) == 0 { + return nil + } + return unsafe.Pointer(&m[0]) +} diff --git a/mojo/public/interfaces/application/application.mojom b/mojo/public/interfaces/application/application.mojom index 84417be..67e14d7 100644 --- a/mojo/public/interfaces/application/application.mojom +++ b/mojo/public/interfaces/application/application.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/application/service_provider.mojom" +import "mojo/public/interfaces/application/service_provider.mojom"; module mojo { diff --git a/mojo/public/interfaces/application/shell.mojom b/mojo/public/interfaces/application/shell.mojom index 014fa3d..72e1764 100644 --- a/mojo/public/interfaces/application/shell.mojom +++ b/mojo/public/interfaces/application/shell.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/application/application.mojom" -import "mojo/public/interfaces/application/service_provider.mojom" +import "mojo/public/interfaces/application/application.mojom"; +import "mojo/public/interfaces/application/service_provider.mojom"; module mojo { diff --git a/mojo/public/interfaces/bindings/tests/sample_factory.mojom b/mojo/public/interfaces/bindings/tests/sample_factory.mojom index 567cf23..b818921 100644 --- a/mojo/public/interfaces/bindings/tests/sample_factory.mojom +++ b/mojo/public/interfaces/bindings/tests/sample_factory.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "sample_import.mojom" +import "sample_import.mojom"; [JavaPackage="org.chromium.mojo.bindings.test.mojom.sample"] module sample { diff --git a/mojo/public/interfaces/bindings/tests/sample_import2.mojom b/mojo/public/interfaces/bindings/tests/sample_import2.mojom index 63ddb5a..04c77ed 100644 --- a/mojo/public/interfaces/bindings/tests/sample_import2.mojom +++ b/mojo/public/interfaces/bindings/tests/sample_import2.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "sample_import.mojom" +import "sample_import.mojom"; [JavaPackage="org.chromium.mojo.bindings.test.mojom.imported"] module imported { diff --git a/mojo/public/interfaces/bindings/tests/sample_service.mojom b/mojo/public/interfaces/bindings/tests/sample_service.mojom index baf03de..f01d1c2 100644 --- a/mojo/public/interfaces/bindings/tests/sample_service.mojom +++ b/mojo/public/interfaces/bindings/tests/sample_service.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "sample_import.mojom" -import "sample_import2.mojom" +import "sample_import.mojom"; +import "sample_import2.mojom"; [JavaPackage="org.chromium.mojo.bindings.test.mojom.sample"] module sample { diff --git a/mojo/public/interfaces/bindings/tests/test_structs.mojom b/mojo/public/interfaces/bindings/tests/test_structs.mojom index 2063149..3216caf 100644 --- a/mojo/public/interfaces/bindings/tests/test_structs.mojom +++ b/mojo/public/interfaces/bindings/tests/test_structs.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/bindings/tests/rect.mojom" +import "mojo/public/interfaces/bindings/tests/rect.mojom"; [JavaPackage="org.chromium.mojo.bindings.test.mojom.test_structs"] module mojo.test { diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java index d97547f..01cddc4 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/BindingsHelper.java @@ -110,6 +110,64 @@ public class BindingsHelper { } /** + * Returns |true| if and only if the two objects are equals, handling |null|. + */ + public static boolean equals(Object o1, Object o2) { + if (o1 == o2) { + return true; + } + if (o1 == null) { + return false; + } + return o1.equals(o2); + } + + /** + * Returns the hash code of the object, handling |null|. + */ + public static int hashCode(Object o) { + if (o == null) { + return 0; + } + return o.hashCode(); + } + + /** + * Returns the hash code of the value. + */ + public static int hashCode(boolean o) { + return o ? 1231 : 1237; + } + + /** + * Returns the hash code of the value. + */ + public static int hashCode(long o) { + return (int) (o ^ (o >>> 32)); + } + + /** + * Returns the hash code of the value. + */ + public static int hashCode(float o) { + return Float.floatToIntBits(o); + } + + /** + * Returns the hash code of the value. + */ + public static int hashCode(double o) { + return hashCode(Double.doubleToLongBits(o)); + } + + /** + * Returns the hash code of the value. + */ + public static int hashCode(int o) { + return o; + } + + /** * Determines if the given {@code char} value is a Unicode <i>surrogate code unit</i>. See * {@link Character#isSurrogate}. Extracting here because the method only exists at API level * 19. @@ -119,8 +177,7 @@ public class BindingsHelper { } /** - * Returns an {@link AsyncWaiter} to use with the given handle, or <code>null</code> if none if - * available. + * Returns an {@link AsyncWaiter} to use with the given handle, or |null| if none if available. */ static AsyncWaiter getDefaultAsyncWaiterForHandle(Handle handle) { if (handle.getCore() != null) { @@ -129,5 +186,4 @@ public class BindingsHelper { return null; } } - } diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageHeader.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageHeader.java index ad4e108..dcaf86c 100644 --- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageHeader.java +++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/MessageHeader.java @@ -190,19 +190,10 @@ public class MessageHeader { return false; MessageHeader other = (MessageHeader) object; - if (mDataHeader == null) { - if (other.mDataHeader != null) { - return false; - } - } else { - if (!mDataHeader.equals(other.mDataHeader)) { - return false; - } - } - - return (mFlags == other.mFlags && - mRequestId == other.mRequestId && - mType == other.mType); + return (BindingsHelper.equals(mDataHeader, other.mDataHeader) + && mFlags == other.mFlags + && mRequestId == other.mRequestId + && mType == other.mType); } /** diff --git a/mojo/public/js/bindings/core_unittests.js b/mojo/public/js/bindings/core_unittests.js index b115cc0..5fed10d 100644 --- a/mojo/public/js/bindings/core_unittests.js +++ b/mojo/public/js/bindings/core_unittests.js @@ -15,6 +15,7 @@ define([ runWithDataPipe(testReadAndWriteDataPipe); runWithDataPipeWithOptions(testNop); runWithDataPipeWithOptions(testReadAndWriteDataPipe); + testHandleToString(); gc.collectGarbage(); // should not crash this.result = "PASS"; @@ -115,4 +116,18 @@ define([ expect(memory[i]).toBe((i * i) & 0xFF); } + function testHandleToString() { + var pipe = core.createDataPipe(); + expect(pipe.consumerHandle.toString).toBeDefined(); + + var openHandleRE = /^\[mojo\:\:Handle \d+\]$/ // e.g. "[mojo::Handle 123]" + var openHandleString = pipe.consumerHandle.toString(); + expect(openHandleString.match(openHandleRE)[0]).toEqual(openHandleString); + + expect(core.close(pipe.producerHandle)).toBe(core.RESULT_OK); + expect(core.close(pipe.consumerHandle)).toBe(core.RESULT_OK); + + expect(pipe.consumerHandle.toString()).toEqual("[mojo::Handle null]"); + } + }); diff --git a/mojo/public/python/mojo/bindings/messaging.py b/mojo/public/python/mojo/bindings/messaging.py index e5a765e..fb1263e 100644 --- a/mojo/public/python/mojo/bindings/messaging.py +++ b/mojo/public/python/mojo/bindings/messaging.py @@ -6,6 +6,7 @@ import struct +import sys import weakref import mojo.bindings.serialization as serialization @@ -20,6 +21,12 @@ MESSAGE_EXPECTS_RESPONSE_FLAG = 1 << 0 MESSAGE_IS_RESPONSE_FLAG = 1 << 1 +class MessagingException(Exception): + def __init__(self, *args, **kwargs): + Exception.__init__(self, *args, **kwargs) + self.__traceback__ = sys.exc_info()[2] + + class MessageHeader(object): """The header of a mojo message.""" @@ -117,10 +124,10 @@ class MessageHeader(object): class Message(object): """A message for a message pipe. This contains data and handles.""" - def __init__(self, data=None, handles=None): + def __init__(self, data=None, handles=None, header=None): self.data = data self.handles = handles - self._header = None + self._header = header self._payload = None @property @@ -251,6 +258,7 @@ class Connector(MessageReceiver): assert not self._cancellable if self._error_handler: self._error_handler.OnError(result) + self._handle.Close() def _RegisterAsyncWaiterForRead(self) : assert not self._cancellable @@ -284,7 +292,7 @@ class Router(MessageReceiverWithResponder): self._responders = {} self._connector = Connector(handle) self._connector.SetIncomingMessageReceiver( - ForwardingMessageReceiver(self._HandleIncomingMessage)) + ForwardingMessageReceiver(_WeakCallback(self._HandleIncomingMessage))) def Start(self): self._connector.Start() diff --git a/mojo/public/python/mojo/bindings/promise.py b/mojo/public/python/mojo/bindings/promise.py index c5d7d7c..ebf6f85 100644 --- a/mojo/public/python/mojo/bindings/promise.py +++ b/mojo/public/python/mojo/bindings/promise.py @@ -8,6 +8,8 @@ Promise used by the python bindings. The API is following the ECMAScript 6 API for promises. """ +import sys + class Promise(object): """The promise object.""" @@ -33,8 +35,12 @@ class Promise(object): self._onRejected = [] self._state = Promise.STATE_PENDING self._result = None - if generator_function: + try: generator_function(self._Resolve, self._Reject) + except Exception as e: + # Adding traceback similarly to python 3.0 (pep-3134) + e.__traceback__ = sys.exc_info()[2] + self._Reject(e) @staticmethod def Resolve(value): @@ -184,5 +190,7 @@ def _Delegate(resolve, reject, action): else: resolve(x) except Exception as e: + # Adding traceback similarly to python 3.0 (pep-3134) + e.__traceback__ = sys.exc_info()[2] reject(e) return _Run diff --git a/mojo/public/python/mojo/bindings/reflection.py b/mojo/public/python/mojo/bindings/reflection.py index e976db3..49c911c 100644 --- a/mojo/public/python/mojo/bindings/reflection.py +++ b/mojo/public/python/mojo/bindings/reflection.py @@ -5,8 +5,12 @@ """The metaclasses used by the mojo python bindings.""" import itertools +import logging +import sys # pylint: disable=F0401 +import mojo.bindings.messaging as messaging +import mojo.bindings.promise as promise import mojo.bindings.serialization as serialization @@ -67,7 +71,7 @@ class MojoStructType(type): ], }, 'fields': [ - FieldDescriptor('x', _descriptor.TYPE_INT32, 0), + SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), ], } @@ -108,6 +112,11 @@ class MojoStructType(type): return serialization_object.Serialize(self, handle_offset) dictionary['Serialize'] = Serialize + # pylint: disable=W0212 + def AsDict(self): + return self._fields + dictionary['AsDict'] = AsDict + def Deserialize(cls, data, handles): result = cls.__new__(cls) fields = {} @@ -130,6 +139,227 @@ class MojoStructType(type): raise AttributeError, 'can\'t delete attribute' +class MojoInterfaceType(type): + """Meta class for interfaces. + + Usage: + class MyInterface(object): + __metaclass__ = MojoInterfaceType + DESCRIPTOR = { + 'client': MyInterfaceClient, + 'methods': [ + { + 'name': 'FireAndForget', + 'ordinal': 0, + 'parameters': [ + SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), + ] + }, + { + 'name': 'Ping', + 'ordinal': 1, + 'parameters': [ + SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), + ], + 'responses': [ + SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0), + ], + }, + ], + } + """ + + def __new__(mcs, name, bases, dictionary): + # If one of the base class is already an interface type, do not edit the + # class. + for base in bases: + if isinstance(base, mcs): + return type.__new__(mcs, name, bases, dictionary) + + descriptor = dictionary.pop('DESCRIPTOR', {}) + + methods = [_MethodDescriptor(x) for x in descriptor.get('methods', [])] + for method in methods: + dictionary[method.name] = _NotImplemented + client_class = descriptor.get('client', None) + + interface_manager = InterfaceManager(name, methods, client_class) + dictionary.update({ + 'client': None, + 'manager': None, + '_interface_manager': interface_manager, + }) + + interface_class = type.__new__(mcs, name, bases, dictionary) + interface_manager.interface_class = interface_class + return interface_class + + @property + def manager(mcs): + return mcs._interface_manager + + # Prevent adding new attributes, or mutating constants. + def __setattr__(mcs, key, value): + raise AttributeError, 'can\'t set attribute' + + # Prevent deleting constants. + def __delattr__(mcs, key): + raise AttributeError, 'can\'t delete attribute' + + +class InterfaceManager(object): + """ + Manager for an interface class. The manager contains the operation that allows + to bind an implementation to a pipe, or to generate a proxy for an interface + over a pipe. + """ + + def __init__(self, name, methods, client_class): + self.name = name + self.methods = methods + if client_class: + self.client_manager = client_class.manager + else: + self.client_manager = None + self.interface_class = None + self._proxy_class = None + self._stub_class = None + + def Proxy(self, handle): + router = messaging.Router(handle) + error_handler = _ProxyErrorHandler() + router.SetErrorHandler(error_handler) + router.Start() + return self._InternalProxy(router, error_handler) + + # pylint: disable=W0212 + def Bind(self, impl, handle): + router = messaging.Router(handle) + router.SetIncomingMessageReceiver(self._Stub(impl)) + error_handler = _ProxyErrorHandler() + router.SetErrorHandler(error_handler) + + # Retain the router, until an error happen. + retainer = _Retainer(router) + def Cleanup(_): + retainer.release() + error_handler.AddCallback(Cleanup) + + if self.client_manager: + impl.client = self.client_manager._InternalProxy(router, error_handler) + + # Give an instance manager to the implementation to allow it to close + # the connection. + impl.manager = InstanceManager(router) + + router.Start() + + def _InternalProxy(self, router, error_handler): + if not self._proxy_class: + dictionary = { + '__module__': __name__, + '__init__': _ProxyInit, + } + if self.client_manager: + dictionary['client'] = property(_ProxyGetClient, _ProxySetClient) + dictionary['manager'] = None + dictionary['_client_manager'] = self.client_manager + for method in self.methods: + dictionary[method.name] = _ProxyMethodCall(method) + self._proxy_class = type('%sProxy' % self.name, + (self.interface_class,), + dictionary) + + proxy = self._proxy_class(router, error_handler) + # Give an instance manager to the proxy to allow to close the connection. + proxy.manager = InstanceManager(router) + return proxy + + def _Stub(self, impl): + if not self._stub_class: + accept_method = _StubAccept(self.methods) + dictionary = { + '__module__': __name__, + '__init__': _StubInit, + 'Accept': accept_method, + 'AcceptWithResponder': accept_method, + } + self._stub_class = type('%sStub' % self.name, + (messaging.MessageReceiverWithResponder,), + dictionary) + return self._stub_class(impl) + + +class InstanceManager(object): + """ + Manager for the implementation of an interface or a proxy. The manager allows + to control the connection over the pipe. + """ + def __init__(self, router): + self.router = router + + def Close(self): + self.router.Close() + + +class _MethodDescriptor(object): + def __init__(self, descriptor): + self.name = descriptor['name'] + self.ordinal = descriptor['ordinal'] + self.parameters_struct = _ConstructParameterStruct( + descriptor['parameters'], self.name, "Parameters") + self.response_struct = _ConstructParameterStruct( + descriptor.get('responses'), self.name, "Responses") + + +def _ConstructParameterStruct(descriptor, name, suffix): + if descriptor is None: + return None + parameter_dictionary = { + '__metaclass__': MojoStructType, + '__module__': __name__, + 'DESCRIPTOR': descriptor, + } + return MojoStructType( + '%s%s' % (name, suffix), + (object,), + parameter_dictionary) + + +class _ProxyErrorHandler(messaging.ConnectionErrorHandler): + def __init__(self): + messaging.ConnectionErrorHandler.__init__(self) + self._callbacks = set() + + def OnError(self, result): + exception = messaging.MessagingException('Mojo error: %d' % result) + for callback in list(self._callbacks): + callback(exception) + self._callbacks = None + + def AddCallback(self, callback): + if self._callbacks is not None: + self._callbacks.add(callback) + + def RemoveCallback(self, callback): + if self._callbacks: + self._callbacks.remove(callback) + + +class _Retainer(object): + + # Set to force instances to be retained. + _RETAINED = set() + + def __init__(self, retained): + self._retained = retained + _Retainer._RETAINED.add(self) + + def release(self): + self._retained = None + _Retainer._RETAINED.remove(self) + + def _StructInit(fields): def _Init(self, *args, **kwargs): if len(args) + len(kwargs) > len(fields): @@ -165,6 +395,7 @@ def _BuildProperty(field): return property(Get, Set) + def _StructEq(fields): def _Eq(self, other): if type(self) is not type(other): @@ -177,3 +408,125 @@ def _StructEq(fields): def _StructNe(self, other): return not self.__eq__(other) + + +def _ProxyInit(self, router, error_handler): + self._router = router + self._error_handler = error_handler + self._client = None + + +# pylint: disable=W0212 +def _ProxyGetClient(self): + return self._client + + +# pylint: disable=W0212 +def _ProxySetClient(self, client): + self._client = client + stub = self._client_manager._Stub(client) + self._router.SetIncomingMessageReceiver(stub) + + +# pylint: disable=W0212 +def _ProxyMethodCall(method): + flags = messaging.NO_FLAG + if method.response_struct: + flags = messaging.MESSAGE_EXPECTS_RESPONSE_FLAG + def _Call(self, *args, **kwargs): + def GenerationMethod(resolve, reject): + message = _GetMessage(method, flags, *args, **kwargs) + if method.response_struct: + def Accept(message): + try: + assert message.header.message_type == method.ordinal + payload = message.payload + response = method.response_struct.Deserialize(payload.data, + payload.handles) + as_dict = response.AsDict() + if len(as_dict) == 1: + value = as_dict.values()[0] + if not isinstance(value, dict): + response = value + resolve(response) + return True + except Exception as e: + # Adding traceback similarly to python 3.0 (pep-3134) + e.__traceback__ = sys.exc_info()[2] + reject(e) + return False + finally: + self._error_handler.RemoveCallback(reject) + + self._error_handler.AddCallback(reject) + if not self._router.AcceptWithResponder( + message, messaging.ForwardingMessageReceiver(Accept)): + self._error_handler.RemoveCallback(reject) + reject(messaging.MessagingException("Unable to send message.")) + else: + if (self._router.Accept(message)): + resolve(None) + else: + reject(messaging.MessagingException("Unable to send message.")) + return promise.Promise(GenerationMethod) + return _Call + + +def _GetMessage(method, flags, *args, **kwargs): + if flags == messaging.MESSAGE_IS_RESPONSE_FLAG: + struct = method.response_struct(*args, **kwargs) + else: + struct = method.parameters_struct(*args, **kwargs) + header = messaging.MessageHeader(method.ordinal, flags) + data = header.Serialize() + (payload, handles) = struct.Serialize() + data.extend(payload) + return messaging.Message(data, handles, header) + + +def _StubInit(self, impl): + self.impl = impl + + +def _StubAccept(methods): + methods_by_ordinal = dict((m.ordinal, m) for m in methods) + def Accept(self, message, responder=None): + try: + header = message.header + assert header.expects_response == bool(responder) + assert header.message_type in methods_by_ordinal + method = methods_by_ordinal[header.message_type] + payload = message.payload + parameters = method.parameters_struct.Deserialize( + payload.data, payload.handles).AsDict() + response = getattr(self.impl, method.name)(**parameters) + if header.expects_response: + def SendResponse(response): + if isinstance(response, dict): + response_message = _GetMessage(method, + messaging.MESSAGE_IS_RESPONSE_FLAG, + **response) + else: + response_message = _GetMessage(method, + messaging.MESSAGE_IS_RESPONSE_FLAG, + response) + response_message.header.request_id = header.request_id + responder.Accept(response_message) + p = promise.Promise.Resolve(response).Then(SendResponse) + if self.impl.manager: + # Close the connection in case of error. + p.Catch(lambda _: self.impl.manager.Close()) + return True + # pylint: disable=W0702 + except: + # Close the connection in case of error. + logging.warning( + 'Error occured in accept method. Connection will be closed.') + if self.impl.manager: + self.impl.manager.Close() + return False + return Accept + + +def _NotImplemented(*_1, **_2): + raise NotImplementedError() diff --git a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl index f187dc1..cfc66915 100644 --- a/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl +++ b/mojo/public/tools/bindings/generators/java_templates/struct_definition.tmpl @@ -1,6 +1,34 @@ {% from "constant_definition.tmpl" import constant_def %} {% from "enum_definition.tmpl" import enum_def %} +{%- macro inequality(kind, v1, v2) -%} +{%- if kind|is_reference_kind -%} +{%- if kind|is_array_kind -%} +{%- if kind.kind|is_reference_kind -%} +!java.util.Arrays.deepEquals({{v1}}, {{v2}}) +{%- else -%} +!java.util.Arrays.equals({{v1}}, {{v2}}) +{%- endif -%} +{%- else -%} +!org.chromium.mojo.bindings.BindingsHelper.equals({{v1}}, {{v2}}) +{%- endif -%} +{%- else -%} +{{v1}} != {{v2}} +{%- endif -%} +{%- endmacro -%} + +{%- macro hash(kind, v) -%} +{%- if kind|is_array_kind -%} +{%- if kind.kind|is_reference_kind -%} +java.util.Arrays.deepHashCode({{v}}) +{%- else -%} +java.util.Arrays.hashCode({{v}}) +{%- endif -%} +{%- else -%} +org.chromium.mojo.bindings.BindingsHelper.hashCode({{v}}) +{%- endif -%} +{%- endmacro -%} + {% macro encode(variable, kind, offset, bit, level=0, check_for_null=True) %} {% if kind|is_pointer_array_kind %} {% set sub_kind = kind.kind %} @@ -147,5 +175,39 @@ if (decoder{{level+1}} == null) { {% endfor %} {% endfor %} } + + /** + * @see Object#equals(Object) + */ + @Override + public boolean equals(Object object) { + if (object == this) + return true; + if (object == null) + return false; + if (getClass() != object.getClass()) + return false; +{% if struct.fields|length %} + {{struct|name}} other = ({{struct|name}}) object; +{% for field in struct.fields %} + if ({{inequality(field.kind, field|name, 'other.'~field|name)}}) + return false; +{% endfor %} +{% endif %} + return true; + } + + /** + * @see Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = prime + getClass().hashCode(); +{% for field in struct.fields %} + result = prime * result + {{hash(field.kind, field|name)}}; +{% endfor %} + return result; + } } {% endmacro %} diff --git a/mojo/public/tools/bindings/generators/mojom_java_generator.py b/mojo/public/tools/bindings/generators/mojom_java_generator.py index 4ee6ce3..4bede9a 100644 --- a/mojo/public/tools/bindings/generators/mojom_java_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_java_generator.py @@ -393,23 +393,25 @@ def ZipContentInto(root, zip_filename): class Generator(generator.Generator): java_filters = { - 'array': GetArrayKind, 'array_expected_length': GetArrayExpectedLength, - 'interface_response_name': GetInterfaceResponseName, + 'array': GetArrayKind, 'constant_value': ConstantValue, - 'default_value': DefaultValue, 'decode_method': DecodeMethod, - 'expression_to_text': ExpressionToText, + 'default_value': DefaultValue, 'encode_method': EncodeMethod, - 'has_method_with_response': HasMethodWithResponse, + 'expression_to_text': ExpressionToText, 'has_method_without_response': HasMethodWithoutResponse, + 'has_method_with_response': HasMethodWithResponse, + 'interface_response_name': GetInterfaceResponseName, + 'is_array_kind': mojom.IsArrayKind, 'is_handle': mojom.IsNonInterfaceHandleKind, 'is_map_kind': mojom.IsMapKind, 'is_nullable_kind': mojom.IsNullableKind, 'is_pointer_array_kind': IsPointerArrayKind, + 'is_reference_kind': mojom.IsReferenceKind, 'is_struct_kind': mojom.IsStructKind, - 'java_type': GetJavaType, 'java_true_false': GetJavaTrueFalse, + 'java_type': GetJavaType, 'method_ordinal_name': GetMethodOrdinalName, 'name': GetNameForElement, 'new_array': NewArray, diff --git a/mojo/public/tools/bindings/generators/mojom_python_generator.py b/mojo/public/tools/bindings/generators/mojom_python_generator.py index db5e8b6..295c656 100644 --- a/mojo/public/tools/bindings/generators/mojom_python_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_python_generator.py @@ -90,9 +90,13 @@ def ConstantStyle(name): components = components[1:] return '_'.join([x.upper() for x in components]) +def FieldStyle(name): + components = NameToComponent(name) + return '_'.join([x.lower() for x in components]) + def GetNameForElement(element): if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or - mojom.IsStructKind(element)): + mojom.IsStructKind(element) or isinstance(element, mojom.Method)): return UpperCamelCase(element.name) if isinstance(element, mojom.EnumValue): return (GetNameForElement(element.enum) + '.' + @@ -100,7 +104,9 @@ def GetNameForElement(element): if isinstance(element, (mojom.NamedValue, mojom.Constant)): return ConstantStyle(element.name) - raise Exception('Unexpected element: ' % element) + if isinstance(element, mojom.Field): + return FieldStyle(element.name) + raise Exception('Unexpected element: %s' % element) def ExpressionToText(token): if isinstance(token, (mojom.EnumValue, mojom.NamedValue)): @@ -120,7 +126,7 @@ def ExpressionToText(token): return token -def GetStructClass(kind): +def GetFullyQualifiedName(kind): name = [] if kind.imported_from: name.append(kind.imported_from['python_module']) @@ -155,7 +161,7 @@ def GetFieldType(kind, field=None): return '_descriptor.MapType(%s)' % ', '.join(arguments) if mojom.IsStructKind(kind): - arguments = [ 'lambda: %s' % GetStructClass(kind) ] + arguments = [ 'lambda: %s' % GetFullyQualifiedName(kind) ] if mojom.IsNullableKind(kind): arguments.append('nullable=True') return '_descriptor.StructType(%s)' % ', '.join(arguments) @@ -170,7 +176,7 @@ def GetFieldDescriptor(packed_field): class_name = 'SingleFieldGroup' if field.kind == mojom.BOOL: class_name = 'FieldDescriptor' - arguments = [ '%r' % field.name ] + arguments = [ '%r' % GetNameForElement(field) ] arguments.append(GetFieldType(field.kind, field)) arguments.append(str(packed_field.index)) arguments.append(str(packed_field.ordinal)) @@ -182,12 +188,20 @@ def GetFieldDescriptor(packed_field): return '_descriptor.%s(%s)' % (class_name, ', '.join(arguments)) def GetFieldGroup(byte): - if len(byte.packed_fields) > 1: + if byte.packed_fields[0].field.kind == mojom.BOOL: descriptors = map(GetFieldDescriptor, byte.packed_fields) return '_descriptor.BooleanGroup([%s])' % ', '.join(descriptors) assert len(byte.packed_fields) == 1 return GetFieldDescriptor(byte.packed_fields[0]) +def GetResponseStructFromMethod(method): + return generator.GetDataHeader( + False, generator.GetResponseStructFromMethod(method)) + +def GetStructFromMethod(method): + return generator.GetDataHeader( + False, generator.GetStructFromMethod(method)) + def ComputeStaticValues(module): in_progress = set() computed = set() @@ -274,14 +288,18 @@ class Generator(generator.Generator): python_filters = { 'expression_to_text': ExpressionToText, 'field_group': GetFieldGroup, + 'fully_qualified_name': GetFullyQualifiedName, 'name': GetNameForElement, + 'response_struct_from_method': GetResponseStructFromMethod, + 'struct_from_method': GetStructFromMethod, } @UseJinja('python_templates/module.py.tmpl', filters=python_filters) def GeneratePythonModule(self): return { - 'imports': self.GetImports(), 'enums': self.module.enums, + 'imports': self.GetImports(), + 'interfaces': self.GetQualifiedInterfaces(), 'module': ComputeStaticValues(self.module), 'structs': self.GetStructs(), } @@ -296,6 +314,25 @@ class Generator(generator.Generator): each['python_module'] = MojomToPythonImport(each['module_name']) return self.module.imports + def GetQualifiedInterfaces(self): + """ + Returns the list of interfaces of the module. Each interface that has a + client will have a reference to the representation of the client interface + in the 'qualified_client' field. + """ + interfaces = self.module.interfaces + all_interfaces = [] + interfaces + for each in self.module.imports: + all_interfaces += each['module'].interfaces + interfaces_by_name = dict((x.name, x) for x in all_interfaces) + for interface in interfaces: + if interface.client: + assert interface.client in interfaces_by_name, ( + 'Unable to find interface %s declared as client of %s.' % + (interface.client, interface.name)) + interface.qualified_client = interfaces_by_name[interface.client] + return sorted(interfaces, key=lambda i: (bool(i.client), i.name)) + def GetJinjaParameters(self): return { 'lstrip_blocks': True, diff --git a/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl b/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl index d5bff30..e0dd27f 100644 --- a/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl +++ b/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl @@ -1,4 +1,5 @@ {% from "module_macros.tmpl" import enum_values %} +{% from "module_macros.tmpl" import struct_descriptor %} # 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. @@ -18,39 +19,39 @@ import {{import.python_module}} {{constant|name}} = {{constant.value|expression_to_text}} {% endfor %} {% endif %} -{% for enum in module.enums %} +{% for enum in enums %} class {{enum|name}}(object): __metaclass__ = _reflection.MojoEnumType VALUES = {{enum_values(enum)|indent(2)}} {% endfor %} -{% for struct in module.structs %} +{% for struct in structs %} class {{struct|name}}(object): __metaclass__ = _reflection.MojoStructType + DESCRIPTOR = {{struct_descriptor(struct)|indent(2)}} +{% endfor %} +{% for interface in interfaces %} + +class {{interface|name}}(object): + __metaclass__ = _reflection.MojoInterfaceType DESCRIPTOR = { -{% if struct.constants %} - 'constants': { -{% for constant in struct.constants %} - '{{constant|name}}': {{constant.value|expression_to_text}}, -{% endfor %} - }, -{% endif %} -{% if struct.enums %} - 'enums': { -{% for enum in struct.enums %} - '{{enum|name}}': {{enum_values(enum)|indent(6)}}, -{% endfor %} - }, -{% endif %} -{% if struct.fields %} - 'fields': [ -{% for byte in struct.bytes %} -{% if byte.packed_fields %} - {{byte|field_group}}, -{% endif %} -{% endfor %} +{% if interface.client %} + 'client': {{interface.qualified_client|fully_qualified_name}}, +{% endif %} + 'methods': [ +{% for method in interface.methods %} + { + 'name': '{{method|name}}', + 'ordinal': {{method.ordinal}}, +{% set request_struct = method|struct_from_method %} + 'parameters': {{struct_descriptor(request_struct)|indent(8)}}, +{% if method.response_parameters != None %} +{% set response_struct = method|response_struct_from_method %} + 'responses': {{struct_descriptor(response_struct)|indent(8)}}, +{% endif %} + }, +{% endfor %} ], -{% endif %} } {% endfor %} diff --git a/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl b/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl index 305b26a..b42fc30 100644 --- a/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl +++ b/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl @@ -9,3 +9,31 @@ {% endfor %} ] {%- endmacro -%} + +{%- macro struct_descriptor(struct) -%} +{ +{% if struct.constants %} + 'constants': { +{% for constant in struct.constants %} + '{{constant|name}}': {{constant.value|expression_to_text}}, +{% endfor %} + }, +{% endif %} +{% if struct.enums %} + 'enums': { +{% for enum in struct.enums %} + '{{enum|name}}': {{enum_values(enum)|indent(6)}}, +{% endfor %} + }, +{% endif %} +{% if struct.fields %} + 'fields': [ +{% for byte in struct.bytes %} +{% if byte.packed_fields %} + {{byte|field_group}}, +{% endif %} +{% endfor %} + ], +{% endif %} +} +{%- endmacro -%} diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py index 7d668f1..35070ef 100644 --- a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py +++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py @@ -88,7 +88,7 @@ class Parser(object): p[0].Append(p[2]) def p_import(self, p): - """import : IMPORT STRING_LITERAL""" + """import : IMPORT STRING_LITERAL SEMI""" # 'eval' the literal to strip the quotes. # TODO(vtl): This eval is dubious. We should unquote/unescape ourselves. p[0] = ast.Import(eval(p[2])) diff --git a/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py b/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py index b27217a..cc71f04 100644 --- a/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py +++ b/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py @@ -961,7 +961,7 @@ class ParserTest(unittest.TestCase): """Tests parsing import statements.""" # One import (no module statement). - source1 = "import \"somedir/my.mojom\"" + source1 = "import \"somedir/my.mojom\";" expected1 = ast.Mojom( None, ast.ImportList(ast.Import("somedir/my.mojom")), @@ -970,8 +970,8 @@ class ParserTest(unittest.TestCase): # Two imports (no module statement). source2 = """\ - import "somedir/my1.mojom" - import "somedir/my2.mojom" + import "somedir/my1.mojom"; + import "somedir/my2.mojom"; """ expected2 = ast.Mojom( None, @@ -982,8 +982,8 @@ class ParserTest(unittest.TestCase): # Imports with module statement. source3 = """\ - import "somedir/my1.mojom" - import "somedir/my2.mojom" + import "somedir/my1.mojom"; + import "somedir/my2.mojom"; module my_module {} """ expected3 = ast.Mojom( @@ -1016,6 +1016,16 @@ class ParserTest(unittest.TestCase): r" *module {}$"): parser.Parse(source2, "my_file.mojom") + source3 = """\ + import "foo.mojom" // Missing semicolon. + module {} + """ + with self.assertRaisesRegexp( + parser.ParseError, + r"^my_file\.mojom:2: Error: Unexpected 'module':\n" + r" *module {}$"): + parser.Parse(source3, "my_file.mojom") + def testValidNullableTypes(self): """Tests parsing nullable types.""" diff --git a/mojo/services/public/cpp/native_viewport/args.h b/mojo/services/public/cpp/native_viewport/args.h index 623433d..092d1d9 100644 --- a/mojo/services/public/cpp/native_viewport/args.h +++ b/mojo/services/public/cpp/native_viewport/args.h @@ -9,8 +9,9 @@ namespace mojo { // All args in alphabetical order. The switches should be documented // alongside the definition of their values in the .cc file. -extern const char kUseTestConfig[]; extern const char kUseHeadlessConfig[]; +extern const char kUseOSMesa[]; +extern const char kUseTestConfig[]; } // namespace mojo diff --git a/mojo/services/public/cpp/native_viewport/lib/args.cc b/mojo/services/public/cpp/native_viewport/lib/args.cc index cf0617d..7b1cb89 100644 --- a/mojo/services/public/cpp/native_viewport/lib/args.cc +++ b/mojo/services/public/cpp/native_viewport/lib/args.cc @@ -6,6 +6,8 @@ namespace mojo { +// Instead of using the system GL implementation, use OSMesa. +const char kUseOSMesa[] = "--use-osmesa"; // Loads an app from the specified directory and launches it. // Force gl to be initialized in test mode. const char kUseTestConfig[] = "--use-test-config"; diff --git a/mojo/services/public/interfaces/content_handler/content_handler.mojom b/mojo/services/public/interfaces/content_handler/content_handler.mojom index b9c1c04..4c3051c 100644 --- a/mojo/services/public/interfaces/content_handler/content_handler.mojom +++ b/mojo/services/public/interfaces/content_handler/content_handler.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/application/service_provider.mojom" -import "mojo/services/public/interfaces/network/url_loader.mojom" +import "mojo/public/interfaces/application/service_provider.mojom"; +import "mojo/services/public/interfaces/network/url_loader.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/gpu/gpu.mojom b/mojo/services/public/interfaces/gpu/gpu.mojom index 07e813d..49f6ae7 100644 --- a/mojo/services/public/interfaces/gpu/gpu.mojom +++ b/mojo/services/public/interfaces/gpu/gpu.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/gpu/command_buffer.mojom" +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/gpu/command_buffer.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/input_events/input_events.mojom b/mojo/services/public/interfaces/input_events/input_events.mojom index 4067f68..9530b6e 100644 --- a/mojo/services/public/interfaces/input_events/input_events.mojom +++ b/mojo/services/public/interfaces/input_events/input_events.mojom @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/input_events/input_event_constants.mojom" -import "mojo/services/public/interfaces/input_events/input_key_codes.mojom" +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/input_events/input_event_constants.mojom"; +import "mojo/services/public/interfaces/input_events/input_key_codes.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom index 421f47c..61e32e7 100644 --- a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom +++ b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/gpu/command_buffer.mojom" -import "mojo/services/public/interfaces/input_events/input_events.mojom" -import "mojo/services/public/interfaces/surfaces/surface_id.mojom" +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/gpu/command_buffer.mojom"; +import "mojo/services/public/interfaces/input_events/input_events.mojom"; +import "mojo/services/public/interfaces/surfaces/surface_id.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/navigation/navigation.mojom b/mojo/services/public/interfaces/navigation/navigation.mojom index 6a9e94f9..e709317 100644 --- a/mojo/services/public/interfaces/navigation/navigation.mojom +++ b/mojo/services/public/interfaces/navigation/navigation.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/url_loader.mojom" +import "mojo/services/public/interfaces/network/url_loader.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/network_service.mojom b/mojo/services/public/interfaces/network/network_service.mojom index e039780..b2bdd40 100644 --- a/mojo/services/public/interfaces/network/network_service.mojom +++ b/mojo/services/public/interfaces/network/network_service.mojom @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/cookie_store.mojom" -import "mojo/services/public/interfaces/network/net_address.mojom" -import "mojo/services/public/interfaces/network/network_error.mojom" -import "mojo/services/public/interfaces/network/tcp_bound_socket.mojom" -import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom" -import "mojo/services/public/interfaces/network/udp_socket.mojom" -import "mojo/services/public/interfaces/network/url_loader.mojom" -import "mojo/services/public/interfaces/network/web_socket.mojom" +import "mojo/services/public/interfaces/network/cookie_store.mojom"; +import "mojo/services/public/interfaces/network/net_address.mojom"; +import "mojo/services/public/interfaces/network/network_error.mojom"; +import "mojo/services/public/interfaces/network/tcp_bound_socket.mojom"; +import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom"; +import "mojo/services/public/interfaces/network/udp_socket.mojom"; +import "mojo/services/public/interfaces/network/url_loader.mojom"; +import "mojo/services/public/interfaces/network/web_socket.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/tcp_bound_socket.mojom b/mojo/services/public/interfaces/network/tcp_bound_socket.mojom index 973afc3..1846fc8 100644 --- a/mojo/services/public/interfaces/network/tcp_bound_socket.mojom +++ b/mojo/services/public/interfaces/network/tcp_bound_socket.mojom @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/net_address.mojom" -import "mojo/services/public/interfaces/network/network_error.mojom" -import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom" -import "mojo/services/public/interfaces/network/tcp_server_socket.mojom" +import "mojo/services/public/interfaces/network/net_address.mojom"; +import "mojo/services/public/interfaces/network/network_error.mojom"; +import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom"; +import "mojo/services/public/interfaces/network/tcp_server_socket.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/tcp_server_socket.mojom b/mojo/services/public/interfaces/network/tcp_server_socket.mojom index 6d8430d..09921c02 100644 --- a/mojo/services/public/interfaces/network/tcp_server_socket.mojom +++ b/mojo/services/public/interfaces/network/tcp_server_socket.mojom @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/net_address.mojom" -import "mojo/services/public/interfaces/network/network_error.mojom" -import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom" +import "mojo/services/public/interfaces/network/net_address.mojom"; +import "mojo/services/public/interfaces/network/network_error.mojom"; +import "mojo/services/public/interfaces/network/tcp_connected_socket.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/udp_socket.mojom b/mojo/services/public/interfaces/network/udp_socket.mojom index f26cd09..3b0c72e 100644 --- a/mojo/services/public/interfaces/network/udp_socket.mojom +++ b/mojo/services/public/interfaces/network/udp_socket.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/net_address.mojom" -import "mojo/services/public/interfaces/network/network_error.mojom" +import "mojo/services/public/interfaces/network/net_address.mojom"; +import "mojo/services/public/interfaces/network/network_error.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/url_loader.mojom b/mojo/services/public/interfaces/network/url_loader.mojom index 61cdc8f..e62b1d1 100644 --- a/mojo/services/public/interfaces/network/url_loader.mojom +++ b/mojo/services/public/interfaces/network/url_loader.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/network_error.mojom" +import "mojo/services/public/interfaces/network/network_error.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/network/web_socket.mojom b/mojo/services/public/interfaces/network/web_socket.mojom index d96fb26..488746e 100644 --- a/mojo/services/public/interfaces/network/web_socket.mojom +++ b/mojo/services/public/interfaces/network/web_socket.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/network/network_error.mojom" +import "mojo/services/public/interfaces/network/network_error.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/surfaces/quads.mojom b/mojo/services/public/interfaces/surfaces/quads.mojom index 7625faa..a1a8308e 100644 --- a/mojo/services/public/interfaces/surfaces/quads.mojom +++ b/mojo/services/public/interfaces/surfaces/quads.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/surfaces/surface_id.mojom" +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/surfaces/surface_id.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/surfaces/surfaces.mojom b/mojo/services/public/interfaces/surfaces/surfaces.mojom index 0d93ee4..ffa8fce 100644 --- a/mojo/services/public/interfaces/surfaces/surfaces.mojom +++ b/mojo/services/public/interfaces/surfaces/surfaces.mojom @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/gpu/command_buffer.mojom" -import "mojo/services/public/interfaces/surfaces/quads.mojom" -import "mojo/services/public/interfaces/surfaces/surface_id.mojom" +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/gpu/command_buffer.mojom"; +import "mojo/services/public/interfaces/surfaces/quads.mojom"; +import "mojo/services/public/interfaces/surfaces/surface_id.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/surfaces/surfaces_service.mojom b/mojo/services/public/interfaces/surfaces/surfaces_service.mojom index 76faeec..f26c7aa 100644 --- a/mojo/services/public/interfaces/surfaces/surfaces_service.mojom +++ b/mojo/services/public/interfaces/surfaces/surfaces_service.mojom @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/services/public/interfaces/surfaces/surfaces.mojom" +import "mojo/services/public/interfaces/surfaces/surfaces.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom index e76996e..a903437 100644 --- a/mojo/services/public/interfaces/view_manager/view_manager.mojom +++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/application/service_provider.mojom" -import "mojo/services/public/interfaces/geometry/geometry.mojom" -import "mojo/services/public/interfaces/input_events/input_events.mojom" -import "mojo/services/public/interfaces/surfaces/surface_id.mojom" -import "mojo/services/public/interfaces/view_manager/view_manager_constants.mojom" +import "mojo/public/interfaces/application/service_provider.mojom"; +import "mojo/services/public/interfaces/geometry/geometry.mojom"; +import "mojo/services/public/interfaces/input_events/input_events.mojom"; +import "mojo/services/public/interfaces/surfaces/surface_id.mojom"; +import "mojo/services/public/interfaces/view_manager/view_manager_constants.mojom"; module mojo { diff --git a/mojo/services/public/interfaces/window_manager/BUILD.gn b/mojo/services/public/interfaces/window_manager/BUILD.gn index 3d1e55f..30c9984 100644 --- a/mojo/services/public/interfaces/window_manager/BUILD.gn +++ b/mojo/services/public/interfaces/window_manager/BUILD.gn @@ -8,6 +8,7 @@ import("//mojo/public/tools/bindings/mojom.gni") mojom("window_manager") { sources = [ "window_manager.mojom", + "window_manager_internal.mojom", ] deps = [ diff --git a/mojo/services/public/interfaces/window_manager/window_manager.mojom b/mojo/services/public/interfaces/window_manager/window_manager.mojom index 804bd37..754f1ed 100644 --- a/mojo/services/public/interfaces/window_manager/window_manager.mojom +++ b/mojo/services/public/interfaces/window_manager/window_manager.mojom @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import "mojo/public/interfaces/application/service_provider.mojom" -import "mojo/services/public/interfaces/input_events/input_events.mojom" +import "mojo/public/interfaces/application/service_provider.mojom"; +import "mojo/services/public/interfaces/input_events/input_events.mojom"; module mojo { @@ -13,26 +13,4 @@ interface WindowManager { Embed(string url, ServiceProvider&? service_provider); }; -// WindowManagerInternalService provides high level window management policies -// and is used by the ViewManager. This interface is marked as internal as only -// the view manager is allowed to connect to this. -[Client=WindowManagerInternalClient] -interface WindowManagerInternalService { - // Called when an input event is received from the native system. It's - // expected that when this is received the WindowManagerInternalService will - // call back to WindowManagerInternalServieClient will call - // DispatchInputEventToView(). - // TODO(sky): nuke this and instead have an interface specifically for - // dispatching events in the NativeViewportService. - OnViewInputEvent(mojo.Event event); -}; - -// ViewManager provides this interface for functionality only exposed to the -// WindowManagerInternalServie. -[Client=WindowManagerInternalService] -interface WindowManagerInternalClient { - // Dispatches the specified input event to the specified view. - DispatchInputEventToView(uint32 view_id, mojo.Event event); -}; - } diff --git a/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom b/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom new file mode 100644 index 0000000..9d7fef1 --- /dev/null +++ b/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom @@ -0,0 +1,31 @@ +// 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/services/public/interfaces/input_events/input_events.mojom"; + +module mojo { + +// WindowManagerInternalService provides high level window management policies +// and is used by the ViewManager. This interface is marked as internal as only +// the view manager is allowed to connect to this. +[Client=WindowManagerInternalClient] +interface WindowManagerInternalService { + // Called when an input event is received from the native system. It's + // expected that when this is received the WindowManagerInternalService will + // call back to WindowManagerInternalServieClient will call + // DispatchInputEventToView(). + // TODO(sky): nuke this and instead have an interface specifically for + // dispatching events in the NativeViewportService. + OnViewInputEvent(mojo.Event event); +}; + +// ViewManager provides this interface for functionality only exposed to the +// WindowManagerInternalServie. +[Client=WindowManagerInternalService] +interface WindowManagerInternalClient { + // Dispatches the specified input event to the specified view. + DispatchInputEventToView(uint32 view_id, mojo.Event event); +}; + +} |