Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: services/shell/shell.cc

Issue 2118083002: ShellClient -> Service (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mus2
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/shell/shell.h ('k') | services/shell/shell_public.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/shell/shell.h" 5 #include "services/shell/shell.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/guid.h" 13 #include "base/guid.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/process/process.h" 16 #include "base/process/process.h"
17 #include "base/process/process_handle.h" 17 #include "base/process/process_handle.h"
18 #include "base/stl_util.h" 18 #include "base/stl_util.h"
19 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
20 #include "base/trace_event/trace_event.h" 20 #include "base/trace_event/trace_event.h"
21 #include "mojo/public/cpp/bindings/binding.h" 21 #include "mojo/public/cpp/bindings/binding.h"
22 #include "mojo/public/cpp/bindings/binding_set.h" 22 #include "mojo/public/cpp/bindings/binding_set.h"
23 #include "services/shell/connect_util.h" 23 #include "services/shell/connect_util.h"
24 #include "services/shell/public/cpp/connector.h" 24 #include "services/shell/public/cpp/connector.h"
25 #include "services/shell/public/cpp/names.h" 25 #include "services/shell/public/cpp/names.h"
26 #include "services/shell/public/cpp/shell_connection.h" 26 #include "services/shell/public/cpp/shell_connection.h"
27 #include "services/shell/public/interfaces/connector.mojom.h" 27 #include "services/shell/public/interfaces/connector.mojom.h"
28 #include "services/shell/public/interfaces/service.mojom.h"
28 #include "services/shell/public/interfaces/shell.mojom.h" 29 #include "services/shell/public/interfaces/shell.mojom.h"
29 #include "services/shell/public/interfaces/shell_client.mojom.h"
30 30
31 namespace shell { 31 namespace shell {
32 32
33 namespace { 33 namespace {
34 34
35 const char kCatalogName[] = "mojo:catalog"; 35 const char kCatalogName[] = "mojo:catalog";
36 const char kShellName[] = "mojo:shell"; 36 const char kShellName[] = "mojo:shell";
37 const char kCapabilityClass_UserID[] = "shell:user_id"; 37 const char kCapabilityClass_UserID[] = "shell:user_id";
38 const char kCapabilityClass_ClientProcess[] = "shell:client_process"; 38 const char kCapabilityClass_ClientProcess[] = "shell:client_process";
39 const char kCapabilityClass_InstanceName[] = "shell:instance_name"; 39 const char kCapabilityClass_InstanceName[] = "shell:instance_name";
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 auto it = spec.required.find(kShellName); 103 auto it = spec.required.find(kShellName);
104 if (it == spec.required.end()) 104 if (it == spec.required.end())
105 return false; 105 return false;
106 return it->second.classes.find(class_name) != it->second.classes.end(); 106 return it->second.classes.find(class_name) != it->second.classes.end();
107 } 107 }
108 108
109 // Encapsulates a connection to an instance of an application, tracked by the 109 // Encapsulates a connection to an instance of an application, tracked by the
110 // shell's Shell. 110 // shell's Shell.
111 class Shell::Instance : public mojom::Connector, 111 class Shell::Instance : public mojom::Connector,
112 public mojom::PIDReceiver, 112 public mojom::PIDReceiver,
113 public ShellClient, 113 public Service,
114 public InterfaceFactory<mojom::Shell>, 114 public InterfaceFactory<mojom::Shell>,
115 public mojom::Shell { 115 public mojom::Shell {
116 public: 116 public:
117 Instance(shell::Shell* shell, 117 Instance(shell::Shell* shell,
118 const Identity& identity, 118 const Identity& identity,
119 const CapabilitySpec& capability_spec) 119 const CapabilitySpec& capability_spec)
120 : shell_(shell), 120 : shell_(shell),
121 id_(GenerateUniqueID()), 121 id_(GenerateUniqueID()),
122 identity_(identity), 122 identity_(identity),
123 capability_spec_(capability_spec), 123 capability_spec_(capability_spec),
124 allow_any_application_(capability_spec.required.count("*") == 1), 124 allow_any_application_(capability_spec.required.count("*") == 1),
125 pid_receiver_binding_(this), 125 pid_receiver_binding_(this),
126 weak_factory_(this) { 126 weak_factory_(this) {
127 if (identity_.name() == kShellName || identity_.name() == kCatalogName) 127 if (identity_.name() == kShellName || identity_.name() == kCatalogName)
128 pid_ = base::Process::Current().Pid(); 128 pid_ = base::Process::Current().Pid();
129 DCHECK_NE(mojom::kInvalidInstanceID, id_); 129 DCHECK_NE(mojom::kInvalidInstanceID, id_);
130 } 130 }
131 131
132 ~Instance() override { 132 ~Instance() override {
133 if (parent_) 133 if (parent_)
134 parent_->RemoveChild(this); 134 parent_->RemoveChild(this);
135 // |children_| will be modified during destruction. 135 // |children_| will be modified during destruction.
136 std::set<Instance*> children = children_; 136 std::set<Instance*> children = children_;
137 for (auto child : children) 137 for (auto child : children)
138 shell_->OnInstanceError(child); 138 shell_->OnInstanceError(child);
139 139
140 // Shutdown all bindings before we close the runner. This way the process 140 // Shutdown all bindings before we close the runner. This way the process
141 // should see the pipes closed and exit, as well as waking up any potential 141 // should see the pipes closed and exit, as well as waking up any potential
142 // sync/WaitForIncomingResponse(). 142 // sync/WaitForIncomingResponse().
143 shell_client_.reset(); 143 service_.reset();
144 if (pid_receiver_binding_.is_bound()) 144 if (pid_receiver_binding_.is_bound())
145 pid_receiver_binding_.Close(); 145 pid_receiver_binding_.Close();
146 connectors_.CloseAllBindings(); 146 connectors_.CloseAllBindings();
147 shell_bindings_.CloseAllBindings(); 147 shell_bindings_.CloseAllBindings();
148 // Release |runner_| so that if we are called back to OnRunnerCompleted() 148 // Release |runner_| so that if we are called back to OnRunnerCompleted()
149 // we know we're in the destructor. 149 // we know we're in the destructor.
150 std::unique_ptr<NativeRunner> runner = std::move(runner_); 150 std::unique_ptr<NativeRunner> runner = std::move(runner_);
151 runner.reset(); 151 runner.reset();
152 } 152 }
153 153
154 Instance* parent() { return parent_; } 154 Instance* parent() { return parent_; }
155 155
156 void AddChild(Instance* child) { 156 void AddChild(Instance* child) {
157 children_.insert(child); 157 children_.insert(child);
158 child->parent_ = this; 158 child->parent_ = this;
159 } 159 }
160 160
161 void RemoveChild(Instance* child) { 161 void RemoveChild(Instance* child) {
162 auto it = children_.find(child); 162 auto it = children_.find(child);
163 DCHECK(it != children_.end()); 163 DCHECK(it != children_.end());
164 children_.erase(it); 164 children_.erase(it);
165 child->parent_ = nullptr; 165 child->parent_ = nullptr;
166 } 166 }
167 167
168 bool ConnectToClient(std::unique_ptr<ConnectParams>* connect_params) { 168 bool ConnectToClient(std::unique_ptr<ConnectParams>* connect_params) {
169 if (!shell_client_.is_bound()) 169 if (!service_.is_bound())
170 return false; 170 return false;
171 171
172 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); 172 std::unique_ptr<ConnectParams> params(std::move(*connect_params));
173 if (!params->connect_callback().is_null()) { 173 if (!params->connect_callback().is_null()) {
174 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, 174 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
175 identity_.user_id(), id_); 175 identity_.user_id(), id_);
176 } 176 }
177 uint32_t source_id = mojom::kInvalidInstanceID; 177 uint32_t source_id = mojom::kInvalidInstanceID;
178 CapabilityRequest request; 178 CapabilityRequest request;
179 request.interfaces.insert("*"); 179 request.interfaces.insert("*");
180 Instance* source = shell_->GetExistingInstance(params->source()); 180 Instance* source = shell_->GetExistingInstance(params->source());
181 if (source) { 181 if (source) {
182 request = GenerateCapabilityRequestForConnection( 182 request = GenerateCapabilityRequestForConnection(
183 source->capability_spec_, identity_, capability_spec_); 183 source->capability_spec_, identity_, capability_spec_);
184 source_id = source->id(); 184 source_id = source->id();
185 } 185 }
186 186
187 // The target has specified that sources must request one of its provided 187 // The target has specified that sources must request one of its provided
188 // classes instead of specifying a wild-card for interfaces. 188 // classes instead of specifying a wild-card for interfaces.
189 if (HasClass(capability_spec_, kCapabilityClass_ExplicitClass) && 189 if (HasClass(capability_spec_, kCapabilityClass_ExplicitClass) &&
190 (request.interfaces.count("*") != 0)) { 190 (request.interfaces.count("*") != 0)) {
191 request.interfaces.erase("*"); 191 request.interfaces.erase("*");
192 } 192 }
193 193
194 shell_client_->AcceptConnection( 194 service_->OnConnect(
195 mojom::Identity::From(params->source()), source_id, 195 mojom::Identity::From(params->source()), source_id,
196 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), 196 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(),
197 mojom::CapabilityRequest::From(request), params->target().name()); 197 mojom::CapabilityRequest::From(request), params->target().name());
198 198
199 return true; 199 return true;
200 } 200 }
201 201
202 void StartWithClient(mojom::ShellClientPtr client) { 202 void StartWithClient(mojom::ServicePtr client) {
203 CHECK(!shell_client_); 203 CHECK(!service_);
204 shell_client_ = std::move(client); 204 service_ = std::move(client);
205 shell_client_.set_connection_error_handler( 205 service_.set_connection_error_handler(
206 base::Bind(&Instance::OnShellClientLost, base::Unretained(this), 206 base::Bind(&Instance::OnServiceLost, base::Unretained(this),
207 shell_->GetWeakPtr())); 207 shell_->GetWeakPtr()));
208 shell_client_->Initialize(mojom::Identity::From(identity_), id_, 208 service_->OnStart(mojom::Identity::From(identity_), id_,
209 base::Bind(&Instance::OnInitializeResponse, 209 base::Bind(&Instance::OnInitializeResponse,
210 base::Unretained(this))); 210 base::Unretained(this)));
211 } 211 }
212 212
213 void StartWithClientProcessConnection( 213 void StartWithClientProcessConnection(
214 mojom::ClientProcessConnectionPtr client_process_connection) { 214 mojom::ClientProcessConnectionPtr client_process_connection) {
215 mojom::ShellClientPtr client; 215 mojom::ServicePtr client;
216 client.Bind(mojom::ShellClientPtrInfo( 216 client.Bind(mojom::ServicePtrInfo(
217 std::move(client_process_connection->shell_client), 0)); 217 std::move(client_process_connection->service), 0));
218 pid_receiver_binding_.Bind( 218 pid_receiver_binding_.Bind(
219 std::move(client_process_connection->pid_receiver_request)); 219 std::move(client_process_connection->pid_receiver_request));
220 StartWithClient(std::move(client)); 220 StartWithClient(std::move(client));
221 } 221 }
222 222
223 void StartWithFilePath(const base::FilePath& path) { 223 void StartWithFilePath(const base::FilePath& path) {
224 CHECK(!shell_client_); 224 CHECK(!service_);
225 runner_ = shell_->native_runner_factory_->Create(path); 225 runner_ = shell_->native_runner_factory_->Create(path);
226 bool start_sandboxed = false; 226 bool start_sandboxed = false;
227 mojom::ShellClientPtr client = runner_->Start( 227 mojom::ServicePtr client = runner_->Start(
228 path, identity_, start_sandboxed, 228 path, identity_, start_sandboxed,
229 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()), 229 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()),
230 base::Bind(&Instance::OnRunnerCompleted, weak_factory_.GetWeakPtr())); 230 base::Bind(&Instance::OnRunnerCompleted, weak_factory_.GetWeakPtr()));
231 StartWithClient(std::move(client)); 231 StartWithClient(std::move(client));
232 } 232 }
233 233
234 mojom::InstanceInfoPtr CreateInstanceInfo() const { 234 mojom::InstanceInfoPtr CreateInstanceInfo() const {
235 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New()); 235 mojom::InstanceInfoPtr info(mojom::InstanceInfo::New());
236 info->id = id_; 236 info->id = id_;
237 info->identity = mojom::Identity::From(identity_); 237 info->identity = mojom::Identity::From(identity_);
238 info->pid = pid_; 238 info->pid = pid_;
239 return info; 239 return info;
240 } 240 }
241 241
242 const CapabilitySpec& capability_spec() const { 242 const CapabilitySpec& capability_spec() const {
243 return capability_spec_; 243 return capability_spec_;
244 } 244 }
245 const Identity& identity() const { return identity_; } 245 const Identity& identity() const { return identity_; }
246 uint32_t id() const { return id_; } 246 uint32_t id() const { return id_; }
247 247
248 // ShellClient: 248 // Service:
249 bool AcceptConnection(Connection* connection) override { 249 bool OnConnect(Connection* connection) override {
250 connection->AddInterface<mojom::Shell>(this); 250 connection->AddInterface<mojom::Shell>(this);
251 return true; 251 return true;
252 } 252 }
253 253
254 private: 254 private:
255 // mojom::Connector implementation: 255 // mojom::Connector implementation:
256 void Connect(mojom::IdentityPtr target_ptr, 256 void Connect(mojom::IdentityPtr target_ptr,
257 mojom::InterfaceProviderRequest remote_interfaces, 257 mojom::InterfaceProviderRequest remote_interfaces,
258 mojom::InterfaceProviderPtr local_interfaces, 258 mojom::InterfaceProviderPtr local_interfaces,
259 mojom::ClientProcessConnectionPtr client_process_connection, 259 mojom::ClientProcessConnectionPtr client_process_connection,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 if (!HasClass(capability_spec_, kCapabilityClass_ClientProcess)) { 328 if (!HasClass(capability_spec_, kCapabilityClass_ClientProcess)) {
329 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " 329 LOG(ERROR) << "Instance: " << identity_.name() << " attempting "
330 << "to register an instance for a process it created for " 330 << "to register an instance for a process it created for "
331 << "target: " << target.name() << " without the " 331 << "target: " << target.name() << " without the "
332 << "mojo:shell{client_process} capability class."; 332 << "mojo:shell{client_process} capability class.";
333 callback.Run(mojom::ConnectResult::ACCESS_DENIED, 333 callback.Run(mojom::ConnectResult::ACCESS_DENIED,
334 mojom::kInheritUserID, mojom::kInvalidInstanceID); 334 mojom::kInheritUserID, mojom::kInvalidInstanceID);
335 return false; 335 return false;
336 } 336 }
337 337
338 if (!(*client_process_connection)->shell_client.is_valid() || 338 if (!(*client_process_connection)->service.is_valid() ||
339 !(*client_process_connection)->pid_receiver_request.is_valid()) { 339 !(*client_process_connection)->pid_receiver_request.is_valid()) {
340 LOG(ERROR) << "Must supply both shell_client AND " 340 LOG(ERROR) << "Must supply both service AND "
341 << "pid_receiver_request when sending " 341 << "pid_receiver_request when sending "
342 << "client_process_connection."; 342 << "client_process_connection.";
343 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, 343 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
344 mojom::kInheritUserID, mojom::kInvalidInstanceID); 344 mojom::kInheritUserID, mojom::kInvalidInstanceID);
345 return false; 345 return false;
346 } 346 }
347 if (shell_->GetExistingInstance(target)) { 347 if (shell_->GetExistingInstance(target)) {
348 LOG(ERROR) << "Cannot client process matching existing identity:" 348 LOG(ERROR) << "Cannot client process matching existing identity:"
349 << "Name: " << target.name() << " User: " 349 << "Name: " << target.name() << " User: "
350 << target.user_id() << " Instance: " << target.instance(); 350 << target.user_id() << " Instance: " << target.instance();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 406
407 void PIDAvailable(base::ProcessId pid) { 407 void PIDAvailable(base::ProcessId pid) {
408 if (pid == base::kNullProcessId) { 408 if (pid == base::kNullProcessId) {
409 shell_->OnInstanceError(this); 409 shell_->OnInstanceError(this);
410 return; 410 return;
411 } 411 }
412 pid_ = pid; 412 pid_ = pid;
413 shell_->NotifyPIDAvailable(id_, pid_); 413 shell_->NotifyPIDAvailable(id_, pid_);
414 } 414 }
415 415
416 void OnShellClientLost(base::WeakPtr<shell::Shell> shell) { 416 void OnServiceLost(base::WeakPtr<shell::Shell> shell) {
417 shell_client_.reset(); 417 service_.reset();
418 OnConnectionLost(shell); 418 OnConnectionLost(shell);
419 } 419 }
420 420
421 void OnConnectionLost(base::WeakPtr<shell::Shell> shell) { 421 void OnConnectionLost(base::WeakPtr<shell::Shell> shell) {
422 // Any time a Connector is lost or we lose the ShellClient connection, it 422 // Any time a Connector is lost or we lose the Service connection, it
423 // may have been the last pipe using this Instance. If so, clean up. 423 // may have been the last pipe using this Instance. If so, clean up.
424 if (shell && connectors_.empty() && !shell_client_) { 424 if (shell && connectors_.empty() && !service_) {
425 // Deletes |this|. 425 // Deletes |this|.
426 shell->OnInstanceError(this); 426 shell->OnInstanceError(this);
427 } 427 }
428 } 428 }
429 429
430 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { 430 void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
431 if (connector_request.is_pending()) { 431 if (connector_request.is_pending()) {
432 connectors_.AddBinding(this, std::move(connector_request)); 432 connectors_.AddBinding(this, std::move(connector_request));
433 connectors_.set_connection_error_handler( 433 connectors_.set_connection_error_handler(
434 base::Bind(&Instance::OnConnectionLost, base::Unretained(this), 434 base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
(...skipping 12 matching lines...) Expand all
447 shell::Shell* const shell_; 447 shell::Shell* const shell_;
448 448
449 // An id that identifies this instance. Distinct from pid, as a single process 449 // An id that identifies this instance. Distinct from pid, as a single process
450 // may vend multiple application instances, and this object may exist before a 450 // may vend multiple application instances, and this object may exist before a
451 // process is launched. 451 // process is launched.
452 const uint32_t id_; 452 const uint32_t id_;
453 const Identity identity_; 453 const Identity identity_;
454 const CapabilitySpec capability_spec_; 454 const CapabilitySpec capability_spec_;
455 const bool allow_any_application_; 455 const bool allow_any_application_;
456 std::unique_ptr<NativeRunner> runner_; 456 std::unique_ptr<NativeRunner> runner_;
457 mojom::ShellClientPtr shell_client_; 457 mojom::ServicePtr service_;
458 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; 458 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
459 mojo::BindingSet<mojom::Connector> connectors_; 459 mojo::BindingSet<mojom::Connector> connectors_;
460 mojo::BindingSet<mojom::Shell> shell_bindings_; 460 mojo::BindingSet<mojom::Shell> shell_bindings_;
461 base::ProcessId pid_ = base::kNullProcessId; 461 base::ProcessId pid_ = base::kNullProcessId;
462 Instance* parent_ = nullptr; 462 Instance* parent_ = nullptr;
463 std::set<Instance*> children_; 463 std::set<Instance*> children_;
464 base::WeakPtrFactory<Instance> weak_factory_; 464 base::WeakPtrFactory<Instance> weak_factory_;
465 465
466 DISALLOW_COPY_AND_ASSIGN(Instance); 466 DISALLOW_COPY_AND_ASSIGN(Instance);
467 }; 467 };
468 468
469 // static 469 // static
470 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {} 470 Shell::TestAPI::TestAPI(Shell* shell) : shell_(shell) {}
471 Shell::TestAPI::~TestAPI() {} 471 Shell::TestAPI::~TestAPI() {}
472 472
473 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const { 473 bool Shell::TestAPI::HasRunningInstanceForName(const std::string& name) const {
474 for (const auto& entry : shell_->identity_to_instance_) { 474 for (const auto& entry : shell_->identity_to_instance_) {
475 if (entry.first.name() == name) 475 if (entry.first.name() == name)
476 return true; 476 return true;
477 } 477 }
478 return false; 478 return false;
479 } 479 }
480 480
481 //////////////////////////////////////////////////////////////////////////////// 481 ////////////////////////////////////////////////////////////////////////////////
482 // Shell, public: 482 // Shell, public:
483 483
484 Shell::Shell(std::unique_ptr<NativeRunnerFactory> native_runner_factory, 484 Shell::Shell(std::unique_ptr<NativeRunnerFactory> native_runner_factory,
485 mojom::ShellClientPtr catalog) 485 mojom::ServicePtr catalog)
486 : native_runner_factory_(std::move(native_runner_factory)), 486 : native_runner_factory_(std::move(native_runner_factory)),
487 weak_ptr_factory_(this) { 487 weak_ptr_factory_(this) {
488 mojom::ShellClientPtr client; 488 mojom::ServicePtr client;
489 mojom::ShellClientRequest request = mojo::GetProxy(&client); 489 mojom::ServiceRequest request = mojo::GetProxy(&client);
490 Instance* instance = CreateInstance(Identity(), CreateShellIdentity(), 490 Instance* instance = CreateInstance(Identity(), CreateShellIdentity(),
491 GetPermissiveCapabilities()); 491 GetPermissiveCapabilities());
492 instance->StartWithClient(std::move(client)); 492 instance->StartWithClient(std::move(client));
493 singletons_.insert(kShellName); 493 singletons_.insert(kShellName);
494 shell_connection_.reset(new ShellConnection(this, std::move(request))); 494 shell_connection_.reset(new ShellConnection(this, std::move(request)));
495 495
496 if (catalog) 496 if (catalog)
497 InitCatalog(std::move(catalog)); 497 InitCatalog(std::move(catalog));
498 } 498 }
499 499
500 Shell::~Shell() { 500 Shell::~Shell() {
501 TerminateShellConnections(); 501 TerminateShellConnections();
502 // Terminate any remaining instances. 502 // Terminate any remaining instances.
503 while (!identity_to_instance_.empty()) 503 while (!identity_to_instance_.empty())
504 OnInstanceError(identity_to_instance_.begin()->second); 504 OnInstanceError(identity_to_instance_.begin()->second);
505 identity_to_resolver_.clear(); 505 identity_to_resolver_.clear();
506 } 506 }
507 507
508 void Shell::SetInstanceQuitCallback( 508 void Shell::SetInstanceQuitCallback(
509 base::Callback<void(const Identity&)> callback) { 509 base::Callback<void(const Identity&)> callback) {
510 instance_quit_callback_ = callback; 510 instance_quit_callback_ = callback;
511 } 511 }
512 512
513 void Shell::Connect(std::unique_ptr<ConnectParams> params) { 513 void Shell::Connect(std::unique_ptr<ConnectParams> params) {
514 Connect(std::move(params), nullptr); 514 Connect(std::move(params), nullptr);
515 } 515 }
516 516
517 mojom::ShellClientRequest Shell::InitInstanceForEmbedder( 517 mojom::ServiceRequest Shell::InitInstanceForEmbedder(
518 const std::string& name) { 518 const std::string& name) {
519 std::unique_ptr<ConnectParams> params(new ConnectParams); 519 std::unique_ptr<ConnectParams> params(new ConnectParams);
520 520
521 Identity embedder_identity(name, mojom::kRootUserID); 521 Identity embedder_identity(name, mojom::kRootUserID);
522 params->set_source(embedder_identity); 522 params->set_source(embedder_identity);
523 params->set_target(embedder_identity); 523 params->set_target(embedder_identity);
524 524
525 mojom::ShellClientPtr client; 525 mojom::ServicePtr client;
526 mojom::ShellClientRequest request = mojo::GetProxy(&client); 526 mojom::ServiceRequest request = mojo::GetProxy(&client);
527 Connect(std::move(params), std::move(client)); 527 Connect(std::move(params), std::move(client));
528 528
529 return request; 529 return request;
530 } 530 }
531 531
532 //////////////////////////////////////////////////////////////////////////////// 532 ////////////////////////////////////////////////////////////////////////////////
533 // Shell, ShellClient implementation: 533 // Shell, Service implementation:
534 534
535 bool Shell::AcceptConnection(Connection* connection) { 535 bool Shell::OnConnect(Connection* connection) {
536 // The only interface we expose is mojom::Shell, and access to this interface 536 // The only interface we expose is mojom::Shell, and access to this interface
537 // is brokered by a policy specific to each caller, managed by the caller's 537 // is brokered by a policy specific to each caller, managed by the caller's
538 // instance. Here we look to see who's calling, and forward to the caller's 538 // instance. Here we look to see who's calling, and forward to the caller's
539 // instance to continue. 539 // instance to continue.
540 Instance* instance = nullptr; 540 Instance* instance = nullptr;
541 for (const auto& entry : identity_to_instance_) { 541 for (const auto& entry : identity_to_instance_) {
542 if (entry.second->id() == connection->GetRemoteInstanceID()) { 542 if (entry.second->id() == connection->GetRemoteInstanceID()) {
543 instance = entry.second; 543 instance = entry.second;
544 break; 544 break;
545 } 545 }
546 } 546 }
547 DCHECK(instance); 547 DCHECK(instance);
548 return instance->AcceptConnection(connection); 548 return instance->OnConnect(connection);
549 } 549 }
550 550
551 //////////////////////////////////////////////////////////////////////////////// 551 ////////////////////////////////////////////////////////////////////////////////
552 // Shell, private: 552 // Shell, private:
553 553
554 void Shell::InitCatalog(mojom::ShellClientPtr catalog) { 554 void Shell::InitCatalog(mojom::ServicePtr catalog) {
555 // TODO(beng): It'd be great to build this from the manifest, however there's 555 // TODO(beng): It'd be great to build this from the manifest, however there's
556 // a bit of a chicken-and-egg problem. 556 // a bit of a chicken-and-egg problem.
557 CapabilitySpec spec; 557 CapabilitySpec spec;
558 Interfaces interfaces; 558 Interfaces interfaces;
559 interfaces.insert("filesystem::mojom::Directory"); 559 interfaces.insert("filesystem::mojom::Directory");
560 spec.provided["app"] = interfaces; 560 spec.provided["app"] = interfaces;
561 Instance* instance = CreateInstance(CreateShellIdentity(), 561 Instance* instance = CreateInstance(CreateShellIdentity(),
562 CreateCatalogIdentity(), 562 CreateCatalogIdentity(),
563 spec); 563 spec);
564 singletons_.insert(kCatalogName); 564 singletons_.insert(kCatalogName);
(...skipping 27 matching lines...) Expand all
592 identity_to_instance_.erase(it); 592 identity_to_instance_.erase(it);
593 instance_listeners_.ForAllPtrs([this, id](mojom::InstanceListener* listener) { 593 instance_listeners_.ForAllPtrs([this, id](mojom::InstanceListener* listener) {
594 listener->InstanceDestroyed(id); 594 listener->InstanceDestroyed(id);
595 }); 595 });
596 delete instance; 596 delete instance;
597 if (!instance_quit_callback_.is_null()) 597 if (!instance_quit_callback_.is_null())
598 instance_quit_callback_.Run(identity); 598 instance_quit_callback_.Run(identity);
599 } 599 }
600 600
601 void Shell::Connect(std::unique_ptr<ConnectParams> params, 601 void Shell::Connect(std::unique_ptr<ConnectParams> params,
602 mojom::ShellClientPtr client) { 602 mojom::ServicePtr client) {
603 TRACE_EVENT_INSTANT1("mojo_shell", "Shell::Connect", 603 TRACE_EVENT_INSTANT1("mojo_shell", "Shell::Connect",
604 TRACE_EVENT_SCOPE_THREAD, "original_name", 604 TRACE_EVENT_SCOPE_THREAD, "original_name",
605 params->target().name()); 605 params->target().name());
606 DCHECK(IsValidName(params->target().name())); 606 DCHECK(IsValidName(params->target().name()));
607 DCHECK(base::IsValidGUID(params->target().user_id())); 607 DCHECK(base::IsValidGUID(params->target().user_id()));
608 DCHECK_NE(mojom::kInheritUserID, params->target().user_id()); 608 DCHECK_NE(mojom::kInheritUserID, params->target().user_id());
609 DCHECK(!client.is_bound() || !identity_to_instance_.count(params->target())); 609 DCHECK(!client.is_bound() || !identity_to_instance_.count(params->target()));
610 610
611 // Connect to an existing matching instance, if possible. 611 // Connect to an existing matching instance, if possible.
612 if (!client.is_bound() && ConnectToExistingInstance(&params)) 612 if (!client.is_bound() && ConnectToExistingInstance(&params))
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 void Shell::AddInstanceListener(mojom::InstanceListenerPtr listener) { 675 void Shell::AddInstanceListener(mojom::InstanceListenerPtr listener) {
676 // TODO(beng): filter instances provided by those visible to this client. 676 // TODO(beng): filter instances provided by those visible to this client.
677 mojo::Array<mojom::InstanceInfoPtr> instances; 677 mojo::Array<mojom::InstanceInfoPtr> instances;
678 for (auto& instance : identity_to_instance_) 678 for (auto& instance : identity_to_instance_)
679 instances.push_back(instance.second->CreateInstanceInfo()); 679 instances.push_back(instance.second->CreateInstanceInfo());
680 listener->SetExistingInstances(std::move(instances)); 680 listener->SetExistingInstances(std::move(instances));
681 681
682 instance_listeners_.AddPtr(std::move(listener)); 682 instance_listeners_.AddPtr(std::move(listener));
683 } 683 }
684 684
685 void Shell::CreateShellClientWithFactory(const Identity& shell_client_factory, 685 void Shell::CreateServiceWithFactory(const Identity& service_factory,
686 const std::string& name, 686 const std::string& name,
687 mojom::ShellClientRequest request) { 687 mojom::ServiceRequest request) {
688 mojom::ShellClientFactory* factory = 688 mojom::ServiceFactory* factory = GetServiceFactory(service_factory);
689 GetShellClientFactory(shell_client_factory); 689 factory->CreateService(std::move(request), name);
690 factory->CreateShellClient(std::move(request), name);
691 } 690 }
692 691
693 mojom::ShellClientFactory* Shell::GetShellClientFactory( 692 mojom::ServiceFactory* Shell::GetServiceFactory(
694 const Identity& shell_client_factory_identity) { 693 const Identity& service_factory_identity) {
695 auto it = shell_client_factories_.find(shell_client_factory_identity); 694 auto it = service_factories_.find(service_factory_identity);
696 if (it != shell_client_factories_.end()) 695 if (it != service_factories_.end())
697 return it->second.get(); 696 return it->second.get();
698 697
699 Identity source_identity(kShellName, mojom::kInheritUserID); 698 Identity source_identity(kShellName, mojom::kInheritUserID);
700 mojom::ShellClientFactoryPtr factory; 699 mojom::ServiceFactoryPtr factory;
701 ConnectToInterface(this, source_identity, shell_client_factory_identity, 700 ConnectToInterface(this, source_identity, service_factory_identity,
702 &factory); 701 &factory);
703 mojom::ShellClientFactory* factory_interface = factory.get(); 702 mojom::ServiceFactory* factory_interface = factory.get();
704 factory.set_connection_error_handler(base::Bind( 703 factory.set_connection_error_handler(base::Bind(
705 &shell::Shell::OnShellClientFactoryLost, weak_ptr_factory_.GetWeakPtr(), 704 &shell::Shell::OnServiceFactoryLost, weak_ptr_factory_.GetWeakPtr(),
706 shell_client_factory_identity)); 705 service_factory_identity));
707 shell_client_factories_[shell_client_factory_identity] = std::move(factory); 706 service_factories_[service_factory_identity] = std::move(factory);
708 return factory_interface; 707 return factory_interface;
709 } 708 }
710 709
711 void Shell::OnShellClientFactoryLost(const Identity& which) { 710 void Shell::OnServiceFactoryLost(const Identity& which) {
712 // Remove the mapping. 711 // Remove the mapping.
713 auto it = shell_client_factories_.find(which); 712 auto it = service_factories_.find(which);
714 DCHECK(it != shell_client_factories_.end()); 713 DCHECK(it != service_factories_.end());
715 shell_client_factories_.erase(it); 714 service_factories_.erase(it);
716 } 715 }
717 716
718 void Shell::OnGotResolvedName(std::unique_ptr<ConnectParams> params, 717 void Shell::OnGotResolvedName(std::unique_ptr<ConnectParams> params,
719 mojom::ShellClientPtr client, 718 mojom::ServicePtr client,
720 mojom::ResolveResultPtr result) { 719 mojom::ResolveResultPtr result) {
721 std::string instance_name = params->target().instance(); 720 std::string instance_name = params->target().instance();
722 if (instance_name == GetNamePath(params->target().name()) && 721 if (instance_name == GetNamePath(params->target().name()) &&
723 result->qualifier != GetNamePath(result->resolved_name)) { 722 result->qualifier != GetNamePath(result->resolved_name)) {
724 instance_name = result->qualifier; 723 instance_name = result->qualifier;
725 } 724 }
726 Identity target(params->target().name(), params->target().user_id(), 725 Identity target(params->target().name(), params->target().user_id(),
727 instance_name); 726 instance_name);
728 params->set_target(target); 727 params->set_target(target);
729 728
(...skipping 23 matching lines...) Expand all
753 } else { 752 } else {
754 source_identity_for_creation = params->source(); 753 source_identity_for_creation = params->source();
755 } 754 }
756 755
757 mojom::ClientProcessConnectionPtr client_process_connection = 756 mojom::ClientProcessConnectionPtr client_process_connection =
758 params->TakeClientProcessConnection(); 757 params->TakeClientProcessConnection();
759 Instance* instance = CreateInstance(source_identity_for_creation, 758 Instance* instance = CreateInstance(source_identity_for_creation,
760 target, capabilities); 759 target, capabilities);
761 760
762 // Below are various paths through which a new Instance can be bound to a 761 // Below are various paths through which a new Instance can be bound to a
763 // ShellClient proxy. 762 // Service proxy.
764 if (client.is_bound()) { 763 if (client.is_bound()) {
765 // If a ShellClientPtr was provided, there's no more work to do: someone 764 // If a ServicePtr was provided, there's no more work to do: someone
766 // is already holding a corresponding ShellClientRequest. 765 // is already holding a corresponding ServiceRequest.
767 instance->StartWithClient(std::move(client)); 766 instance->StartWithClient(std::move(client));
768 } else if (!client_process_connection.is_null()) { 767 } else if (!client_process_connection.is_null()) {
769 // Likewise if a ClientProcessConnection was given via Connect(), it 768 // Likewise if a ClientProcessConnection was given via Connect(), it
770 // provides the ShellClient proxy to use. 769 // provides the Service proxy to use.
771 instance->StartWithClientProcessConnection( 770 instance->StartWithClientProcessConnection(
772 std::move(client_process_connection)); 771 std::move(client_process_connection));
773 } else { 772 } else {
774 // Otherwise we create a new ShellClient pipe. 773 // Otherwise we create a new Service pipe.
775 mojom::ShellClientRequest request = GetProxy(&client); 774 mojom::ServiceRequest request = GetProxy(&client);
776 CHECK(!result->package_path.empty() && !result->capabilities.is_null()); 775 CHECK(!result->package_path.empty() && !result->capabilities.is_null());
777 776
778 if (target.name() != result->resolved_name) { 777 if (target.name() != result->resolved_name) {
779 instance->StartWithClient(std::move(client)); 778 instance->StartWithClient(std::move(client));
780 Identity factory(result->resolved_name, target.user_id(), 779 Identity factory(result->resolved_name, target.user_id(),
781 instance_name); 780 instance_name);
782 CreateShellClientWithFactory(factory, target.name(), 781 CreateServiceWithFactory(factory, target.name(),
783 std::move(request)); 782 std::move(request));
784 } else { 783 } else {
785 instance->StartWithFilePath(result->package_path); 784 instance->StartWithFilePath(result->package_path);
786 } 785 }
787 } 786 }
788 787
789 // Now that the instance has a ShellClient, we can connect to it. 788 // Now that the instance has a Service, we can connect to it.
790 bool connected = instance->ConnectToClient(&params); 789 bool connected = instance->ConnectToClient(&params);
791 DCHECK(connected); 790 DCHECK(connected);
792 } 791 }
793 792
794 base::WeakPtr<Shell> Shell::GetWeakPtr() { 793 base::WeakPtr<Shell> Shell::GetWeakPtr() {
795 return weak_ptr_factory_.GetWeakPtr(); 794 return weak_ptr_factory_.GetWeakPtr();
796 } 795 }
797 796
798 } // namespace shell 797 } // namespace shell
OLDNEW
« no previous file with comments | « services/shell/shell.h ('k') | services/shell/shell_public.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698