| 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 |