Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdio.h> | |
| 6 | |
| 7 #include "base/at_exit.h" | |
| 8 #include "base/bind.h" | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/i18n/icu_util.h" | |
| 5 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/path_service.h" | |
| 13 #include "gin/converter.h" | |
| 14 #include "gin/modules/console.h" | |
| 15 #include "gin/modules/module_registry.h" | |
| 16 #include "gin/modules/module_runner_delegate.h" | |
| 6 #include "gin/public/isolate_holder.h" | 17 #include "gin/public/isolate_holder.h" |
| 7 #include "mojo/apps/js/mojo_runner_delegate.h" | 18 #include "gin/test/file_runner.h" |
| 8 #include "mojo/public/cpp/system/core.h" | 19 #include "gin/try_catch.h" |
| 9 #include "mojo/public/cpp/system/macros.h" | 20 #include "mojo/apps/js/bindings/gl/module.h" |
| 10 | 21 #include "mojo/apps/js/bindings/threading.h" |
| 11 #if defined(WIN32) | 22 #include "mojo/bindings/js/core.h" |
| 12 #if !defined(CDECL) | 23 #include "mojo/bindings/js/handle.h" |
| 13 #define CDECL __cdecl | 24 #include "mojo/bindings/js/support.h" |
| 14 #endif | 25 #include "mojo/common/data_pipe_utils.h" |
| 15 #define MOJO_APPS_JS_EXPORT __declspec(dllexport) | 26 #include "mojo/public/c/system/main.h" |
| 16 #else | 27 #include "mojo/public/cpp/application/application_delegate.h" |
| 17 #define CDECL | 28 #include "mojo/public/cpp/application/application_impl.h" |
| 18 #define MOJO_APPS_JS_EXPORT __attribute__((visibility("default"))) | 29 #include "mojo/public/cpp/application/application_runner_chromium.h" |
| 19 #endif | 30 #include "mojo/public/cpp/application/interface_factory_impl.h" |
| 31 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h" | |
| 20 | 32 |
| 21 namespace mojo { | 33 namespace mojo { |
| 22 namespace apps { | 34 namespace apps { |
| 35 namespace { | |
| 23 | 36 |
| 24 void Start(MojoHandle pipe, const std::string& module) { | 37 std::vector<base::FilePath> GetModuleSearchPaths() { |
| 25 base::MessageLoop loop; | 38 std::vector<base::FilePath> module_base(1); |
| 39 CHECK(base::GetCurrentDirectory(&module_base[0])); | |
| 40 return module_base; | |
| 41 } | |
| 26 | 42 |
| 27 gin::IsolateHolder instance(gin::IsolateHolder::kStrictMode); | 43 void Run( |
| 28 MojoRunnerDelegate delegate; | 44 base::WeakPtr<gin::Runner> runner, |
| 29 gin::ShellRunner runner(&delegate, instance.isolate()); | 45 const std::string& code, |
| 30 delegate.Start(&runner, pipe, module); | 46 const std::string& path) { |
| 47 if (!runner) | |
| 48 return; | |
| 49 gin::Runner::Scope scope(runner.get()); | |
| 50 runner->Run(code.c_str(), path.c_str()); | |
| 51 } | |
| 31 | 52 |
| 32 base::MessageLoop::current()->Run(); | 53 class MojoRunnerDelegate : public gin::ModuleRunnerDelegate { |
| 54 public: | |
| 55 MojoRunnerDelegate() : gin::ModuleRunnerDelegate(GetModuleSearchPaths()) { | |
| 56 AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetModule); | |
| 57 } | |
| 58 | |
| 59 virtual void UnhandledException(gin::ShellRunner* runner, | |
| 60 gin::TryCatch& try_catch) OVERRIDE { | |
| 61 gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch); | |
| 62 LOG(ERROR) << try_catch.GetStackTrace(); | |
| 63 } | |
| 64 | |
| 65 private: | |
| 66 DISALLOW_COPY_AND_ASSIGN(MojoRunnerDelegate); | |
| 67 }; | |
| 68 | |
| 69 } // namespace | |
| 70 | |
| 71 | |
| 72 class ContentHandlerApp; | |
| 73 | |
| 74 class ContentHandlerImpl : public InterfaceImpl<ContentHandler> { | |
| 75 public: | |
| 76 explicit ContentHandlerImpl(ContentHandlerApp* content_handler_app) | |
| 77 : content_handler_app_(content_handler_app) { | |
| 78 } | |
| 79 virtual ~ContentHandlerImpl() {} | |
| 80 | |
| 81 private: | |
| 82 virtual void OnConnect(const mojo::String& url, | |
| 83 URLResponsePtr content, | |
| 84 ServiceProviderPtr service_provider) MOJO_OVERRIDE; | |
| 85 | |
| 86 ContentHandlerApp* content_handler_app_; | |
| 87 }; | |
| 88 | |
| 89 // TODO(hansmuller); does this class define the right lifetime | |
| 90 // for its gin members? | |
| 91 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
| |
| 92 public: | |
| 93 ContentHandlerApp() | |
| 94 : isolate_holder_(gin::IsolateHolder::kStrictMode), | |
| 95 content_handler_factory_(this) { | |
| 96 base::i18n::InitializeICU(); | |
| 97 shell_runner_.reset( | |
| 98 new gin::ShellRunner(&runner_delegate_, isolate_holder_.isolate())); | |
| 99 } | |
| 100 | |
| 101 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) | |
| 102 MOJO_OVERRIDE { | |
| 103 connection->AddService(&content_handler_factory_); | |
| 104 return true; | |
| 105 } | |
| 106 | |
| 107 void LoadMainJSModule(const std::string& module, const std::string& path) { | |
| 108 // TODO(hansmuller): is this the right place to put the stack | |
| 109 // frame capturer? | |
| 110 { | |
| 111 gin::Runner::Scope scope(shell_runner_.get()); | |
| 112 v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); | |
| 113 } | |
| 114 | |
| 115 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
| |
| 116 base::Bind(apps::Run, shell_runner_->GetWeakPtr(), module, path)); | |
| 117 } | |
| 118 | |
| 119 private: | |
| 120 gin::IsolateHolder isolate_holder_; | |
| 121 scoped_ptr<gin::ShellRunner> shell_runner_; | |
| 122 apps::MojoRunnerDelegate runner_delegate_; | |
| 123 InterfaceFactoryImplWithContext< | |
| 124 ContentHandlerImpl, ContentHandlerApp> content_handler_factory_; | |
| 125 }; | |
| 126 | |
| 127 void ContentHandlerImpl::OnConnect( | |
| 128 const mojo::String& url, | |
| 129 URLResponsePtr content, | |
| 130 ServiceProviderPtr service_provider) { | |
| 131 | |
| 132 std::string path(url.To<std::string>()); | |
| 133 std::string module; | |
| 134 // 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
| |
| 135 // initial JS module? | |
| 136 // TODO(hansmuller): check the return value and fail gracefully. | |
| 137 common::BlockingCopyToString(content->body.Pass(), &module); | |
| 138 | |
| 139 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
| |
| 33 } | 140 } |
| 34 | 141 |
| 35 } // namespace apps | 142 } // namespace apps |
| 36 } // namespace mojo | 143 } // namespace mojo |
| 37 | 144 |
| 38 extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { | 145 MojoResult MojoMain(MojoHandle shell_handle) { |
| 39 mojo::apps::Start(pipe, "mojo/apps/js/main"); | 146 mojo::ApplicationRunnerChromium runner(new mojo::apps::ContentHandlerApp()); |
| 40 return MOJO_RESULT_OK; | 147 return runner.Run(shell_handle); |
| 41 } | 148 } |
| 149 | |
| OLD | NEW |