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