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

Side by Side Diff: services/dart/content_handler_app.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.h ('k') | services/dart/content_handler_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4 #include "services/dart/content_handler_app.h"
5
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/dart/embedder/dart_controller.h"
13 #include "mojo/public/cpp/application/application_impl.h"
14 #include "mojo/public/cpp/application/connect.h"
15 #include "mojo/public/cpp/bindings/binding.h"
16 #include "mojo/public/cpp/bindings/interface_request.h"
17 #include "mojo/services/tracing/interfaces/tracing.mojom.h"
18 #include "services/dart/dart_app.h"
19 #include "url/gurl.h"
20
21 namespace dart {
22
23 // Flags for the content handler:
24 const char kDartTimeline[] = "--dart-timeline";
25 const char kDisableObservatory[] = "--disable-observatory";
26 const char kEnableStrictMode[] = "--enable-strict-mode";
27 const char kRunOnMessageLoop[] = "--run-on-message-loop";
28 const char kTraceStartup[] = "--trace-startup";
29 // Flags forwarded to the Dart VM:
30 const char kCompleteTimeline[] = "--complete-timeline";
31 const char kPauseIsolatesOnStart[] = "--pause-isolates-on-start";
32 const char kPauseIsolatesOnExit[] = "--pause-isolates-on-exit";
33
34 static bool IsDartZip(std::string url) {
35 // If the url doesn't end with ".dart" we assume it is a zipped up
36 // dart application.
37 return !base::EndsWith(url, ".dart", base::CompareCase::INSENSITIVE_ASCII);
38 }
39
40 // Returns true if |requestedUrl| has a boolean query parameter named |param|.
41 static bool HasBoolQueryParam(const std::string& requestedUrl,
42 const std::string& param) {
43 std::string param_true = param + "=true";
44 std::string param_false = param + "=false";
45
46 GURL url(requestedUrl);
47 if (url.has_query()) {
48 std::vector<std::string> query_parameters = base::SplitString(
49 url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
50 bool has_true = std::find(query_parameters.begin(), query_parameters.end(),
51 param_true) != query_parameters.end();
52 bool has_false = std::find(query_parameters.begin(), query_parameters.end(),
53 param_false) != query_parameters.end();
54 return has_true || has_false;
55 }
56 return false;
57 }
58
59 // Returns the value of the boolean query parameter named |param|, or
60 // |default_value| if it |param| is not present.
61 static bool BoolQueryParamValue(const std::string& requestedUrl,
62 const std::string& param,
63 bool default_value) {
64 if (!HasBoolQueryParam(requestedUrl, param)) {
65 return default_value;
66 }
67 std::string param_true = param + "=true";
68 std::string param_false = param + "=false";
69 GURL url(requestedUrl);
70 DCHECK(url.has_query());
71 std::vector<std::string> query_parameters = base::SplitString(
72 url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
73 bool has_true = std::find(query_parameters.begin(), query_parameters.end(),
74 param_true) != query_parameters.end();
75 bool has_false = std::find(query_parameters.begin(), query_parameters.end(),
76 param_false) != query_parameters.end();
77 if (has_true) {
78 return has_true;
79 }
80 if (has_false) {
81 return false;
82 }
83 return default_value;
84 }
85
86 static bool HasStrictQueryParam(const std::string& requestedUrl) {
87 return BoolQueryParamValue(requestedUrl, "strict", false);
88 }
89
90 DartContentHandler::DartContentHandler(DartContentHandlerApp* app, bool strict)
91 : app_(app), strict_(strict) {}
92
93 void DartContentHandler::set_handler_task_runner(
94 scoped_refptr<base::SingleThreadTaskRunner> handler_task_runner) {
95 handler_task_runner_ = handler_task_runner;
96 }
97
98 DartContentHandlerApp::DartContentHandlerApp()
99 : content_handler_(this, false),
100 strict_content_handler_(this, true),
101 service_connector_(nullptr),
102 default_strict_(false),
103 run_on_message_loop_(false) {}
104
105 DartContentHandlerApp::~DartContentHandlerApp() {
106 // Shutdown the controller.
107 mojo::dart::DartController::Shutdown();
108 delete service_connector_;
109 }
110
111 void DartContentHandlerApp::ExtractApplication(base::FilePath* application_dir,
112 mojo::URLResponsePtr response,
113 const base::Closure& callback) {
114 url_response_disk_cache_->UpdateAndGetExtracted(
115 response.Pass(),
116 [application_dir, callback](mojo::Array<uint8_t> application_dir_path,
117 mojo::Array<uint8_t> cache_path) {
118 if (application_dir_path.is_null()) {
119 *application_dir = base::FilePath();
120 } else {
121 *application_dir = base::FilePath(std::string(
122 reinterpret_cast<char*>(&application_dir_path.front()),
123 application_dir_path.size()));
124 }
125 callback.Run();
126 });
127 }
128
129 bool DartContentHandlerApp::run_on_message_loop() const {
130 return run_on_message_loop_;
131 }
132
133 void DartContentHandlerApp::Initialize(mojo::ApplicationImpl* app) {
134 // Tracing of content handler and controller.
135 tracing_.Initialize(app);
136 // Tracing of isolates and VM.
137 dart_tracing_.Initialize(app);
138
139 // TODO(qsr): This has no effect for now, as the tracing infrastructure
140 // doesn't allow to trace anything before the tracing app connects to the
141 // application.
142 TRACE_EVENT0("dart_content_handler", "DartContentHandler::Initialize");
143
144 default_strict_ = app->HasArg(kEnableStrictMode);
145 content_handler_.set_handler_task_runner(
146 base::MessageLoop::current()->task_runner());
147 strict_content_handler_.set_handler_task_runner(
148 base::MessageLoop::current()->task_runner());
149 mojo::ConnectToService(app->shell(), "mojo:url_response_disk_cache",
150 GetProxy(&url_response_disk_cache_));
151 service_connector_ = new ContentHandlerAppServiceConnector(app);
152
153 if (app->HasArg(kRunOnMessageLoop)) {
154 run_on_message_loop_ = true;
155 }
156
157 bool enable_observatory = true;
158 if (app->HasArg(kDisableObservatory)) {
159 enable_observatory = false;
160 }
161
162 bool enable_dart_timeline = false;
163 if (app->HasArg(kDartTimeline)) {
164 enable_dart_timeline = true;
165 }
166
167 std::vector<const char*> extra_args;
168
169 if (app->HasArg(kPauseIsolatesOnStart)) {
170 extra_args.push_back(kPauseIsolatesOnStart);
171 }
172
173 if (app->HasArg(kPauseIsolatesOnExit)) {
174 extra_args.push_back(kPauseIsolatesOnExit);
175 }
176
177 if (app->HasArg(kCompleteTimeline)) {
178 extra_args.push_back(kCompleteTimeline);
179 }
180
181 bool success = mojo::dart::DartController::Initialize(
182 service_connector_, default_strict_, enable_observatory,
183 enable_dart_timeline, extra_args.data(), extra_args.size());
184
185 if (app->HasArg(kTraceStartup)) {
186 DartTimelineController::EnableAll();
187 }
188 if (!success) {
189 LOG(ERROR) << "Dart VM Initialization failed";
190 }
191 }
192
193 bool DartContentHandlerApp::ConfigureIncomingConnection(
194 mojo::ServiceProviderImpl* service_provider_impl) {
195 bool strict = HasStrictQueryParam(
196 service_provider_impl->connection_context().connection_url);
197 if (default_strict_ || strict) {
198 service_provider_impl->AddService<mojo::ContentHandler>(
199 mojo::ContentHandlerFactory::GetInterfaceRequestHandler(
200 &strict_content_handler_));
201 } else {
202 service_provider_impl->AddService<mojo::ContentHandler>(
203 mojo::ContentHandlerFactory::GetInterfaceRequestHandler(
204 &content_handler_));
205 }
206 return true;
207 }
208
209 scoped_ptr<mojo::ContentHandlerFactory::HandledApplicationHolder>
210 DartContentHandler::CreateApplication(
211 mojo::InterfaceRequest<mojo::Application> application_request,
212 mojo::URLResponsePtr response) {
213 base::trace_event::TraceLog::GetInstance()
214 ->SetCurrentThreadBlocksMessageLoop();
215
216 TRACE_EVENT1("dart_content_handler", "DartContentHandler::CreateApplication",
217 "url", response->url.get());
218
219 const bool run_on_message_loop = app_->run_on_message_loop();
220 base::FilePath application_dir;
221 std::string url = response->url.get();
222 const char* kPauseIsolatesOnStart = "pauseIsolatesOnStart";
223 const char* kPauseIsolatesOnExit = "pauseIsolatesOnExit";
224 const bool override_pause_isolates_flags =
225 HasBoolQueryParam(url, kPauseIsolatesOnStart) ||
226 HasBoolQueryParam(url, kPauseIsolatesOnExit);
227 const bool pause_isolates_on_start = BoolQueryParamValue(
228 url, kPauseIsolatesOnStart,
229 mojo::dart::DartControllerConfig::kDefaultPauseOnStart);
230 const bool pause_isolates_on_exit = BoolQueryParamValue(
231 url, kPauseIsolatesOnExit,
232 mojo::dart::DartControllerConfig::kDefaultPauseOnExit);
233 if (IsDartZip(response->url.get())) {
234 // Loading a zipped snapshot:
235 // 1) Extract the zip file.
236 // 2) Launch from temporary directory (|application_dir|).
237 handler_task_runner_->PostTask(
238 FROM_HERE,
239 base::Bind(
240 &DartContentHandlerApp::ExtractApplication, base::Unretained(app_),
241 base::Unretained(&application_dir), base::Passed(response.Pass()),
242 base::Bind(
243 base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
244 base::MessageLoop::current()->task_runner(), FROM_HERE,
245 base::MessageLoop::QuitWhenIdleClosure())));
246 base::RunLoop().Run();
247 return make_scoped_ptr(
248 new DartApp(application_request.Pass(), url, application_dir, strict_,
249 run_on_message_loop, override_pause_isolates_flags,
250 pause_isolates_on_start, pause_isolates_on_exit));
251 } else {
252 // Loading a raw .dart file pointed at by |url|.
253 return make_scoped_ptr(
254 new DartApp(application_request.Pass(), url, strict_,
255 run_on_message_loop, override_pause_isolates_flags,
256 pause_isolates_on_start, pause_isolates_on_exit));
257 }
258 }
259
260 } // namespace dart
OLDNEW
« no previous file with comments | « services/dart/content_handler_app.h ('k') | services/dart/content_handler_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698