Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1347)

Side by Side Diff: services/dart/content_handler_main.cc

Issue 2004403003: Build library for the Dart Content Handler. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/dart/content_handler_app.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 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
5 #include "base/bind.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "base/strings/string_split.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "base/threading/platform_thread.h"
11 #include "base/trace_event/trace_event.h"
12 #include "mojo/application/application_runner_chromium.h" 4 #include "mojo/application/application_runner_chromium.h"
13 #include "mojo/application/content_handler_factory.h"
14 #include "mojo/common/tracing_impl.h"
15 #include "mojo/dart/embedder/dart_controller.h"
16 #include "mojo/public/c/system/main.h" 5 #include "mojo/public/c/system/main.h"
17 #include "mojo/public/cpp/application/application_delegate.h" 6 #include "services/dart/content_handler_app.h"
18 #include "mojo/public/cpp/application/application_impl.h"
19 #include "mojo/public/cpp/application/connect.h"
20 #include "mojo/public/cpp/bindings/binding.h"
21 #include "mojo/public/cpp/bindings/interface_request.h"
22 #include "mojo/services/tracing/interfaces/tracing.mojom.h"
23 #include "mojo/services/url_response_disk_cache/interfaces/url_response_disk_cac he.mojom.h"
24 #include "services/dart/content_handler_app_service_connector.h"
25 #include "services/dart/dart_app.h"
26 #include "services/dart/dart_tracing.h"
27 #include "url/gurl.h"
28
29 namespace dart {
30
31 // Flags for the content handler:
32 const char kDartTimeline[] = "--dart-timeline";
33 const char kDisableObservatory[] = "--disable-observatory";
34 const char kEnableStrictMode[] = "--enable-strict-mode";
35 const char kRunOnMessageLoop[] = "--run-on-message-loop";
36 const char kTraceStartup[] = "--trace-startup";
37 // Flags forwarded to the Dart VM:
38 const char kCompleteTimeline[] = "--complete-timeline";
39 const char kPauseIsolatesOnStart[] = "--pause-isolates-on-start";
40 const char kPauseIsolatesOnExit[] = "--pause-isolates-on-exit";
41
42 static bool IsDartZip(std::string url) {
43 // If the url doesn't end with ".dart" we assume it is a zipped up
44 // dart application.
45 return !base::EndsWith(url, ".dart", base::CompareCase::INSENSITIVE_ASCII);
46 }
47
48 // Returns true if |requestedUrl| has a boolean query parameter named |param|.
49 static bool HasBoolQueryParam(const std::string& requestedUrl,
50 const std::string& param) {
51 std::string param_true = param + "=true";
52 std::string param_false = param + "=false";
53
54 GURL url(requestedUrl);
55 if (url.has_query()) {
56 std::vector<std::string> query_parameters = base::SplitString(
57 url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
58 bool has_true =
59 std::find(query_parameters.begin(),
60 query_parameters.end(),
61 param_true) != query_parameters.end();
62 bool has_false =
63 std::find(query_parameters.begin(),
64 query_parameters.end(),
65 param_false) != query_parameters.end();
66 return has_true || has_false;
67 }
68 return false;
69 }
70
71 // Returns the value of the boolean query parameter named |param|, or
72 // |default_value| if it |param| is not present.
73 static bool BoolQueryParamValue(const std::string& requestedUrl,
74 const std::string& param,
75 bool default_value) {
76 if (!HasBoolQueryParam(requestedUrl, param)) {
77 return default_value;
78 }
79 std::string param_true = param + "=true";
80 std::string param_false = param + "=false";
81 GURL url(requestedUrl);
82 DCHECK(url.has_query());
83 std::vector<std::string> query_parameters = base::SplitString(
84 url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
85 bool has_true =
86 std::find(query_parameters.begin(),
87 query_parameters.end(),
88 param_true) != query_parameters.end();
89 bool has_false =
90 std::find(query_parameters.begin(),
91 query_parameters.end(),
92 param_false) != query_parameters.end();
93 if (has_true) {
94 return has_true;
95 }
96 if (has_false) {
97 return false;
98 }
99 return default_value;
100 }
101
102 static bool HasStrictQueryParam(const std::string& requestedUrl) {
103 return BoolQueryParamValue(requestedUrl, "strict", false);
104 }
105
106 class DartContentHandlerApp;
107
108 class DartContentHandler : public mojo::ContentHandlerFactory::ManagedDelegate {
109 public:
110 DartContentHandler(DartContentHandlerApp* app, bool strict)
111 : app_(app), strict_(strict) {
112 }
113
114 void set_handler_task_runner(
115 scoped_refptr<base::SingleThreadTaskRunner> handler_task_runner) {
116 handler_task_runner_ = handler_task_runner;
117 }
118
119 private:
120 // Overridden from ContentHandlerFactory::ManagedDelegate:
121 scoped_ptr<mojo::ContentHandlerFactory::HandledApplicationHolder>
122 CreateApplication(
123 mojo::InterfaceRequest<mojo::Application> application_request,
124 mojo::URLResponsePtr response) override;
125
126 DartContentHandlerApp* app_;
127 bool strict_;
128 scoped_refptr<base::SingleThreadTaskRunner> handler_task_runner_;
129
130 DISALLOW_COPY_AND_ASSIGN(DartContentHandler);
131 };
132
133 class DartContentHandlerApp : public mojo::ApplicationDelegate {
134 public:
135 DartContentHandlerApp()
136 : content_handler_(this, false),
137 strict_content_handler_(this, true),
138 service_connector_(nullptr),
139 default_strict_(false),
140 run_on_message_loop_(false) {}
141
142 ~DartContentHandlerApp() override {
143 // Shutdown the controller.
144 mojo::dart::DartController::Shutdown();
145 delete service_connector_;
146 }
147
148 void ExtractApplication(base::FilePath* application_dir,
149 mojo::URLResponsePtr response,
150 const base::Closure& callback) {
151 url_response_disk_cache_->UpdateAndGetExtracted(
152 response.Pass(),
153 [application_dir, callback](mojo::Array<uint8_t> application_dir_path,
154 mojo::Array<uint8_t> cache_path) {
155 if (application_dir_path.is_null()) {
156 *application_dir = base::FilePath();
157 } else {
158 *application_dir = base::FilePath(std::string(
159 reinterpret_cast<char*>(&application_dir_path.front()),
160 application_dir_path.size()));
161 }
162 callback.Run();
163 });
164 }
165
166 bool run_on_message_loop() const {
167 return run_on_message_loop_;
168 }
169
170 private:
171 // Overridden from mojo::ApplicationDelegate:
172 void Initialize(mojo::ApplicationImpl* app) override {
173 // Tracing of content handler and controller.
174 tracing_.Initialize(app);
175 // Tracing of isolates and VM.
176 dart_tracing_.Initialize(app);
177
178 // TODO(qsr): This has no effect for now, as the tracing infrastructure
179 // doesn't allow to trace anything before the tracing app connects to the
180 // application.
181 TRACE_EVENT0("dart_content_handler", "DartContentHandler::Initialize");
182
183 default_strict_ = app->HasArg(kEnableStrictMode);
184 content_handler_.set_handler_task_runner(
185 base::MessageLoop::current()->task_runner());
186 strict_content_handler_.set_handler_task_runner(
187 base::MessageLoop::current()->task_runner());
188 mojo::ConnectToService(app->shell(), "mojo:url_response_disk_cache",
189 GetProxy(&url_response_disk_cache_));
190 service_connector_ = new ContentHandlerAppServiceConnector(app);
191
192 if (app->HasArg(kRunOnMessageLoop)) {
193 run_on_message_loop_ = true;
194 }
195
196 bool enable_observatory = true;
197 if (app->HasArg(kDisableObservatory)) {
198 enable_observatory = false;
199 }
200
201 bool enable_dart_timeline = false;
202 if (app->HasArg(kDartTimeline)) {
203 enable_dart_timeline = true;
204 }
205
206 std::vector<const char*> extra_args;
207
208 if (app->HasArg(kPauseIsolatesOnStart)) {
209 extra_args.push_back(kPauseIsolatesOnStart);
210 }
211
212 if (app->HasArg(kPauseIsolatesOnExit)) {
213 extra_args.push_back(kPauseIsolatesOnExit);
214 }
215
216 if (app->HasArg(kCompleteTimeline)) {
217 extra_args.push_back(kCompleteTimeline);
218 }
219
220 bool success = mojo::dart::DartController::Initialize(
221 service_connector_,
222 default_strict_,
223 enable_observatory,
224 enable_dart_timeline,
225 extra_args.data(),
226 extra_args.size());
227
228 if (app->HasArg(kTraceStartup)) {
229 DartTimelineController::EnableAll();
230 }
231 if (!success) {
232 LOG(ERROR) << "Dart VM Initialization failed";
233 }
234 }
235
236 // Overridden from ApplicationDelegate:
237 bool ConfigureIncomingConnection(
238 mojo::ServiceProviderImpl* service_provider_impl) override {
239 bool strict = HasStrictQueryParam(
240 service_provider_impl->connection_context().connection_url);
241 if (default_strict_ || strict) {
242 service_provider_impl->AddService<mojo::ContentHandler>(
243 mojo::ContentHandlerFactory::GetInterfaceRequestHandler(
244 &strict_content_handler_));
245 } else {
246 service_provider_impl->AddService<mojo::ContentHandler>(
247 mojo::ContentHandlerFactory::GetInterfaceRequestHandler(
248 &content_handler_));
249 }
250 return true;
251 }
252
253 mojo::TracingImpl tracing_;
254 DartContentHandler content_handler_;
255 DartContentHandler strict_content_handler_;
256 mojo::URLResponseDiskCachePtr url_response_disk_cache_;
257 ContentHandlerAppServiceConnector* service_connector_;
258 DartTracingImpl dart_tracing_;
259 bool default_strict_;
260 bool run_on_message_loop_;
261
262 DISALLOW_COPY_AND_ASSIGN(DartContentHandlerApp);
263 };
264
265 scoped_ptr<mojo::ContentHandlerFactory::HandledApplicationHolder>
266 DartContentHandler::CreateApplication(
267 mojo::InterfaceRequest<mojo::Application> application_request,
268 mojo::URLResponsePtr response) {
269 base::trace_event::TraceLog::GetInstance()
270 ->SetCurrentThreadBlocksMessageLoop();
271
272 TRACE_EVENT1("dart_content_handler", "DartContentHandler::CreateApplication",
273 "url", response->url.get());
274
275 const bool run_on_message_loop = app_->run_on_message_loop();
276 base::FilePath application_dir;
277 std::string url = response->url.get();
278 const char* kPauseIsolatesOnStart = "pauseIsolatesOnStart";
279 const char* kPauseIsolatesOnExit = "pauseIsolatesOnExit";
280 const bool override_pause_isolates_flags =
281 HasBoolQueryParam(url, kPauseIsolatesOnStart) ||
282 HasBoolQueryParam(url, kPauseIsolatesOnExit);
283 const bool pause_isolates_on_start = BoolQueryParamValue(
284 url,
285 kPauseIsolatesOnStart,
286 mojo::dart::DartControllerConfig::kDefaultPauseOnStart);
287 const bool pause_isolates_on_exit = BoolQueryParamValue(
288 url,
289 kPauseIsolatesOnExit,
290 mojo::dart::DartControllerConfig::kDefaultPauseOnExit);
291 if (IsDartZip(response->url.get())) {
292 // Loading a zipped snapshot:
293 // 1) Extract the zip file.
294 // 2) Launch from temporary directory (|application_dir|).
295 handler_task_runner_->PostTask(
296 FROM_HERE,
297 base::Bind(
298 &DartContentHandlerApp::ExtractApplication, base::Unretained(app_),
299 base::Unretained(&application_dir), base::Passed(response.Pass()),
300 base::Bind(
301 base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
302 base::MessageLoop::current()->task_runner(), FROM_HERE,
303 base::MessageLoop::QuitWhenIdleClosure())));
304 base::RunLoop().Run();
305 return make_scoped_ptr(
306 new DartApp(application_request.Pass(),
307 url,
308 application_dir,
309 strict_,
310 run_on_message_loop,
311 override_pause_isolates_flags,
312 pause_isolates_on_start,
313 pause_isolates_on_exit));
314 } else {
315 // Loading a raw .dart file pointed at by |url|.
316 return make_scoped_ptr(
317 new DartApp(application_request.Pass(),
318 url,
319 strict_,
320 run_on_message_loop,
321 override_pause_isolates_flags,
322 pause_isolates_on_start,
323 pause_isolates_on_exit));
324 }
325 }
326
327 } // namespace dart
328 7
329 MojoResult MojoMain(MojoHandle application_request) { 8 MojoResult MojoMain(MojoHandle application_request) {
330 mojo::ApplicationRunnerChromium runner(new dart::DartContentHandlerApp); 9 mojo::ApplicationRunnerChromium runner(new dart::DartContentHandlerApp);
331 return runner.Run(application_request); 10 return runner.Run(application_request);
332 } 11 }
OLDNEW
« no previous file with comments | « services/dart/content_handler_app.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698