diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 18:12:21 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-15 18:12:21 +0000 |
commit | f43fdd7758e4dae74cdcd444b6ecbf9c7a4d0aee (patch) | |
tree | f7ccb6a3317c2e1ac15bae3c545a894324340bde /mojo | |
parent | e4a52c8146deda91c10e9ff293ba0ba0b312a801 (diff) | |
download | chromium_src-f43fdd7758e4dae74cdcd444b6ecbf9c7a4d0aee.zip chromium_src-f43fdd7758e4dae74cdcd444b6ecbf9c7a4d0aee.tar.gz chromium_src-f43fdd7758e4dae74cdcd444b6ecbf9c7a4d0aee.tar.bz2 |
Work in progress for end-to-end bindings
R=darin@chromium.org, sky@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=234975
Review URL: https://codereview.chromium.org/72123002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235379 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/examples/hello_world_service/hello_world_service.mojom | 17 | ||||
-rw-r--r-- | mojo/examples/hello_world_service/hello_world_service_impl.cc | 26 | ||||
-rw-r--r-- | mojo/examples/hello_world_service/hello_world_service_impl.h | 27 | ||||
-rw-r--r-- | mojo/examples/sample_app/hello_world_client_impl.cc | 28 | ||||
-rw-r--r-- | mojo/examples/sample_app/hello_world_client_impl.h | 32 | ||||
-rw-r--r-- | mojo/examples/sample_app/sample_app.cc | 75 | ||||
-rw-r--r-- | mojo/mojo.gyp | 37 | ||||
-rw-r--r-- | mojo/public/bindings/mojom_bindings_generator.gypi | 6 | ||||
-rw-r--r-- | mojo/shell/app_container.cc | 93 | ||||
-rw-r--r-- | mojo/shell/app_container.h | 22 |
10 files changed, 259 insertions, 104 deletions
diff --git a/mojo/examples/hello_world_service/hello_world_service.mojom b/mojo/examples/hello_world_service/hello_world_service.mojom new file mode 100644 index 0000000..5f03d69 --- /dev/null +++ b/mojo/examples/hello_world_service/hello_world_service.mojom @@ -0,0 +1,17 @@ +// 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. + +module mojo { + +[Peer=HelloWorldClient] +interface HelloWorldService { + void Greeting(string greeting); +}; + +[Peer=HelloWorldService] +interface HelloWorldClient { + void DidReceiveGreeting(int32 result); +}; + +} diff --git a/mojo/examples/hello_world_service/hello_world_service_impl.cc b/mojo/examples/hello_world_service/hello_world_service_impl.cc new file mode 100644 index 0000000..d1060cb --- /dev/null +++ b/mojo/examples/hello_world_service/hello_world_service_impl.cc @@ -0,0 +1,26 @@ +// 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/examples/hello_world_service/hello_world_service_impl.h" + +#include <string> +#include "base/logging.h" + +namespace mojo { +namespace examples { + +HelloWorldServiceImpl::HelloWorldServiceImpl(mojo::Handle pipe) + : client_(pipe) { + client_.SetPeer(this); +} + +void HelloWorldServiceImpl::Greeting(const mojo::String* greeting) { + LOG(INFO) << greeting->To<std::string>(); + client_->DidReceiveGreeting(42); +} + +HelloWorldServiceImpl::~HelloWorldServiceImpl() {} + +} // examples +} // mojo diff --git a/mojo/examples/hello_world_service/hello_world_service_impl.h b/mojo/examples/hello_world_service/hello_world_service_impl.h new file mode 100644 index 0000000..6382617 --- /dev/null +++ b/mojo/examples/hello_world_service/hello_world_service_impl.h @@ -0,0 +1,27 @@ +// 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_EXAMPLES_HELLO_WORLD_SERVICE_HELLO_WORLD_SERVICE_IMPL_H_ +#define MOJO_EXAMPLES_HELLO_WORLD_SERVICE_HELLO_WORLD_SERVICE_IMPL_H_ + +#include "mojo/public/bindings/lib/remote_ptr.h" +#include "mojom/hello_world_service.h" + +namespace mojo { +namespace examples { + +class HelloWorldServiceImpl : public HelloWorldServiceStub { + public: + explicit HelloWorldServiceImpl(mojo::Handle pipe); + virtual ~HelloWorldServiceImpl(); + virtual void Greeting(const mojo::String* greeting) MOJO_OVERRIDE; + + private: + mojo::RemotePtr<HelloWorldClient> client_; +}; + +} // examples +} // mojo + +#endif // MOJO_EXAMPLES_HELLO_WORLD_SERVICE_HELLO_WORLD_SERVICE_IMPL_H_ diff --git a/mojo/examples/sample_app/hello_world_client_impl.cc b/mojo/examples/sample_app/hello_world_client_impl.cc new file mode 100644 index 0000000..bda310e --- /dev/null +++ b/mojo/examples/sample_app/hello_world_client_impl.cc @@ -0,0 +1,28 @@ +// 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/examples/sample_app/hello_world_client_impl.h" + +#include <stdio.h> + +#include "base/message_loop/message_loop.h" + +namespace mojo { +namespace examples { + +HelloWorldClientImpl::HelloWorldClientImpl(mojo::Handle pipe) + : service_(pipe) { + service_.SetPeer(this); +} + +void HelloWorldClientImpl::DidReceiveGreeting(int32_t result) { + printf("DidReceiveGreeting from pipe: %d\n", result); + // Stop the current message loop. + base::MessageLoop::current()->QuitNow(); +} + +HelloWorldClientImpl::~HelloWorldClientImpl() {} + +} // examples +} // mojo diff --git a/mojo/examples/sample_app/hello_world_client_impl.h b/mojo/examples/sample_app/hello_world_client_impl.h new file mode 100644 index 0000000..4995406 --- /dev/null +++ b/mojo/examples/sample_app/hello_world_client_impl.h @@ -0,0 +1,32 @@ +// 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_EXAMPLES_SAMPLE_APP_HELLO_WORLD_CLIENT_IMPL_H_ +#define MOJO_EXAMPLES_SAMPLE_APP_HELLO_WORLD_CLIENT_IMPL_H_ + +#include "mojo/public/bindings/lib/remote_ptr.h" +#include "mojom/hello_world_service.h" + +namespace mojo { +namespace examples { + +class HelloWorldClientImpl : public HelloWorldClientStub { + public: + explicit HelloWorldClientImpl(mojo::Handle pipe); + virtual ~HelloWorldClientImpl(); + + virtual void DidReceiveGreeting(int32_t result) MOJO_OVERRIDE; + + HelloWorldService* service() { + return service_.get(); + } + + private: + mojo::RemotePtr<HelloWorldService> service_; +}; + +} // examples +} // mojo + +#endif // MOJO_EXAMPLES_SAMPLE_APP_HELLO_WORLD_CLIENT_IMPL_H_ diff --git a/mojo/examples/sample_app/sample_app.cc b/mojo/examples/sample_app/sample_app.cc index abef1f3..b071a4e 100644 --- a/mojo/examples/sample_app/sample_app.cc +++ b/mojo/examples/sample_app/sample_app.cc @@ -3,7 +3,12 @@ // found in the LICENSE file. #include <stdio.h> +#include <string> +#include "base/message_loop/message_loop.h" +#include "mojo/common/bindings_support_impl.h" +#include "mojo/examples/sample_app/hello_world_client_impl.h" +#include "mojo/public/bindings/lib/bindings_support.h" #include "mojo/public/system/core.h" #include "mojo/public/system/macros.h" @@ -17,59 +22,33 @@ #define SAMPLE_APP_EXPORT __attribute__((visibility("default"))) #endif -char* ReadStringFromPipe(mojo::Handle pipe) { - uint32_t len = 0; - char* buf = NULL; - MojoResult result = mojo::ReadMessage(pipe, buf, &len, NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE); - if (result == MOJO_RESULT_RESOURCE_EXHAUSTED) { - buf = new char[len]; - result = mojo::ReadMessage(pipe, buf, &len, NULL, NULL, - MOJO_READ_MESSAGE_FLAG_NONE); - } - if (result < MOJO_RESULT_OK) { - // Failure.. - if (buf) - delete[] buf; - return NULL; - } - return buf; -} - -class SampleMessageWaiter { - public: - explicit SampleMessageWaiter(mojo::Handle pipe) : pipe_(pipe) {} - ~SampleMessageWaiter() {} - - void Read() { - char* string = ReadStringFromPipe(pipe_); - if (string) { - printf("Read string from pipe: %s\n", string); - delete[] string; - string = NULL; - } - } +namespace mojo { +namespace examples { - void WaitAndRead() { - for (int i = 0; i < 100;) { - MojoResult result = mojo::Wait(pipe_, MOJO_WAIT_FLAG_READABLE, 100); - if (result < MOJO_RESULT_OK) { - // Failure... - continue; - } - ++i; - Read(); - } - } +void SayHello(mojo::Handle pipe) { + // Send message out. + HelloWorldClientImpl client(pipe); + mojo::ScratchBuffer buf; + const std::string kGreeting("hello, world!"); + mojo::String* greeting = mojo::String::NewCopyOf(&buf, kGreeting); + client.service()->Greeting(greeting); - private: - mojo::Handle pipe_; + // Run loop to receieve Ack. The client will quit the loop. + base::MessageLoop::current()->Run(); +} - MOJO_DISALLOW_COPY_AND_ASSIGN(SampleMessageWaiter); -}; +} // examples +} // mojo extern "C" SAMPLE_APP_EXPORT MojoResult CDECL MojoMain( mojo::Handle pipe) { - SampleMessageWaiter(pipe).WaitAndRead(); + base::MessageLoop loop; + // Set the global bindings support. + mojo::common::BindingsSupportImpl bindings_support; + mojo::BindingsSupport::Set(&bindings_support); + + mojo::examples::SayHello(pipe); + + mojo::BindingsSupport::Set(NULL); return MOJO_RESULT_OK; } diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index e7cc056..96517d1 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -233,6 +233,7 @@ 'mojo_system', 'mojo_utility', 'native_viewport', + 'hello_world_service_impl', ], 'sources': [ 'shell/app_container.cc', @@ -314,16 +315,52 @@ 'target_name': 'sample_app', 'type': 'shared_library', 'dependencies': [ + '../base/base.gyp:base', '../ui/gl/gl.gyp:gl', + 'hello_world_service', + 'mojo_common_lib', 'mojo_system', ], 'sources': [ + 'examples/sample_app/hello_world_client_impl.cc', + 'examples/sample_app/hello_world_client_impl.h', 'examples/sample_app/sample_app.cc', 'examples/sample_app/spinning_cube.cc', 'examples/sample_app/spinning_cube.h', ], }, { + 'target_name': 'hello_world_service', + 'type': 'static_library', + 'dependencies': [ + 'mojo_bindings', + 'mojo_system', + ], + 'export_dependent_settings': [ + 'mojo_bindings', + 'mojo_system', + ], + 'sources': [ + 'examples/hello_world_service/hello_world_service.mojom', + ], + 'includes': [ 'public/bindings/mojom_bindings_generator.gypi' ], + }, + { + 'target_name': 'hello_world_service_impl', + 'type': 'static_library', + 'sources': [ + 'examples/hello_world_service/hello_world_service_impl.cc', + 'examples/hello_world_service/hello_world_service_impl.h', + ], + 'export_dependent_settings': [ + 'hello_world_service', + ], + 'dependencies': [ + '../base/base.gyp:base', + 'hello_world_service', + ], + }, + { 'target_name': 'mojo_bindings', 'type': 'static_library', 'include_dirs': [ diff --git a/mojo/public/bindings/mojom_bindings_generator.gypi b/mojo/public/bindings/mojom_bindings_generator.gypi index 17b4d31..099e3eb7 100644 --- a/mojo/public/bindings/mojom_bindings_generator.gypi +++ b/mojo/public/bindings/mojom_bindings_generator.gypi @@ -42,5 +42,11 @@ '<(DEPTH)', '<(SHARED_INTERMEDIATE_DIR)', ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(DEPTH)', + '<(SHARED_INTERMEDIATE_DIR)', + ], + }, 'hard_dependency': 1, } diff --git a/mojo/shell/app_container.cc b/mojo/shell/app_container.cc index 221c871..6699b1a 100644 --- a/mojo/shell/app_container.cc +++ b/mojo/shell/app_container.cc @@ -23,38 +23,9 @@ typedef MojoResult (*MojoMainFunction)(mojo::Handle pipe); namespace mojo { namespace shell { -void LaunchAppOnThread( - const base::FilePath& app_path, - Handle app_handle_raw) { - base::ScopedClosureRunner app_deleter( - base::Bind(base::IgnoreResult(&base::DeleteFile), app_path, false)); - ScopedHandle app_handle(app_handle_raw); - - base::ScopedNativeLibrary app_library( - base::LoadNativeLibrary(app_path, NULL)); - if (!app_library.is_valid()) { - LOG(ERROR) << "Failed to load library: " << app_path.value().c_str(); - return; - } - - MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( - app_library.GetFunctionPointer("MojoMain")); - if (!main_function) { - LOG(ERROR) << "Entrypoint MojoMain not found."; - return; - } - - MojoResult result = main_function(app_handle.get()); - if (result < MOJO_RESULT_OK) { - LOG(ERROR) << "MojoMain returned an error: " << result; - return; - } - - LOG(INFO) << "MojoMain succeeded: " << result; -} - AppContainer::AppContainer(Context* context) : context_(context), + app_handle_raw_(mojo::kInvalidHandle), weak_factory_(this) { } @@ -67,40 +38,64 @@ void AppContainer::Load(const GURL& app_url) { void AppContainer::DidCompleteLoad(const GURL& app_url, const base::FilePath& app_path) { - Handle app_handle; - MojoResult result = CreateMessagePipe(&shell_handle_, &app_handle); + Handle shell_handle; + MojoResult result = CreateMessagePipe(&shell_handle, &app_handle_raw_); if (result < MOJO_RESULT_OK) { // Failure.. } + hello_world_service_.reset( + new examples::HelloWorldServiceImpl(shell_handle)); + // Launch the app on its own thread. // TODO(beng): Create a unique thread name. - thread_.reset(new base::Thread("app_thread")); + app_path_ = app_path; + ack_closure_ = + base::Bind(&AppContainer::AppCompleted, weak_factory_.GetWeakPtr()); + thread_.reset(new base::DelegateSimpleThread(this, "app_thread")); thread_->Start(); - thread_->message_loop_proxy()->PostTaskAndReply( - FROM_HERE, - base::Bind(&LaunchAppOnThread, app_path, app_handle), - base::Bind(&AppContainer::AppCompleted, weak_factory_.GetWeakPtr())); - - const char* hello_msg = "Hello"; - result = WriteMessage(shell_handle_, hello_msg, - static_cast<uint32_t>(strlen(hello_msg)+1), - NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); - if (result < MOJO_RESULT_OK) { - // Failure.. - } // TODO(beng): This should be created on demand by the NativeViewportService // when it is retrieved by the app. - native_viewport_controller_.reset( - new services::NativeViewportController(context_, shell_handle_)); + // native_viewport_controller_.reset( + // new services::NativeViewportController(context_, shell_handle_)); +} + +void AppContainer::Run() { + base::ScopedClosureRunner app_deleter( + base::Bind(base::IgnoreResult(&base::DeleteFile), app_path_, false)); + ScopedHandle app_handle(app_handle_raw_); + + base::ScopedNativeLibrary app_library( + base::LoadNativeLibrary(app_path_, NULL)); + if (!app_library.is_valid()) { + LOG(ERROR) << "Failed to load library: " << app_path_.value().c_str(); + return; + } + + MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( + app_library.GetFunctionPointer("MojoMain")); + if (!main_function) { + LOG(ERROR) << "Entrypoint MojoMain not found."; + return; + } + + MojoResult result = main_function(app_handle.get()); + if (result < MOJO_RESULT_OK) { + LOG(ERROR) << "MojoMain returned an error: " << result; + return; + } + LOG(INFO) << "MojoMain succeeded: " << result; + context_->task_runners()->ui_runner()->PostTask(FROM_HERE, ack_closure_); } void AppContainer::AppCompleted() { - native_viewport_controller_->Close(); + hello_world_service_.reset(); + // TODO(aa): This code gets replaced once we have a service manager. + // native_viewport_controller_->Close(); + thread_->Join(); thread_.reset(); - Close(shell_handle_); } } // namespace shell diff --git a/mojo/shell/app_container.h b/mojo/shell/app_container.h index ae6e277..09231d7 100644 --- a/mojo/shell/app_container.h +++ b/mojo/shell/app_container.h @@ -8,12 +8,14 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/threading/simple_thread.h" +#include "mojo/examples/hello_world_service/hello_world_service_impl.h" #include "mojo/public/system/core.h" #include "mojo/shell/loader.h" namespace base { class FilePath; -class Thread; +class PlatformThreadHandle; } namespace mojo { @@ -25,7 +27,9 @@ namespace shell { class Context; // A container class that runs an app on its own thread. -class AppContainer : public Loader::Delegate { +class AppContainer + : public Loader::Delegate, + public base::DelegateSimpleThread::Delegate { public: explicit AppContainer(Context* context); virtual ~AppContainer(); @@ -33,20 +37,24 @@ class AppContainer : public Loader::Delegate { void Load(const GURL& app_url); private: - // From Loader::Delegate + // From Loader::Delegate. virtual void DidCompleteLoad(const GURL& app_url, const base::FilePath& app_path) OVERRIDE; + // From base::DelegateSimpleThread::Delegate. + virtual void Run() OVERRIDE; + void AppCompleted(); Context* context_; + base::FilePath app_path_; + Handle app_handle_raw_; + base::Closure ack_closure_; scoped_ptr<Loader::Job> request_; - scoped_ptr<base::Thread> thread_; + scoped_ptr<base::DelegateSimpleThread> thread_; + scoped_ptr<examples::HelloWorldServiceImpl> hello_world_service_; scoped_ptr<services::NativeViewportController> native_viewport_controller_; - // Following members are valid only on app thread. - Handle shell_handle_; - base::WeakPtrFactory<AppContainer> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AppContainer); |