OLD | NEW |
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/application_manager.h" | 5 #include "mojo/shell/application_manager.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/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 weak_ptr_factory_(this) { | 56 weak_ptr_factory_(this) { |
57 fetcher_->SetApplicationManager(this); | 57 fetcher_->SetApplicationManager(this); |
58 } | 58 } |
59 | 59 |
60 ApplicationManager::~ApplicationManager() { | 60 ApplicationManager::~ApplicationManager() { |
61 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_); | 61 URLToContentHandlerMap url_to_content_handler(url_to_content_handler_); |
62 for (auto& pair : url_to_content_handler) | 62 for (auto& pair : url_to_content_handler) |
63 pair.second->CloseConnection(); | 63 pair.second->CloseConnection(); |
64 TerminateShellConnections(); | 64 TerminateShellConnections(); |
65 STLDeleteValues(&url_to_loader_); | 65 STLDeleteValues(&url_to_loader_); |
66 STLDeleteValues(&scheme_to_loader_); | |
67 } | 66 } |
68 | 67 |
69 void ApplicationManager::TerminateShellConnections() { | 68 void ApplicationManager::TerminateShellConnections() { |
70 STLDeleteValues(&identity_to_instance_); | 69 STLDeleteValues(&identity_to_instance_); |
71 } | 70 } |
72 | 71 |
73 void ApplicationManager::ConnectToApplication( | 72 void ApplicationManager::ConnectToApplication( |
74 ApplicationInstance* originator, | 73 ApplicationInstance* originator, |
75 URLRequestPtr app_url_request, | 74 URLRequestPtr app_url_request, |
76 const std::string& qualifier, | 75 const std::string& qualifier, |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 qualifier = alias_iter->second.second; | 280 qualifier = alias_iter->second.second; |
282 } | 281 } |
283 | 282 |
284 LoadWithContentHandler(originator_identity, originator_filter, | 283 LoadWithContentHandler(originator_identity, originator_filter, |
285 alias_iter->second.first, qualifier, filter, | 284 alias_iter->second.first, qualifier, filter, |
286 connect_callback, app, request.Pass(), | 285 connect_callback, app, request.Pass(), |
287 response.Pass()); | 286 response.Pass()); |
288 return; | 287 return; |
289 } | 288 } |
290 | 289 |
291 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo | |
292 // application. That could either mean looking for the platform-specific dll | |
293 // header, or looking for some specific mojo signature prepended to the | |
294 // library. | |
295 // TODO(vtl): (Maybe this should be done by the factory/runner?) | |
296 | |
297 GURL base_resolved_url = GetBaseURLAndQuery(fetcher->GetURL(), nullptr); | |
298 NativeRunnerFactory::Options options; | |
299 if (url_to_native_options_.find(base_resolved_url) != | |
300 url_to_native_options_.end()) { | |
301 DVLOG(2) << "Applying stored native options to resolved URL " | |
302 << fetcher->GetURL(); | |
303 options = url_to_native_options_[base_resolved_url]; | |
304 } | |
305 | |
306 // TODO(erg): Have a better way of switching the sandbox on. For now, switch | 290 // TODO(erg): Have a better way of switching the sandbox on. For now, switch |
307 // it on hard coded when we're using some of the sandboxable core services. | 291 // it on hard coded when we're using some of the sandboxable core services. |
308 bool start_sandboxed = false; | 292 bool start_sandboxed = false; |
309 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 293 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
310 switches::kMojoNoSandbox)) { | 294 switches::kMojoNoSandbox)) { |
311 if (app_url == GURL("mojo://core_services/") && qualifier == "Core") | 295 if (app_url == GURL("mojo://core_services/") && qualifier == "Core") |
312 start_sandboxed = true; | 296 start_sandboxed = true; |
313 else if (app_url == GURL("mojo://html_viewer/")) | 297 else if (app_url == GURL("mojo://html_viewer/")) |
314 start_sandboxed = true; | 298 start_sandboxed = true; |
315 } | 299 } |
316 | 300 |
317 connect_callback.Run(Shell::kInvalidContentHandlerID); | 301 connect_callback.Run(Shell::kInvalidContentHandlerID); |
318 | 302 |
319 fetcher->AsPath(blocking_pool_, | 303 fetcher->AsPath(blocking_pool_, |
320 base::Bind(&ApplicationManager::RunNativeApplication, | 304 base::Bind(&ApplicationManager::RunNativeApplication, |
321 weak_ptr_factory_.GetWeakPtr(), | 305 weak_ptr_factory_.GetWeakPtr(), |
322 base::Passed(request.Pass()), start_sandboxed, | 306 base::Passed(request.Pass()), start_sandboxed, |
323 options, base::Passed(fetcher.Pass()))); | 307 base::Passed(fetcher.Pass()))); |
324 } | 308 } |
325 | 309 |
326 void ApplicationManager::RunNativeApplication( | 310 void ApplicationManager::RunNativeApplication( |
327 InterfaceRequest<Application> application_request, | 311 InterfaceRequest<Application> application_request, |
328 bool start_sandboxed, | 312 bool start_sandboxed, |
329 const NativeRunnerFactory::Options& options, | |
330 scoped_ptr<Fetcher> fetcher, | 313 scoped_ptr<Fetcher> fetcher, |
331 const base::FilePath& path, | 314 const base::FilePath& path, |
332 bool path_exists) { | 315 bool path_exists) { |
333 // We only passed fetcher to keep it alive. Done with it now. | 316 // We only passed fetcher to keep it alive. Done with it now. |
334 fetcher.reset(); | 317 fetcher.reset(); |
335 | 318 |
336 DCHECK(application_request.is_pending()); | 319 DCHECK(application_request.is_pending()); |
337 | 320 |
338 if (!path_exists) { | 321 if (!path_exists) { |
339 LOG(ERROR) << "Library not started because library path '" << path.value() | 322 LOG(ERROR) << "Library not started because library path '" << path.value() |
340 << "' does not exist."; | 323 << "' does not exist."; |
341 return; | 324 return; |
342 } | 325 } |
343 | 326 |
344 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", | 327 TRACE_EVENT1("mojo_shell", "ApplicationManager::RunNativeApplication", "path", |
345 path.AsUTF8Unsafe()); | 328 path.AsUTF8Unsafe()); |
346 NativeRunner* runner = native_runner_factory_->Create(options).release(); | 329 NativeRunner* runner = native_runner_factory_->Create().release(); |
347 native_runners_.push_back(runner); | 330 native_runners_.push_back(runner); |
348 runner->Start(path, start_sandboxed, NativeApplicationCleanup::DONT_DELETE, | 331 runner->Start(path, start_sandboxed, application_request.Pass(), |
349 application_request.Pass(), | |
350 base::Bind(&ApplicationManager::CleanupRunner, | 332 base::Bind(&ApplicationManager::CleanupRunner, |
351 weak_ptr_factory_.GetWeakPtr(), runner)); | 333 weak_ptr_factory_.GetWeakPtr(), runner)); |
352 } | 334 } |
353 | 335 |
354 void ApplicationManager::RegisterContentHandler( | 336 void ApplicationManager::RegisterContentHandler( |
355 const std::string& mime_type, | 337 const std::string& mime_type, |
356 const GURL& content_handler_url) { | 338 const GURL& content_handler_url) { |
357 DCHECK(content_handler_url.is_valid()) | 339 DCHECK(content_handler_url.is_valid()) |
358 << "Content handler URL is invalid for mime type " << mime_type; | 340 << "Content handler URL is invalid for mime type " << mime_type; |
359 mime_type_to_url_[mime_type] = content_handler_url; | 341 mime_type_to_url_[mime_type] = content_handler_url; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 380 } |
399 | 381 |
400 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 382 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
401 const GURL& url) { | 383 const GURL& url) { |
402 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 384 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
403 if (it != url_to_loader_.end()) | 385 if (it != url_to_loader_.end()) |
404 delete it->second; | 386 delete it->second; |
405 url_to_loader_[url] = loader.release(); | 387 url_to_loader_[url] = loader.release(); |
406 } | 388 } |
407 | 389 |
408 void ApplicationManager::SetLoaderForScheme( | |
409 scoped_ptr<ApplicationLoader> loader, | |
410 const std::string& scheme) { | |
411 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); | |
412 if (it != scheme_to_loader_.end()) | |
413 delete it->second; | |
414 scheme_to_loader_[scheme] = loader.release(); | |
415 } | |
416 | |
417 void ApplicationManager::SetNativeOptionsForURL( | |
418 const NativeRunnerFactory::Options& options, | |
419 const GURL& url) { | |
420 DCHECK(!url.has_query()); // Precondition. | |
421 // Apply mappings and resolution to get the resolved URL. | |
422 GURL resolved_url = fetcher_->ResolveURL(url); | |
423 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. | |
424 // TODO(vtl): We should probably also remove/disregard the query string (and | |
425 // maybe canonicalize in other ways). | |
426 DVLOG(2) << "Storing native options for resolved URL " << resolved_url | |
427 << " (original URL " << url << ")"; | |
428 url_to_native_options_[resolved_url] = options; | |
429 } | |
430 | |
431 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { | 390 ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) { |
432 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr)); | 391 auto url_it = url_to_loader_.find(GetBaseURLAndQuery(url, nullptr)); |
433 if (url_it != url_to_loader_.end()) | 392 if (url_it != url_to_loader_.end()) |
434 return url_it->second; | 393 return url_it->second; |
435 auto scheme_it = scheme_to_loader_.find(url.scheme()); | |
436 if (scheme_it != scheme_to_loader_.end()) | |
437 return scheme_it->second; | |
438 return default_loader_.get(); | 394 return default_loader_.get(); |
439 } | 395 } |
440 | 396 |
441 void ApplicationManager::OnApplicationInstanceError( | 397 void ApplicationManager::OnApplicationInstanceError( |
442 ApplicationInstance* instance) { | 398 ApplicationInstance* instance) { |
443 // Called from ~ApplicationInstance, so we do not need to call Destroy here. | 399 // Called from ~ApplicationInstance, so we do not need to call Destroy here. |
444 const Identity identity = instance->identity(); | 400 const Identity identity = instance->identity(); |
445 base::Closure on_application_end = instance->on_application_end(); | 401 base::Closure on_application_end = instance->on_application_end(); |
446 // Remove the shell. | 402 // Remove the shell. |
447 auto it = identity_to_instance_.find(identity); | 403 auto it = identity_to_instance_.find(identity); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 436 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
481 return pipe.handle0.Pass(); | 437 return pipe.handle0.Pass(); |
482 } | 438 } |
483 | 439 |
484 Shell::ConnectToApplicationCallback EmptyConnectCallback() { | 440 Shell::ConnectToApplicationCallback EmptyConnectCallback() { |
485 return base::Bind(&OnEmptyOnConnectCallback); | 441 return base::Bind(&OnEmptyOnConnectCallback); |
486 } | 442 } |
487 | 443 |
488 } // namespace shell | 444 } // namespace shell |
489 } // namespace mojo | 445 } // namespace mojo |
OLD | NEW |