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/shell.h" | 5 #include "mojo/shell/shell.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 } | 97 } |
98 | 98 |
99 // Encapsulates a connection to an instance of an application, tracked by the | 99 // Encapsulates a connection to an instance of an application, tracked by the |
100 // shell's Shell. | 100 // shell's Shell. |
101 class Shell::Instance : public mojom::Connector, | 101 class Shell::Instance : public mojom::Connector, |
102 public mojom::PIDReceiver, | 102 public mojom::PIDReceiver, |
103 public ShellClient, | 103 public ShellClient, |
104 public InterfaceFactory<mojom::Shell>, | 104 public InterfaceFactory<mojom::Shell>, |
105 public mojom::Shell { | 105 public mojom::Shell { |
106 public: | 106 public: |
107 Instance(mojom::ShellClientPtr shell_client, | 107 Instance(mojo::shell::Shell* shell, |
108 mojo::shell::Shell* shell, | |
109 const Identity& identity, | 108 const Identity& identity, |
110 const CapabilitySpec& capability_spec) | 109 const CapabilitySpec& capability_spec) |
111 : shell_(shell), | 110 : shell_(shell), |
112 id_(GenerateUniqueID()), | 111 id_(GenerateUniqueID()), |
113 identity_(identity), | 112 identity_(identity), |
114 capability_spec_(capability_spec), | 113 capability_spec_(capability_spec), |
115 allow_any_application_(capability_spec.required.count("*") == 1), | 114 allow_any_application_(capability_spec.required.count("*") == 1), |
116 shell_client_(std::move(shell_client)), | |
117 pid_receiver_binding_(this), | 115 pid_receiver_binding_(this), |
118 weak_factory_(this) { | 116 weak_factory_(this) { |
119 if (identity_.name() == kShellName || | 117 if (identity_.name() == kShellName || |
120 shell_->GetLoaderForName(identity_.name())) { | 118 shell_->GetLoaderForName(identity_.name())) { |
121 pid_ = base::Process::Current().Pid(); | 119 pid_ = base::Process::Current().Pid(); |
122 } | 120 } |
123 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 121 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
124 | |
125 shell_client_.set_connection_error_handler( | |
126 base::Bind(&Instance::OnShellClientLost, base::Unretained(this))); | |
127 } | 122 } |
128 | 123 |
129 ~Instance() override {} | 124 ~Instance() override {} |
130 | 125 |
131 void OnShellClientLost() { | 126 void OnShellClientLost() { |
132 shell_client_.reset(); | 127 shell_client_.reset(); |
133 OnConnectionLost(); | 128 OnConnectionLost(); |
134 } | 129 } |
135 | 130 |
136 void OnConnectionLost() { | 131 void OnConnectionLost() { |
137 // Any time a Connector is lost or we lose the ShellClient connection, it | 132 // Any time a Connector is lost or we lose the ShellClient connection, it |
138 // may have been the last pipe using this Instance. If so, clean up. | 133 // may have been the last pipe using this Instance. If so, clean up. |
139 if (connectors_.empty() && !shell_client_) { | 134 if (connectors_.empty() && !shell_client_) { |
140 // Deletes |this|. | 135 // Deletes |this|. |
141 shell_->OnInstanceError(this); | 136 shell_->OnInstanceError(this); |
142 } | 137 } |
143 } | 138 } |
144 | 139 |
145 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { | 140 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { |
146 if (connector_request.is_pending()) { | 141 if (connector_request.is_pending()) { |
147 connectors_.AddBinding(this, std::move(connector_request)); | 142 connectors_.AddBinding(this, std::move(connector_request)); |
148 connectors_.set_connection_error_handler( | 143 connectors_.set_connection_error_handler( |
149 base::Bind(&Instance::OnConnectionLost, base::Unretained(this))); | 144 base::Bind(&Instance::OnConnectionLost, base::Unretained(this))); |
150 } | 145 } |
151 } | 146 } |
152 | 147 |
153 void InitializeClient() { | |
154 shell_client_->Initialize(mojom::Identity::From(identity_), id_, | |
155 base::Bind(&Instance::OnInitializeResponse, | |
156 base::Unretained(this))); | |
157 } | |
158 | |
159 void ConnectToClient(scoped_ptr<ConnectParams> params) { | 148 void ConnectToClient(scoped_ptr<ConnectParams> params) { |
| 149 CHECK(shell_client_.is_bound()); |
160 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 150 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
161 identity_.user_id(), id_); | 151 identity_.user_id(), id_); |
162 uint32_t source_id = mojom::kInvalidInstanceID; | 152 uint32_t source_id = mojom::kInvalidInstanceID; |
163 CapabilityRequest spec; | 153 CapabilityRequest spec; |
164 spec.interfaces.insert("*"); | 154 spec.interfaces.insert("*"); |
165 Instance* source = shell_->GetExistingInstance(params->source()); | 155 Instance* source = shell_->GetExistingInstance(params->source()); |
166 if (source) { | 156 if (source) { |
167 spec = GenerateCapabilityRequestForConnection( | 157 spec = GenerateCapabilityRequestForConnection( |
168 source->capability_spec_, identity_, capability_spec_); | 158 source->capability_spec_, identity_, capability_spec_); |
169 source_id = source->id(); | 159 source_id = source->id(); |
170 } | 160 } |
171 shell_client_->AcceptConnection( | 161 shell_client_->AcceptConnection( |
172 mojom::Identity::From(params->source()), source_id, | 162 mojom::Identity::From(params->source()), source_id, |
173 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), | 163 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), |
174 mojom::CapabilityRequest::From(spec), params->target().name()); | 164 mojom::CapabilityRequest::From(spec), params->target().name()); |
175 } | 165 } |
176 | 166 |
| 167 void StartWithClient(mojom::ShellClientPtr client) { |
| 168 CHECK(!shell_client_); |
| 169 shell_client_ = std::move(client); |
| 170 shell_client_.set_connection_error_handler( |
| 171 base::Bind(&Instance::OnShellClientLost, base::Unretained(this))); |
| 172 shell_client_->Initialize(mojom::Identity::From(identity_), id_, |
| 173 base::Bind(&Instance::OnInitializeResponse, |
| 174 base::Unretained(this))); |
| 175 } |
| 176 |
177 void StartWithClientProcessConnection( | 177 void StartWithClientProcessConnection( |
178 mojom::ShellClientRequest request, | |
179 mojom::ClientProcessConnectionPtr client_process_connection) { | 178 mojom::ClientProcessConnectionPtr client_process_connection) { |
180 factory_.Bind(mojom::ShellClientFactoryPtrInfo( | 179 mojom::ShellClientPtr client; |
181 std::move(client_process_connection->shell_client_factory), 0u)); | 180 client.Bind(mojom::ShellClientPtrInfo( |
| 181 std::move(client_process_connection->shell_client), 0)); |
182 pid_receiver_binding_.Bind( | 182 pid_receiver_binding_.Bind( |
183 std::move(client_process_connection->pid_receiver_request)); | 183 std::move(client_process_connection->pid_receiver_request)); |
184 factory_->CreateShellClient(std::move(request), identity_.name()); | 184 StartWithClient(std::move(client)); |
185 } | 185 } |
186 | 186 |
187 void StartWithFilePath(mojom::ShellClientRequest request, | 187 void StartWithFilePath(const base::FilePath& path) { |
188 const base::FilePath& path) { | 188 CHECK(!shell_client_); |
189 scoped_ptr<NativeRunner> runner = | 189 scoped_ptr<NativeRunner> runner = |
190 shell_->native_runner_factory_->Create(path); | 190 shell_->native_runner_factory_->Create(path); |
191 bool start_sandboxed = false; | 191 bool start_sandboxed = false; |
192 runner->Start(path, identity_, start_sandboxed, std::move(request), | 192 mojom::ShellClientPtr client = runner->Start( |
193 base::Bind(&Instance::PIDAvailable, | 193 path, identity_, start_sandboxed, |
194 weak_factory_.GetWeakPtr()), | 194 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()), |
195 base::Bind(&mojo::shell::Shell::CleanupRunner, | 195 base::Bind(&mojo::shell::Shell::CleanupRunner, |
196 shell_->weak_ptr_factory_.GetWeakPtr(), | 196 shell_->weak_ptr_factory_.GetWeakPtr(), runner.get())); |
197 runner.get())); | |
198 shell_->native_runners_.push_back(std::move(runner)); | 197 shell_->native_runners_.push_back(std::move(runner)); |
| 198 StartWithClient(std::move(client)); |
199 } | 199 } |
200 | 200 |
201 mojom::InstanceInfoPtr CreateInstanceInfo() const { | 201 mojom::InstanceInfoPtr CreateInstanceInfo() const { |
202 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); | 202 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); |
203 info->id = id_; | 203 info->id = id_; |
204 info->identity = mojom::Identity::From(identity_); | 204 info->identity = mojom::Identity::From(identity_); |
205 info->pid = pid_; | 205 info->pid = pid_; |
206 return info; | 206 return info; |
207 } | 207 } |
208 | 208 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 if (!HasClass(kCapabilityClass_ClientProcess)) { | 292 if (!HasClass(kCapabilityClass_ClientProcess)) { |
293 LOG(ERROR) << "Error: Instance: " << identity_.name() << " attempting " | 293 LOG(ERROR) << "Error: Instance: " << identity_.name() << " attempting " |
294 << "to register an instance for a process it created for " | 294 << "to register an instance for a process it created for " |
295 << "target: " << target.name() << " without the " | 295 << "target: " << target.name() << " without the " |
296 << "mojo:shell{client_process} capability class."; | 296 << "mojo:shell{client_process} capability class."; |
297 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 297 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
298 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 298 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
299 return false; | 299 return false; |
300 } | 300 } |
301 | 301 |
302 if (!(*client_process_connection)->shell_client_factory.is_valid() || | 302 if (!(*client_process_connection)->shell_client.is_valid() || |
303 !(*client_process_connection)->pid_receiver_request.is_valid()) { | 303 !(*client_process_connection)->pid_receiver_request.is_valid()) { |
304 LOG(ERROR) << "Error: must supply both shell_client_factory AND " | 304 LOG(ERROR) << "Error: must supply both shell_client AND " |
305 << "pid_receiver_request when sending " | 305 << "pid_receiver_request when sending " |
306 << "client_process_connection."; | 306 << "client_process_connection."; |
307 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 307 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
308 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 308 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
309 return false; | 309 return false; |
310 } | 310 } |
311 if (shell_->GetExistingOrRootInstance(target)) { | 311 if (shell_->GetExistingOrRootInstance(target)) { |
312 LOG(ERROR) << "Error: Cannot client process matching existing identity:" | 312 LOG(ERROR) << "Error: Cannot client process matching existing identity:" |
313 << "Name: " << target.name() << " User: " << target.user_id() | 313 << "Name: " << target.name() << " User: " << target.user_id() |
314 << " Instance: " << target.instance(); | 314 << " Instance: " << target.instance(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 // may vend multiple application instances, and this object may exist before a | 386 // may vend multiple application instances, and this object may exist before a |
387 // process is launched. | 387 // process is launched. |
388 const uint32_t id_; | 388 const uint32_t id_; |
389 const Identity identity_; | 389 const Identity identity_; |
390 const CapabilitySpec capability_spec_; | 390 const CapabilitySpec capability_spec_; |
391 const bool allow_any_application_; | 391 const bool allow_any_application_; |
392 mojom::ShellClientPtr shell_client_; | 392 mojom::ShellClientPtr shell_client_; |
393 Binding<mojom::PIDReceiver> pid_receiver_binding_; | 393 Binding<mojom::PIDReceiver> pid_receiver_binding_; |
394 BindingSet<mojom::Connector> connectors_; | 394 BindingSet<mojom::Connector> connectors_; |
395 BindingSet<mojom::Shell> shell_bindings_; | 395 BindingSet<mojom::Shell> shell_bindings_; |
396 mojom::ShellClientFactoryPtr factory_; | |
397 NativeRunner* runner_ = nullptr; | 396 NativeRunner* runner_ = nullptr; |
398 base::ProcessId pid_ = base::kNullProcessId; | 397 base::ProcessId pid_ = base::kNullProcessId; |
399 base::WeakPtrFactory<Instance> weak_factory_; | 398 base::WeakPtrFactory<Instance> weak_factory_; |
400 | 399 |
401 DISALLOW_COPY_AND_ASSIGN(Instance); | 400 DISALLOW_COPY_AND_ASSIGN(Instance); |
402 }; | 401 }; |
403 | 402 |
404 // static | 403 // static |
405 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} | 404 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} |
406 Shell::TestAPI::~TestAPI() {} | 405 Shell::TestAPI::~TestAPI() {} |
407 | 406 |
408 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { | 407 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { |
409 for (const auto& entry : shell_->identity_to_instance_) { | 408 for (const auto& entry : shell_->identity_to_instance_) { |
410 if (entry.first.name() == name) | 409 if (entry.first.name() == name) |
411 return true; | 410 return true; |
412 } | 411 } |
413 return false; | 412 return false; |
414 } | 413 } |
415 | 414 |
416 //////////////////////////////////////////////////////////////////////////////// | 415 //////////////////////////////////////////////////////////////////////////////// |
417 // Shell, public: | 416 // Shell, public: |
418 | 417 |
419 Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory, | 418 Shell::Shell(scoped_ptr<NativeRunnerFactory> native_runner_factory, |
420 mojom::ShellClientPtr catalog) | 419 mojom::ShellClientPtr catalog) |
421 : native_runner_factory_(std::move(native_runner_factory)), | 420 : native_runner_factory_(std::move(native_runner_factory)), |
422 weak_ptr_factory_(this) { | 421 weak_ptr_factory_(this) { |
423 mojom::ShellClientPtr client; | 422 mojom::ShellClientPtr client; |
424 mojom::ShellClientRequest request = GetProxy(&client); | 423 mojom::ShellClientRequest request = GetProxy(&client); |
425 CreateInstance(CreateShellIdentity(), GetPermissiveCapabilities(), | 424 Instance* instance = CreateInstance(CreateShellIdentity(), |
426 std::move(client)); | 425 GetPermissiveCapabilities()); |
| 426 instance->StartWithClient(std::move(client)); |
427 shell_connection_.reset(new ShellConnection(this, std::move(request))); | 427 shell_connection_.reset(new ShellConnection(this, std::move(request))); |
428 | 428 |
429 if (catalog) | 429 if (catalog) |
430 InitCatalog(std::move(catalog)); | 430 InitCatalog(std::move(catalog)); |
431 } | 431 } |
432 | 432 |
433 Shell::~Shell() { | 433 Shell::~Shell() { |
434 TerminateShellConnections(); | 434 TerminateShellConnections(); |
435 STLDeleteValues(&name_to_loader_); | 435 STLDeleteValues(&name_to_loader_); |
436 for (auto& runner : native_runners_) | 436 for (auto& runner : native_runners_) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 } | 485 } |
486 } | 486 } |
487 DCHECK(instance); | 487 DCHECK(instance); |
488 return instance->AcceptConnection(connection); | 488 return instance->AcceptConnection(connection); |
489 } | 489 } |
490 | 490 |
491 //////////////////////////////////////////////////////////////////////////////// | 491 //////////////////////////////////////////////////////////////////////////////// |
492 // Shell, private: | 492 // Shell, private: |
493 | 493 |
494 void Shell::InitCatalog(mojom::ShellClientPtr catalog) { | 494 void Shell::InitCatalog(mojom::ShellClientPtr catalog) { |
495 CreateInstance(CreateCatalogIdentity(), CapabilitySpec(), std::move(catalog)); | 495 Instance* instance = |
| 496 CreateInstance(CreateCatalogIdentity(), CapabilitySpec()); |
| 497 instance->StartWithClient(std::move(catalog)); |
496 | 498 |
497 // TODO(beng): this doesn't work anymore. | 499 // TODO(beng): this doesn't work anymore. |
498 // Seed the catalog with manifest info for the shell & catalog. | 500 // Seed the catalog with manifest info for the shell & catalog. |
499 mojo::shell::mojom::ShellResolverPtr resolver; | 501 mojo::shell::mojom::ShellResolverPtr resolver; |
500 shell_connection_->connector()->ConnectToInterface(kCatalogName, &resolver); | 502 shell_connection_->connector()->ConnectToInterface(kCatalogName, &resolver); |
501 resolver->ResolveMojoName(kCatalogName, base::Bind(&EmptyResolverCallback)); | 503 resolver->ResolveMojoName(kCatalogName, base::Bind(&EmptyResolverCallback)); |
502 resolver->ResolveMojoName(kShellName, base::Bind(&EmptyResolverCallback)); | 504 resolver->ResolveMojoName(kShellName, base::Bind(&EmptyResolverCallback)); |
503 } | 505 } |
504 | 506 |
505 void Shell::TerminateShellConnections() { | 507 void Shell::TerminateShellConnections() { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 } | 577 } |
576 | 578 |
577 bool Shell::ConnectToExistingInstance(scoped_ptr<ConnectParams>* params) { | 579 bool Shell::ConnectToExistingInstance(scoped_ptr<ConnectParams>* params) { |
578 Instance* instance = GetExistingOrRootInstance((*params)->target()); | 580 Instance* instance = GetExistingOrRootInstance((*params)->target()); |
579 if (instance) | 581 if (instance) |
580 instance->ConnectToClient(std::move(*params)); | 582 instance->ConnectToClient(std::move(*params)); |
581 return !!instance; | 583 return !!instance; |
582 } | 584 } |
583 | 585 |
584 Shell::Instance* Shell::CreateInstance(const Identity& target, | 586 Shell::Instance* Shell::CreateInstance(const Identity& target, |
585 const CapabilitySpec& spec, | 587 const CapabilitySpec& spec) { |
586 mojom::ShellClientPtr client) { | |
587 CHECK(target.user_id() != mojom::kInheritUserID); | 588 CHECK(target.user_id() != mojom::kInheritUserID); |
588 Instance* instance = new Instance(std::move(client), this, target, spec); | 589 Instance* instance = new Instance(this, target, spec); |
589 DCHECK(identity_to_instance_.find(target) == | 590 DCHECK(identity_to_instance_.find(target) == |
590 identity_to_instance_.end()); | 591 identity_to_instance_.end()); |
591 identity_to_instance_[target] = instance; | 592 identity_to_instance_[target] = instance; |
592 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); | 593 mojom::InstanceInfoPtr info = instance->CreateInstanceInfo(); |
593 instance_listeners_.ForAllPtrs( | 594 instance_listeners_.ForAllPtrs( |
594 [this, &info](mojom::InstanceListener* listener) { | 595 [this, &info](mojom::InstanceListener* listener) { |
595 listener->InstanceCreated(info.Clone()); | 596 listener->InstanceCreated(info.Clone()); |
596 }); | 597 }); |
597 instance->InitializeClient(); | |
598 return instance; | 598 return instance; |
599 } | 599 } |
600 | 600 |
601 void Shell::AddInstanceListener(mojom::InstanceListenerPtr listener) { | 601 void Shell::AddInstanceListener(mojom::InstanceListenerPtr listener) { |
602 // TODO(beng): filter instances provided by those visible to this client. | 602 // TODO(beng): filter instances provided by those visible to this client. |
603 Array<mojom::InstanceInfoPtr> instances; | 603 Array<mojom::InstanceInfoPtr> instances; |
604 for (auto& instance : identity_to_instance_) | 604 for (auto& instance : identity_to_instance_) |
605 instances.push_back(instance.second->CreateInstanceInfo()); | 605 instances.push_back(instance.second->CreateInstanceInfo()); |
606 listener->SetExistingInstances(std::move(instances)); | 606 listener->SetExistingInstances(std::move(instances)); |
607 | 607 |
608 instance_listeners_.AddInterfacePtr(std::move(listener)); | 608 instance_listeners_.AddInterfacePtr(std::move(listener)); |
609 } | 609 } |
610 | 610 |
611 void Shell::CreateShellClient(const Identity& source, | 611 void Shell::CreateShellClientWithFactory(const Identity& source, |
612 const Identity& shell_client_factory, | 612 const Identity& shell_client_factory, |
613 const std::string& name, | 613 const std::string& name, |
614 mojom::ShellClientRequest request) { | 614 mojom::ShellClientRequest request) { |
615 mojom::ShellClientFactory* factory = | 615 mojom::ShellClientFactory* factory = |
616 GetShellClientFactory(shell_client_factory, source); | 616 GetShellClientFactory(shell_client_factory, source); |
617 factory->CreateShellClient(std::move(request), name); | 617 factory->CreateShellClient(std::move(request), name); |
618 } | 618 } |
619 | 619 |
620 mojom::ShellClientFactory* Shell::GetShellClientFactory( | 620 mojom::ShellClientFactory* Shell::GetShellClientFactory( |
621 const Identity& shell_client_factory_identity, | 621 const Identity& shell_client_factory_identity, |
622 const Identity& source_identity) { | 622 const Identity& source_identity) { |
623 auto it = shell_client_factories_.find(shell_client_factory_identity); | 623 auto it = shell_client_factories_.find(shell_client_factory_identity); |
624 if (it != shell_client_factories_.end()) | 624 if (it != shell_client_factories_.end()) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 | 667 |
668 Identity source = params->source(); | 668 Identity source = params->source(); |
669 // |capabilities_ptr| can be null when there is no manifest, e.g. for URL | 669 // |capabilities_ptr| can be null when there is no manifest, e.g. for URL |
670 // types not resolvable by the resolver. | 670 // types not resolvable by the resolver. |
671 CapabilitySpec capabilities = GetPermissiveCapabilities(); | 671 CapabilitySpec capabilities = GetPermissiveCapabilities(); |
672 if (!capabilities_ptr.is_null()) | 672 if (!capabilities_ptr.is_null()) |
673 capabilities = capabilities_ptr.To<CapabilitySpec>(); | 673 capabilities = capabilities_ptr.To<CapabilitySpec>(); |
674 | 674 |
675 mojom::ClientProcessConnectionPtr client_process_connection = | 675 mojom::ClientProcessConnectionPtr client_process_connection = |
676 params->TakeClientProcessConnection(); | 676 params->TakeClientProcessConnection(); |
| 677 Instance* instance = CreateInstance(target, capabilities); |
677 | 678 |
678 mojom::ShellClientRequest request; | 679 // Below are various paths through which a new Instance can be bound to a |
679 if (!client.is_bound()) | 680 // ShellClient proxy. |
680 request = GetProxy(&client); | 681 if (client.is_bound()) { |
| 682 // If a ShellClientPtr was provided, there's no more work to do: someone |
| 683 // is already holding a corresponding ShellClientRequest. |
| 684 instance->StartWithClient(std::move(client)); |
| 685 } else if (!client_process_connection.is_null()) { |
| 686 // Likewise if a ClientProcessConnection was given via Connect(), it |
| 687 // provides the ShellClient proxy to use. |
| 688 instance->StartWithClientProcessConnection( |
| 689 std::move(client_process_connection)); |
| 690 } else { |
| 691 // Otherwise we create a new ShellClient pipe. |
| 692 mojom::ShellClientRequest request = GetProxy(&client); |
| 693 if (LoadWithLoader(target, &request)) { |
| 694 instance->StartWithClient(std::move(client)); |
| 695 } else { |
| 696 CHECK(!file_url.is_null() && !capabilities_ptr.is_null()); |
681 | 697 |
682 Instance* instance = CreateInstance(target, capabilities, std::move(client)); | 698 if (target.name() != resolved_name) { |
683 instance->ConnectToClient(std::move(params)); | 699 instance->StartWithClient(std::move(client)); |
684 | 700 CreateShellClientWithFactory( |
685 // If a ShellClientPtr was provided, there's no more work to do: someone | 701 source, Identity(resolved_name, target.user_id(), instance_name), |
686 // is already holding a corresponding ShellClientRequest. | 702 target.name(), std::move(request)); |
687 if (!request.is_pending()) | 703 } else { |
688 return; | 704 instance->StartWithFilePath(util::UrlToFilePath(file_url.To<GURL>())); |
689 | 705 } |
690 if (client_process_connection.is_null() && LoadWithLoader(target, &request)) | |
691 return; | |
692 | |
693 CHECK(!file_url.is_null() && !capabilities_ptr.is_null()); | |
694 | |
695 if (target.name() != resolved_name) { | |
696 // In cases where a package alias is resolved, we have to use the instance | |
697 // from the original request rather than for the package itself, which will | |
698 // always be the same. | |
699 CreateShellClient( | |
700 source, Identity(resolved_name, target.user_id(), instance_name), | |
701 target.name(), std::move(request)); | |
702 } else { | |
703 if (!client_process_connection.is_null()) { | |
704 // The client already started a process for this instance, use it. | |
705 instance->StartWithClientProcessConnection( | |
706 std::move(request), std::move(client_process_connection)); | |
707 } else { | |
708 // Otherwise we make our own process. | |
709 instance->StartWithFilePath(std::move(request), | |
710 util::UrlToFilePath(file_url.To<GURL>())); | |
711 } | 706 } |
712 } | 707 } |
| 708 |
| 709 // Now that the instance has a ShellClient, we can connect to it. |
| 710 instance->ConnectToClient(std::move(params)); |
713 } | 711 } |
714 | 712 |
715 bool Shell::LoadWithLoader(const Identity& target, | 713 bool Shell::LoadWithLoader(const Identity& target, |
716 mojom::ShellClientRequest* request) { | 714 mojom::ShellClientRequest* request) { |
717 Loader* loader = GetLoaderForName(target.name()); | 715 Loader* loader = GetLoaderForName(target.name()); |
718 if (!loader) | 716 if (!loader) |
719 return false; | 717 return false; |
720 loader->Load(target.name(), std::move(*request)); | 718 loader->Load(target.name(), std::move(*request)); |
721 return true; | 719 return true; |
722 } | 720 } |
723 | 721 |
724 Loader* Shell::GetLoaderForName(const std::string& name) { | 722 Loader* Shell::GetLoaderForName(const std::string& name) { |
725 auto name_it = name_to_loader_.find(name); | 723 auto name_it = name_to_loader_.find(name); |
726 if (name_it != name_to_loader_.end()) | 724 if (name_it != name_to_loader_.end()) |
727 return name_it->second; | 725 return name_it->second; |
728 return default_loader_.get(); | 726 return default_loader_.get(); |
729 } | 727 } |
730 | 728 |
731 void Shell::CleanupRunner(NativeRunner* runner) { | 729 void Shell::CleanupRunner(NativeRunner* runner) { |
732 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 730 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
733 if (it->get() == runner) { | 731 if (it->get() == runner) { |
734 native_runners_.erase(it); | 732 native_runners_.erase(it); |
735 return; | 733 return; |
736 } | 734 } |
737 } | 735 } |
738 } | 736 } |
739 | 737 |
740 } // namespace shell | 738 } // namespace shell |
741 } // namespace mojo | 739 } // namespace mojo |
OLD | NEW |