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 "services/shell/shell.h" | 5 #include "services/shell/shell.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 Instance(shell::Shell* shell, | 113 Instance(shell::Shell* shell, |
114 const Identity& identity, | 114 const Identity& identity, |
115 const CapabilitySpec& capability_spec) | 115 const CapabilitySpec& capability_spec) |
116 : shell_(shell), | 116 : shell_(shell), |
117 id_(GenerateUniqueID()), | 117 id_(GenerateUniqueID()), |
118 identity_(identity), | 118 identity_(identity), |
119 capability_spec_(capability_spec), | 119 capability_spec_(capability_spec), |
120 allow_any_application_(capability_spec.required.count("*") == 1), | 120 allow_any_application_(capability_spec.required.count("*") == 1), |
121 pid_receiver_binding_(this), | 121 pid_receiver_binding_(this), |
122 weak_factory_(this) { | 122 weak_factory_(this) { |
123 if (identity_.name() == kShellName) | 123 if (identity_.name() == kShellName || |
| 124 shell_->GetLoaderForName(identity_.name())) { |
124 pid_ = base::Process::Current().Pid(); | 125 pid_ = base::Process::Current().Pid(); |
| 126 } |
125 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 127 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
126 } | 128 } |
127 | 129 |
128 ~Instance() override { | 130 ~Instance() override { |
129 if (parent_) | 131 if (parent_) |
130 parent_->RemoveChild(this); | 132 parent_->RemoveChild(this); |
131 // |children_| will be modified during destruction. | 133 // |children_| will be modified during destruction. |
132 std::set<Instance*> children = children_; | 134 std::set<Instance*> children = children_; |
133 for (auto child : children) | 135 for (auto child : children) |
134 shell_->OnInstanceError(child); | 136 shell_->OnInstanceError(child); |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 instance->StartWithClient(std::move(client)); | 453 instance->StartWithClient(std::move(client)); |
452 singletons_.insert(kShellName); | 454 singletons_.insert(kShellName); |
453 shell_connection_.reset(new ShellConnection(this, std::move(request))); | 455 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
454 | 456 |
455 if (catalog) | 457 if (catalog) |
456 InitCatalog(std::move(catalog)); | 458 InitCatalog(std::move(catalog)); |
457 } | 459 } |
458 | 460 |
459 Shell::~Shell() { | 461 Shell::~Shell() { |
460 TerminateShellConnections(); | 462 TerminateShellConnections(); |
| 463 STLDeleteValues(&name_to_loader_); |
461 for (auto& runner : native_runners_) | 464 for (auto& runner : native_runners_) |
462 runner.reset(); | 465 runner.reset(); |
463 } | 466 } |
464 | 467 |
465 void Shell::SetInstanceQuitCallback( | 468 void Shell::SetInstanceQuitCallback( |
466 base::Callback<void(const Identity&)> callback) { | 469 base::Callback<void(const Identity&)> callback) { |
467 instance_quit_callback_ = callback; | 470 instance_quit_callback_ = callback; |
468 } | 471 } |
469 | 472 |
470 void Shell::Connect(std::unique_ptr<ConnectParams> params) { | 473 void Shell::Connect(std::unique_ptr<ConnectParams> params) { |
471 Connect(std::move(params), nullptr); | 474 Connect(std::move(params), nullptr); |
472 } | 475 } |
473 | 476 |
474 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( | 477 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( |
475 const std::string& name) { | 478 const std::string& name) { |
476 std::unique_ptr<ConnectParams> params(new ConnectParams); | 479 std::unique_ptr<ConnectParams> params(new ConnectParams); |
477 | 480 |
478 Identity embedder_identity(name, mojom::kRootUserID); | 481 Identity embedder_identity(name, mojom::kRootUserID); |
479 params->set_source(embedder_identity); | 482 params->set_source(embedder_identity); |
480 params->set_target(embedder_identity); | 483 params->set_target(embedder_identity); |
481 | 484 |
482 mojom::ShellClientPtr client; | 485 mojom::ShellClientPtr client; |
483 mojom::ShellClientRequest request = mojo::GetProxy(&client); | 486 mojom::ShellClientRequest request = mojo::GetProxy(&client); |
484 Connect(std::move(params), std::move(client)); | 487 Connect(std::move(params), std::move(client)); |
485 | 488 |
486 return request; | 489 return request; |
487 } | 490 } |
488 | 491 |
| 492 void Shell::SetLoaderForName(std::unique_ptr<Loader> loader, |
| 493 const std::string& name) { |
| 494 auto it = name_to_loader_.find(name); |
| 495 if (it != name_to_loader_.end()) |
| 496 delete it->second; |
| 497 name_to_loader_[name] = loader.release(); |
| 498 } |
| 499 |
489 //////////////////////////////////////////////////////////////////////////////// | 500 //////////////////////////////////////////////////////////////////////////////// |
490 // Shell, ShellClient implementation: | 501 // Shell, ShellClient implementation: |
491 | 502 |
492 bool Shell::AcceptConnection(Connection* connection) { | 503 bool Shell::AcceptConnection(Connection* connection) { |
493 // The only interface we expose is mojom::Shell, and access to this interface | 504 // The only interface we expose is mojom::Shell, and access to this interface |
494 // is brokered by a policy specific to each caller, managed by the caller's | 505 // is brokered by a policy specific to each caller, managed by the caller's |
495 // instance. Here we look to see who's calling, and forward to the caller's | 506 // instance. Here we look to see who's calling, and forward to the caller's |
496 // instance to continue. | 507 // instance to continue. |
497 Instance* instance = nullptr; | 508 Instance* instance = nullptr; |
498 for (const auto& entry : identity_to_instance_) { | 509 for (const auto& entry : identity_to_instance_) { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 // is already holding a corresponding ShellClientRequest. | 730 // is already holding a corresponding ShellClientRequest. |
720 instance->StartWithClient(std::move(client)); | 731 instance->StartWithClient(std::move(client)); |
721 } else if (!client_process_connection.is_null()) { | 732 } else if (!client_process_connection.is_null()) { |
722 // Likewise if a ClientProcessConnection was given via Connect(), it | 733 // Likewise if a ClientProcessConnection was given via Connect(), it |
723 // provides the ShellClient proxy to use. | 734 // provides the ShellClient proxy to use. |
724 instance->StartWithClientProcessConnection( | 735 instance->StartWithClientProcessConnection( |
725 std::move(client_process_connection)); | 736 std::move(client_process_connection)); |
726 } else { | 737 } else { |
727 // Otherwise we create a new ShellClient pipe. | 738 // Otherwise we create a new ShellClient pipe. |
728 mojom::ShellClientRequest request = GetProxy(&client); | 739 mojom::ShellClientRequest request = GetProxy(&client); |
729 CHECK(!result->package_url.is_null() && !result->capabilities.is_null()); | 740 if (LoadWithLoader(target, &request)) { |
| 741 instance->StartWithClient(std::move(client)); |
| 742 } else { |
| 743 CHECK(!result->package_url.is_null() && !result->capabilities.is_null()); |
730 | 744 |
731 if (target.name() != result->resolved_name) { | 745 if (target.name() != result->resolved_name) { |
732 instance->StartWithClient(std::move(client)); | 746 instance->StartWithClient(std::move(client)); |
733 Identity factory(result->resolved_name, target.user_id(), | 747 Identity factory(result->resolved_name, target.user_id(), |
734 instance_name); | 748 instance_name); |
735 CreateShellClientWithFactory(factory, target.name(), | 749 CreateShellClientWithFactory(factory, target.name(), |
736 std::move(request)); | 750 std::move(request)); |
737 } else { | 751 } else { |
738 instance->StartWithFilePath( | 752 instance->StartWithFilePath( |
739 mojo::util::UrlToFilePath(result->package_url.To<GURL>())); | 753 mojo::util::UrlToFilePath(result->package_url.To<GURL>())); |
| 754 } |
740 } | 755 } |
741 } | 756 } |
742 | 757 |
743 // Now that the instance has a ShellClient, we can connect to it. | 758 // Now that the instance has a ShellClient, we can connect to it. |
744 instance->ConnectToClient(std::move(params)); | 759 instance->ConnectToClient(std::move(params)); |
745 } | 760 } |
746 | 761 |
| 762 bool Shell::LoadWithLoader(const Identity& target, |
| 763 mojom::ShellClientRequest* request) { |
| 764 Loader* loader = GetLoaderForName(target.name()); |
| 765 if (!loader) |
| 766 return false; |
| 767 loader->Load(target.name(), std::move(*request)); |
| 768 return true; |
| 769 } |
| 770 |
| 771 Loader* Shell::GetLoaderForName(const std::string& name) { |
| 772 auto name_it = name_to_loader_.find(name); |
| 773 if (name_it != name_to_loader_.end()) |
| 774 return name_it->second; |
| 775 return default_loader_.get(); |
| 776 } |
| 777 |
747 base::WeakPtr<Shell> Shell::GetWeakPtr() { | 778 base::WeakPtr<Shell> Shell::GetWeakPtr() { |
748 return weak_ptr_factory_.GetWeakPtr(); | 779 return weak_ptr_factory_.GetWeakPtr(); |
749 } | 780 } |
750 | 781 |
751 void Shell::CleanupRunner(NativeRunner* runner) { | 782 void Shell::CleanupRunner(NativeRunner* runner) { |
752 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 783 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
753 if (it->get() == runner) { | 784 if (it->get() == runner) { |
754 native_runners_.erase(it); | 785 native_runners_.erase(it); |
755 return; | 786 return; |
756 } | 787 } |
757 } | 788 } |
758 } | 789 } |
759 | 790 |
760 } // namespace shell | 791 } // namespace shell |
OLD | NEW |