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