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

Side by Side Diff: mojo/shell/dynamic_application_loader.cc

Issue 694303002: Allow local file to run though content handler. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fix constants. Created 6 years, 1 month 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 | « mojo/shell/dynamic_application_loader.h ('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 4
5 #include "mojo/shell/dynamic_application_loader.h" 5 #include "mojo/shell/dynamic_application_loader.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/format_macros.h"
12 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h" 14 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
16 #include "mojo/common/common_type_converters.h" 19 #include "mojo/common/common_type_converters.h"
17 #include "mojo/common/data_pipe_utils.h" 20 #include "mojo/common/data_pipe_utils.h"
21 #include "mojo/public/cpp/system/data_pipe.h"
18 #include "mojo/services/public/interfaces/network/url_loader.mojom.h" 22 #include "mojo/services/public/interfaces/network/url_loader.mojom.h"
19 #include "mojo/shell/context.h" 23 #include "mojo/shell/context.h"
20 #include "mojo/shell/data_pipe_peek.h" 24 #include "mojo/shell/data_pipe_peek.h"
21 #include "mojo/shell/filename_util.h" 25 #include "mojo/shell/filename_util.h"
22 #include "mojo/shell/switches.h" 26 #include "mojo/shell/switches.h"
23 #include "url/url_util.h" 27 #include "url/url_util.h"
24 28
25 namespace mojo { 29 namespace mojo {
26 namespace shell { 30 namespace shell {
27 31
28 // Encapsulates loading and running one individual application. 32 namespace {
29 // 33
30 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must 34 static const char kMojoMagic[] = "#!mojo:";
31 // ensure that all the parameters passed to Loader subclasses stay valid through 35 static const size_t kMaxShebangLength = 2048;
32 // Loader's lifetime. 36
33 // 37 void IgnoreResult(bool result) {
34 // Async operations are done with WeakPtr to protect against 38 }
35 // DynamicApplicationLoader going away (and taking all the Loaders with it) 39
36 // while the async operation is outstanding. 40 // A request to load a given URL.
37 class DynamicApplicationLoader::Loader { 41 class LoaderRequest {
38 public: 42 public:
39 Loader(Context* context, 43 virtual ~LoaderRequest() {}
40 DynamicServiceRunnerFactory* runner_factory,
41 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
42 const LoaderCompleteCallback& loader_complete_callback)
43 : load_callbacks_(load_callbacks),
44 loader_complete_callback_(loader_complete_callback),
45 context_(context),
46 runner_factory_(runner_factory),
47 weak_ptr_factory_(this) {}
48 44
49 virtual ~Loader() {} 45 virtual URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
46 uint32_t skip) = 0;
47
48 virtual void AsPath(
49 base::TaskRunner* task_runner,
50 base::Callback<void(const base::FilePath&, bool)> callback) = 0;
51
52 bool PeekContentHandler(std::string* mojo_shebang,
Aaron Boodman 2014/11/07 08:56:27 I would prefer this function in loader, and make L
53 GURL* mojo_content_handler_url) {
54 std::string shebang;
55 if (HasMojoMagic() && PeekFirstLine(&shebang)) {
56 GURL url(shebang.substr(2, std::string::npos));
57 if (url.is_valid()) {
58 *mojo_shebang = shebang;
59 *mojo_content_handler_url = url;
60 return true;
61 }
62 }
63 return false;
64 }
65
66 virtual std::string MimeType() = 0;
50 67
51 protected: 68 protected:
52 void RunLibrary(const base::FilePath& path, bool path_exists) { 69 virtual bool HasMojoMagic() = 0;
53 ScopedMessagePipeHandle shell_handle = 70 virtual bool PeekFirstLine(std::string* line) = 0;
54 load_callbacks_->RegisterApplication(); 71 };
55 if (!shell_handle.is_valid()) { 72
56 LoaderComplete(); 73 // A request to load a remote URL.
74 class NetworkLoaderRequest : public LoaderRequest {
75 public:
76 NetworkLoaderRequest(const GURL& url,
77 NetworkService* network_service,
78 const base::Callback<void(bool)>& completion_callback)
79 : completion_callback_(completion_callback), weak_ptr_factory_(this) {
80 Load(url, network_service);
81 }
82
83 ~NetworkLoaderRequest() override {
84 if (!path_.empty())
85 base::DeleteFile(path_, false);
86 }
87
88 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
89 uint32_t skip) override {
90 if (skip != 0) {
91 MojoResult result = ReadDataRaw(
92 response_->body.get(), nullptr, &skip,
93 MOJO_READ_DATA_FLAG_ALL_OR_NONE | MOJO_READ_DATA_FLAG_DISCARD);
94 DCHECK_EQ(result, MOJO_RESULT_OK);
95 }
96 return response_.Pass();
97 }
98
99 void AsPath(
100 base::TaskRunner* task_runner,
101 base::Callback<void(const base::FilePath&, bool)> callback) override {
102 if (!path_.empty() || !response_) {
103 base::MessageLoop::current()->PostTask(
104 FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
57 return; 105 return;
58 } 106 }
107 base::CreateTemporaryFile(&path_);
108 common::CopyToFile(response_->body.Pass(), path_, task_runner,
109 base::Bind(callback, path_));
110 }
59 111
60 if (!path_exists) { 112 std::string MimeType() override {
61 LOG(ERROR) << "Library not started because library path '" << path.value() 113 DCHECK(response_);
62 << "' does not exist."; 114 return response_->mime_type;
63 LoaderComplete(); 115 }
116
117 private:
118 // TODO(hansmuller): Revisit this when a real peek operation is available.
119 static const MojoDeadline kPeekTimeout = MOJO_DEADLINE_INDEFINITE;
120
121 bool HasMojoMagic() override {
122 std::string magic;
123 return BlockingPeekNBytes(response_->body.get(), &magic, strlen(kMojoMagic),
124 kPeekTimeout) &&
125 magic == kMojoMagic;
126 }
127
128 bool PeekFirstLine(std::string* line) override {
129 return BlockingPeekLine(response_->body.get(), line, kMaxShebangLength,
130 kPeekTimeout);
131 }
132
133 void Load(const GURL& url, NetworkService* network_service) {
134 URLRequestPtr request(URLRequest::New());
135 request->url = String::From(url);
136 request->auto_follow_redirects = true;
137
138 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
139 switches::kDisableCache)) {
140 request->bypass_cache = true;
141 }
142
143 network_service->CreateURLLoader(GetProxy(&url_loader_));
144 url_loader_->Start(request.Pass(),
145 base::Bind(&NetworkLoaderRequest::OnLoadComplete,
146 weak_ptr_factory_.GetWeakPtr()));
147 }
148
149 void OnLoadComplete(URLResponsePtr response) {
150 if (response->error) {
151 LOG(ERROR) << "Error (" << response->error->code << ": "
152 << response->error->description << ") while fetching "
153 << response->url;
154 completion_callback_.Run(false);
64 return; 155 return;
65 } 156 }
66 157 response_ = response.Pass();
67 runner_ = runner_factory_->Create(context_); 158 completion_callback_.Run(true);
68 runner_->Start(
69 path,
70 shell_handle.Pass(),
71 base::Bind(&Loader::LoaderComplete, weak_ptr_factory_.GetWeakPtr()));
72 } 159 }
73 160
74 void LoaderComplete() { loader_complete_callback_.Run(this); } 161 base::Callback<void(bool)> completion_callback_;
162 URLLoaderPtr url_loader_;
163 URLResponsePtr response_;
164 base::FilePath path_;
165 base::WeakPtrFactory<NetworkLoaderRequest> weak_ptr_factory_;
75 166
76 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_; 167 DISALLOW_COPY_AND_ASSIGN(NetworkLoaderRequest);
77 LoaderCompleteCallback loader_complete_callback_; 168 };
78 Context* context_; 169
170 // A request to load a file URL.
171 class LocalLoaderRequest : public LoaderRequest {
172 public:
173 LocalLoaderRequest(const GURL& url,
174 const base::Callback<void(bool)>& completion_callback)
175 : url_(url), path_(UrlToFile(url)) {
176 base::MessageLoop::current()->PostTask(
177 FROM_HERE, base::Bind(completion_callback, true));
178 }
179
180 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner,
181 uint32_t skip) override {
182 URLResponsePtr response(URLResponse::New());
183 response->url = String::From(url_);
184 DataPipe data_pipe;
185 response->body = data_pipe.consumer_handle.Pass();
186 int64 file_size;
187 if (base::GetFileSize(path_, &file_size)) {
188 response->headers = Array<String>(1);
189 response->headers[0] =
190 base::StringPrintf("Content-Length: %" PRId64, file_size);
191 }
192 common::CopyFromFile(path_, data_pipe.producer_handle.Pass(), skip,
193 task_runner, base::Bind(&IgnoreResult));
194 return response.Pass();
195 }
196
197 void AsPath(
198 base::TaskRunner* task_runner,
199 base::Callback<void(const base::FilePath&, bool)> callback) override {
200 base::MessageLoop::current()->PostTask(
201 FROM_HERE, base::Bind(callback, path_, base::PathExists(path_)));
202 }
203
204 std::string MimeType() override { return ""; }
79 205
80 private: 206 private:
81 DynamicServiceRunnerFactory* runner_factory_; 207 static base::FilePath UrlToFile(const GURL& url) {
82 scoped_ptr<DynamicServiceRunner> runner_;
83 base::WeakPtrFactory<Loader> weak_ptr_factory_;
84 };
85
86 // A loader for local files.
87 class DynamicApplicationLoader::LocalLoader : public Loader {
88 public:
89 LocalLoader(const GURL& url,
90 Context* context,
91 DynamicServiceRunnerFactory* runner_factory,
92 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
93 const LoaderCompleteCallback& loader_complete_callback)
94 : Loader(context,
95 runner_factory,
96 load_callbacks,
97 loader_complete_callback),
98 weak_ptr_factory_(this) {
99 DCHECK(url.SchemeIsFile()); 208 DCHECK(url.SchemeIsFile());
100 url::RawCanonOutputW<1024> output; 209 url::RawCanonOutputW<1024> output;
101 url::DecodeURLEscapeSequences( 210 url::DecodeURLEscapeSequences(
102 url.path().data(), static_cast<int>(url.path().length()), &output); 211 url.path().data(), static_cast<int>(url.path().length()), &output);
103 base::string16 decoded_path = 212 base::string16 decoded_path =
104 base::string16(output.data(), output.length()); 213 base::string16(output.data(), output.length());
105 #if defined(OS_WIN) 214 #if defined(OS_WIN)
106 base::TrimString(decoded_path, L"/", &decoded_path); 215 base::TrimString(decoded_path, L"/", &decoded_path);
107 base::FilePath path(decoded_path); 216 base::FilePath path(decoded_path);
108 #else 217 #else
109 base::FilePath path(base::UTF16ToUTF8(decoded_path)); 218 base::FilePath path(base::UTF16ToUTF8(decoded_path));
110 #endif 219 #endif
111 220 return path;
112 // Async for consistency with network case.
113 base::MessageLoop::current()->PostTask(
114 FROM_HERE,
115 base::Bind(&LocalLoader::RunLibrary,
116 weak_ptr_factory_.GetWeakPtr(),
117 path,
118 base::PathExists(path)));
119 } 221 }
120 222
121 ~LocalLoader() override {} 223 bool HasMojoMagic() override {
224 std::string magic;
225 ReadFileToString(path_, &magic, strlen(kMojoMagic));
226 return magic == kMojoMagic;
227 }
228
229 bool PeekFirstLine(std::string* line) override {
230 std::string start_of_file;
231 ReadFileToString(path_, &start_of_file, kMaxShebangLength);
232 size_t return_position = start_of_file.find('\n');
233 if (return_position == std::string::npos)
234 return false;
235 *line = start_of_file.substr(0, return_position + 1);
236 return true;
237 }
238
239 GURL url_;
240 base::FilePath path_;
241
242 DISALLOW_COPY_AND_ASSIGN(LocalLoaderRequest);
243 };
244
245 } // namespace
246
247 // Encapsulates loading and running one individual application.
248 //
249 // Loaders are owned by DynamicApplicationLoader. DynamicApplicationLoader must
250 // ensure that all the parameters passed to Loader subclasses stay valid through
251 // Loader's lifetime.
252 //
253 // Async operations are done with WeakPtr to protect against
254 // DynamicApplicationLoader going away (and taking all the Loaders with it)
255 // while the async operation is outstanding.
256 class DynamicApplicationLoader::Loader {
257 public:
258 Loader(const GURL& url,
259 MimeTypeToURLMap* mime_type_to_url,
260 Context* context,
261 DynamicServiceRunnerFactory* runner_factory,
262 NetworkServicePtr* network_service,
263 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
264 const LoaderCompleteCallback& loader_complete_callback)
265 : load_callbacks_(load_callbacks),
266 loader_complete_callback_(loader_complete_callback),
267 context_(context),
268 mime_type_to_url_(mime_type_to_url),
269 runner_factory_(runner_factory),
270 network_service_(network_service),
271 weak_ptr_factory_(this) {
272 Load(url, network_service);
273 }
274
275 virtual ~Loader() {}
122 276
123 private: 277 private:
124 base::WeakPtrFactory<LocalLoader> weak_ptr_factory_; 278 void RunLibrary(const base::FilePath& path, bool path_exists) {
125 }; 279 ScopedMessagePipeHandle shell_handle =
126 280 load_callbacks_->RegisterApplication();
127 // A loader for network files. 281 if (!shell_handle.is_valid()) {
128 class DynamicApplicationLoader::NetworkLoader : public Loader {
129 public:
130 NetworkLoader(const GURL& url,
131 MimeTypeToURLMap* mime_type_to_url,
132 Context* context,
133 DynamicServiceRunnerFactory* runner_factory,
134 NetworkService* network_service,
135 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks,
136 const LoaderCompleteCallback& loader_complete_callback)
137 : Loader(context,
138 runner_factory,
139 load_callbacks,
140 loader_complete_callback),
141 mime_type_to_url_(mime_type_to_url),
142 weak_ptr_factory_(this) {
143 URLRequestPtr request(URLRequest::New());
144 request->url = String::From(url);
145 request->auto_follow_redirects = true;
146
147 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
148 switches::kDisableCache)) {
149 request->bypass_cache = true;
150 }
151
152 network_service->CreateURLLoader(GetProxy(&url_loader_));
153 url_loader_->Start(request.Pass(),
154 base::Bind(&NetworkLoader::OnLoadComplete,
155 weak_ptr_factory_.GetWeakPtr()));
156 }
157
158 ~NetworkLoader() override {
159 if (!file_.empty())
160 base::DeleteFile(file_, false);
161 }
162
163 private:
164 bool PeekContentHandler(DataPipeConsumerHandle source,
165 std::string* mojo_shebang,
166 GURL* mojo_content_handler_url)
167 {
168 const char* kMojoMagic = "#!mojo:";
169 // TODO(hansmuller): Revisit this when a real peek operation is available.
170 const MojoDeadline kPeekTimeout = MOJO_DEADLINE_INDEFINITE;
171 const size_t kMaxShebangLength = 2048;
172
173 std::string magic;
174 std::string shebang;
175 if (BlockingPeekNBytes(source, &magic, strlen(kMojoMagic), kPeekTimeout) &&
176 magic == kMojoMagic &&
177 BlockingPeekLine(source, &shebang, kMaxShebangLength, kPeekTimeout)) {
178 GURL url(shebang.substr(2, std::string::npos));
179 if (url.is_valid()) {
180 *mojo_shebang = shebang;
181 *mojo_content_handler_url = url;
182 return true;
183 }
184 }
185 return false;
186 }
187
188 void OnLoadComplete(URLResponsePtr response) {
189 if (response->error) {
190 LOG(ERROR) << "Error (" << response->error->code << ": "
191 << response->error->description << ") while fetching "
192 << response->url;
193 LoaderComplete(); 282 LoaderComplete();
194 return; 283 return;
195 } 284 }
285
286 if (!path_exists) {
287 LOG(ERROR) << "Library not started because library path '" << path.value()
288 << "' does not exist.";
289 LoaderComplete();
290 return;
291 }
292
293 runner_ = runner_factory_->Create(context_);
294 runner_->Start(
295 path, shell_handle.Pass(),
296 base::Bind(&Loader::LoaderComplete, weak_ptr_factory_.GetWeakPtr()));
297 }
298
299 void LoaderComplete() { loader_complete_callback_.Run(this); }
300
301 void OnResponse(bool success) {
302 if (!success) {
303 LoaderComplete();
304 return;
305 }
196 306
197 // If the response begins with a #!mojo:<content-handler-url>, use it. 307 // If the response begins with a #!mojo:<content-handler-url>, use it.
198 { 308 {
199 GURL url; 309 GURL url;
200 std::string shebang; 310 std::string shebang;
201 if (PeekContentHandler(response->body.get(), &shebang, &url)) { 311 if (request_->PeekContentHandler(&shebang, &url)) {
202 uint32_t num_skip_bytes = shebang.size(); 312 load_callbacks_->LoadWithContentHandler(
203 if (ReadDataRaw(response->body.get(), 313 url,
204 nullptr, 314 request_->AsURLResponse(context_->task_runners()->blocking_pool(),
205 &num_skip_bytes, 315 shebang.size()));
206 MOJO_READ_DATA_FLAG_ALL_OR_NONE | 316 return;
207 MOJO_READ_DATA_FLAG_DISCARD) ==
208 MOJO_RESULT_OK) {
209 load_callbacks_->LoadWithContentHandler(url, response.Pass());
210 return;
211 }
212 } 317 }
213 } 318 }
214 319
215 MimeTypeToURLMap::iterator iter = 320 MimeTypeToURLMap::iterator iter =
216 mime_type_to_url_->find(response->mime_type); 321 mime_type_to_url_->find(request_->MimeType());
217 if (iter != mime_type_to_url_->end()) { 322 if (iter != mime_type_to_url_->end()) {
218 load_callbacks_->LoadWithContentHandler(iter->second, response.Pass()); 323 load_callbacks_->LoadWithContentHandler(
324 iter->second, request_->AsURLResponse(
325 context_->task_runners()->blocking_pool(), 0));
219 return; 326 return;
220 } 327 }
221 328
222 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo 329 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo
223 // application. That could either mean looking for the platform-specific dll 330 // application. That could either mean looking for the platform-specific dll
224 // header, or looking for some specific mojo signature prepended to the 331 // header, or looking for some specific mojo signature prepended to the
225 // library. 332 // library.
226 333
227 base::CreateTemporaryFile(&file_); 334 request_->AsPath(
228 common::CopyToFile(
229 response->body.Pass(),
230 file_,
231 context_->task_runners()->blocking_pool(), 335 context_->task_runners()->blocking_pool(),
232 base::Bind( 336 base::Bind(&Loader::RunLibrary, weak_ptr_factory_.GetWeakPtr()));
233 &NetworkLoader::RunLibrary, weak_ptr_factory_.GetWeakPtr(), file_));
234 } 337 }
235 338
339 void Load(const GURL& url, NetworkServicePtr* network_service) {
Aaron Boodman 2014/11/07 08:56:27 second param never used.
340 GURL resolved_url;
341 if (url.SchemeIs("mojo")) {
342 resolved_url = context_->mojo_url_resolver()->Resolve(url);
343 } else {
344 resolved_url = url;
345 }
346
347 if (resolved_url.SchemeIsFile()) {
348 request_.reset(new LocalLoaderRequest(
349 resolved_url,
350 base::Bind(&DynamicApplicationLoader::Loader::OnResponse,
351 weak_ptr_factory_.GetWeakPtr())));
352 return;
353 }
354
355 if (!network_service_->get()) {
Aaron Boodman 2014/11/07 08:56:27 Put this back in DAL::Load() so that we share one
356 context_->application_manager()->ConnectToService(
357 GURL("mojo:network_service"), network_service_);
Aaron Boodman 2014/11/07 08:56:27 network_service_ is a pointer, so I guess this pip
qsr 2014/11/07 09:33:22 I mixed 2 things here, sorry. network_service_ sho
358 }
359
360 request_.reset(new NetworkLoaderRequest(
361 resolved_url, network_service_->get(),
362 base::Bind(&DynamicApplicationLoader::Loader::OnResponse,
363 weak_ptr_factory_.GetWeakPtr())));
364 }
365
366 scoped_refptr<ApplicationLoader::LoadCallbacks> load_callbacks_;
367 LoaderCompleteCallback loader_complete_callback_;
368 Context* context_;
236 MimeTypeToURLMap* mime_type_to_url_; 369 MimeTypeToURLMap* mime_type_to_url_;
237 URLLoaderPtr url_loader_; 370 DynamicServiceRunnerFactory* runner_factory_;
238 base::FilePath file_; 371 NetworkServicePtr* network_service_;
239 base::WeakPtrFactory<NetworkLoader> weak_ptr_factory_; 372 scoped_ptr<DynamicServiceRunner> runner_;
373 scoped_ptr<LoaderRequest> request_;
374 base::WeakPtrFactory<Loader> weak_ptr_factory_;
240 }; 375 };
376
241 DynamicApplicationLoader::DynamicApplicationLoader( 377 DynamicApplicationLoader::DynamicApplicationLoader(
242 Context* context, 378 Context* context,
243 scoped_ptr<DynamicServiceRunnerFactory> runner_factory) 379 scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
244 : context_(context), 380 : context_(context),
245 runner_factory_(runner_factory.Pass()), 381 runner_factory_(runner_factory.Pass()),
246 382
247 // Unretained() is correct here because DynamicApplicationLoader owns the 383 // Unretained() is correct here because DynamicApplicationLoader owns the
248 // loaders that we pass this callback to. 384 // loaders that we pass this callback to.
249 loader_complete_callback_( 385 loader_complete_callback_(
250 base::Bind(&DynamicApplicationLoader::LoaderComplete, 386 base::Bind(&DynamicApplicationLoader::LoaderComplete,
251 base::Unretained(this))) { 387 base::Unretained(this))) {
252 } 388 }
253 389
254 DynamicApplicationLoader::~DynamicApplicationLoader() { 390 DynamicApplicationLoader::~DynamicApplicationLoader() {
255 } 391 }
256 392
257 void DynamicApplicationLoader::RegisterContentHandler( 393 void DynamicApplicationLoader::RegisterContentHandler(
258 const std::string& mime_type, 394 const std::string& mime_type,
259 const GURL& content_handler_url) { 395 const GURL& content_handler_url) {
260 mime_type_to_url_[mime_type] = content_handler_url; 396 mime_type_to_url_[mime_type] = content_handler_url;
261 } 397 }
262 398
263 void DynamicApplicationLoader::Load( 399 void DynamicApplicationLoader::Load(
264 ApplicationManager* manager, 400 ApplicationManager* manager,
265 const GURL& url, 401 const GURL& url,
266 scoped_refptr<LoadCallbacks> load_callbacks) { 402 scoped_refptr<LoadCallbacks> load_callbacks) {
267 GURL resolved_url; 403 loaders_.push_back(new Loader(url, &mime_type_to_url_, context_,
268 if (url.SchemeIs("mojo")) { 404 runner_factory_.get(), &network_service_,
Aaron Boodman 2014/11/07 08:56:27 this is always null.
269 resolved_url = context_->mojo_url_resolver()->Resolve(url); 405 load_callbacks, loader_complete_callback_));
270 } else {
271 resolved_url = url;
272 }
273
274 if (resolved_url.SchemeIsFile()) {
275 loaders_.push_back(new LocalLoader(resolved_url,
276 context_,
277 runner_factory_.get(),
278 load_callbacks,
279 loader_complete_callback_));
280 return;
281 }
282
283 if (!network_service_) {
284 context_->application_manager()->ConnectToService(
285 GURL("mojo:network_service"), &network_service_);
286 }
287
288 loaders_.push_back(new NetworkLoader(resolved_url,
289 &mime_type_to_url_,
290 context_,
291 runner_factory_.get(),
292 network_service_.get(),
293 load_callbacks,
294 loader_complete_callback_));
295 } 406 }
296 407
297 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager, 408 void DynamicApplicationLoader::OnApplicationError(ApplicationManager* manager,
298 const GURL& url) { 409 const GURL& url) {
299 // TODO(darin): What should we do about service errors? This implies that 410 // TODO(darin): What should we do about service errors? This implies that
300 // the app closed its handle to the service manager. Maybe we don't care? 411 // the app closed its handle to the service manager. Maybe we don't care?
301 } 412 }
302 413
303 void DynamicApplicationLoader::LoaderComplete(Loader* loader) { 414 void DynamicApplicationLoader::LoaderComplete(Loader* loader) {
304 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader)); 415 loaders_.erase(std::find(loaders_.begin(), loaders_.end(), loader));
305 } 416 }
306 417
307 } // namespace shell 418 } // namespace shell
308 } // namespace mojo 419 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/dynamic_application_loader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698