Chromium Code Reviews| 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 |