Chromium Code Reviews| Index: mojo/apps/js/main.cc |
| diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc |
| index b5d4486736d60b2666b176880310c3922d8e8146..b4512884dd86b872a75734542dc27053d32006b5 100644 |
| --- a/mojo/apps/js/main.cc |
| +++ b/mojo/apps/js/main.cc |
| @@ -1,41 +1,149 @@ |
| -// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// 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 <stdio.h> |
| + |
| +#include "base/at_exit.h" |
| +#include "base/bind.h" |
| +#include "base/file_util.h" |
| +#include "base/i18n/icu_util.h" |
| #include "base/message_loop/message_loop.h" |
| +#include "base/path_service.h" |
| +#include "gin/converter.h" |
| +#include "gin/modules/console.h" |
| +#include "gin/modules/module_registry.h" |
| +#include "gin/modules/module_runner_delegate.h" |
| #include "gin/public/isolate_holder.h" |
| -#include "mojo/apps/js/mojo_runner_delegate.h" |
| -#include "mojo/public/cpp/system/core.h" |
| -#include "mojo/public/cpp/system/macros.h" |
| - |
| -#if defined(WIN32) |
| -#if !defined(CDECL) |
| -#define CDECL __cdecl |
| -#endif |
| -#define MOJO_APPS_JS_EXPORT __declspec(dllexport) |
| -#else |
| -#define CDECL |
| -#define MOJO_APPS_JS_EXPORT __attribute__((visibility("default"))) |
| -#endif |
| +#include "gin/test/file_runner.h" |
| +#include "gin/try_catch.h" |
| +#include "mojo/apps/js/bindings/gl/module.h" |
| +#include "mojo/apps/js/bindings/threading.h" |
| +#include "mojo/bindings/js/core.h" |
| +#include "mojo/bindings/js/handle.h" |
| +#include "mojo/bindings/js/support.h" |
| +#include "mojo/common/data_pipe_utils.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/application/application_runner_chromium.h" |
| +#include "mojo/public/cpp/application/interface_factory_impl.h" |
| +#include "mojo/services/public/interfaces/content_handler/content_handler.mojom.h" |
| namespace mojo { |
| namespace apps { |
| +namespace { |
| + |
| +std::vector<base::FilePath> GetModuleSearchPaths() { |
| + std::vector<base::FilePath> module_base(1); |
| + CHECK(base::GetCurrentDirectory(&module_base[0])); |
| + return module_base; |
| +} |
| + |
| +void Run( |
| + base::WeakPtr<gin::Runner> runner, |
| + const std::string& code, |
| + const std::string& path) { |
| + if (!runner) |
| + return; |
| + gin::Runner::Scope scope(runner.get()); |
| + runner->Run(code.c_str(), path.c_str()); |
| +} |
| + |
| +class MojoRunnerDelegate : public gin::ModuleRunnerDelegate { |
| + public: |
| + MojoRunnerDelegate() : gin::ModuleRunnerDelegate(GetModuleSearchPaths()) { |
| + AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); |
| + } |
| + |
| + virtual void UnhandledException(gin::ShellRunner* runner, |
| + gin::TryCatch& try_catch) OVERRIDE { |
| + gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch); |
| + LOG(ERROR) << try_catch.GetStackTrace(); |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate); |
| +}; |
| + |
| +} // namespace |
| + |
| -void Start(MojoHandle pipe, const std::string& module) { |
| - base::MessageLoop loop; |
| +class ContentHandlerApp; |
| - gin::IsolateHolder instance(gin::IsolateHolder::kStrictMode); |
| - MojoRunnerDelegate delegate; |
| - gin::ShellRunner runner(&delegate, instance.isolate()); |
| - delegate.Start(&runner, pipe, module); |
| +class ContentHandlerImpl : public InterfaceImpl<ContentHandler> { |
| + public: |
| + explicit ContentHandlerImpl(ContentHandlerApp* content_handler_app) |
| + : content_handler_app_(content_handler_app) { |
| + } |
| + virtual ~ContentHandlerImpl() {} |
| - base::MessageLoop::current()->Run(); |
| + private: |
| + virtual void OnConnect(const mojo::String& url, |
| + URLResponsePtr content, |
| + ServiceProviderPtr service_provider) MOJO_OVERRIDE; |
| + |
| + ContentHandlerApp* content_handler_app_; |
| +}; |
| + |
| +// TODO(hansmuller); does this class define the right lifetime |
| +// for its gin members? |
| +class ContentHandlerApp : public ApplicationDelegate { |
|
Aaron Boodman
2014/08/25 17:25:37
Nit: the naming of this kind of confused me... I t
hansmuller
2014/08/26 23:39:12
I've renamed the class JSApp. It bugs me that the
|
| + public: |
| + ContentHandlerApp() |
| + : isolate_holder_(gin::IsolateHolder::kStrictMode), |
| + content_handler_factory_(this) { |
| + base::i18n::InitializeICU(); |
| + shell_runner_.reset( |
| + new gin::ShellRunner(&runner_delegate_, isolate_holder_.isolate())); |
| + } |
| + |
| + virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) |
| + MOJO_OVERRIDE { |
| + connection->AddService(&content_handler_factory_); |
| + return true; |
| + } |
| + |
| + void LoadMainJSModule(const std::string& module, const std::string& path) { |
| + // TODO(hansmuller): is this the right place to put the stack |
| + // frame capturer? |
| + { |
| + gin::Runner::Scope scope(shell_runner_.get()); |
| + v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); |
| + } |
| + |
| + base::MessageLoop::current()->PostTask(FROM_HERE, |
|
darin (slow to review)
2014/08/26 05:23:22
why do you need to use PostTask here?
hansmuller
2014/08/26 23:39:12
It's not necessary to use PostTask. I've removed i
|
| + base::Bind(apps::Run, shell_runner_->GetWeakPtr(), module, path)); |
| + } |
| + |
| + private: |
| + gin::IsolateHolder isolate_holder_; |
| + scoped_ptr<gin::ShellRunner> shell_runner_; |
| + apps::MojoRunnerDelegate runner_delegate_; |
| + InterfaceFactoryImplWithContext< |
| + ContentHandlerImpl, ContentHandlerApp> content_handler_factory_; |
| +}; |
| + |
| +void ContentHandlerImpl::OnConnect( |
| + const mojo::String& url, |
| + URLResponsePtr content, |
| + ServiceProviderPtr service_provider) { |
| + |
| + std::string path(url.To<std::string>()); |
| + std::string module; |
| + // TODO(hansmuller): is this the right place to block and load the |
|
Aaron Boodman
2014/08/25 17:25:37
I agree with your comment that it would be better
hansmuller
2014/08/26 23:39:12
OK, I'll add async loading of JS modules in a subs
|
| + // initial JS module? |
| + // TODO(hansmuller): check the return value and fail gracefully. |
| + common::BlockingCopyToString(content->body.Pass(), &module); |
| + |
| + content_handler_app_->LoadMainJSModule(module, path); |
|
Aaron Boodman
2014/08/25 17:25:37
Remember that OnConnect() can get called multiple
hansmuller
2014/08/26 23:39:12
It looks like I should to wait for your CL (https:
Aaron Boodman
2014/08/27 05:55:53
I think that you could structure the code to have
|
| } |
| } // namespace apps |
| } // namespace mojo |
| -extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { |
| - mojo::apps::Start(pipe, "mojo/apps/js/main"); |
| - return MOJO_RESULT_OK; |
| +MojoResult MojoMain(MojoHandle shell_handle) { |
| + mojo::ApplicationRunnerChromium runner(new mojo::apps::ContentHandlerApp()); |
| + return runner.Run(shell_handle); |
| } |
| + |