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 |