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

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

Issue 2440903002: Make "all user" services work when packaged. (Closed)
Patch Set: Fixed other tests Created 4 years, 2 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
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/service_manager/service_manager.h" 5 #include "services/service_manager/service_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 public: 118 public:
119 Instance(service_manager::ServiceManager* service_manager, 119 Instance(service_manager::ServiceManager* service_manager,
120 const Identity& identity, 120 const Identity& identity,
121 const InterfaceProviderSpec& connection_spec) 121 const InterfaceProviderSpec& connection_spec)
122 : service_manager_(service_manager), 122 : service_manager_(service_manager),
123 id_(GenerateUniqueID()), 123 id_(GenerateUniqueID()),
124 identity_(identity), 124 identity_(identity),
125 connection_spec_(connection_spec), 125 connection_spec_(connection_spec),
126 allow_any_application_(connection_spec.requires.count("*") == 1), 126 allow_any_application_(connection_spec.requires.count("*") == 1),
127 pid_receiver_binding_(this), 127 pid_receiver_binding_(this),
128 state_(State::IDLE),
128 weak_factory_(this) { 129 weak_factory_(this) {
129 if (identity_.name() == kServiceManagerName || 130 if (identity_.name() == kServiceManagerName ||
130 identity_.name() == kCatalogName) { 131 identity_.name() == kCatalogName) {
131 pid_ = base::Process::Current().Pid(); 132 pid_ = base::Process::Current().Pid();
132 } 133 }
133 DCHECK_NE(mojom::kInvalidInstanceID, id_); 134 DCHECK_NE(mojom::kInvalidInstanceID, id_);
134 } 135 }
135 136
136 ~Instance() override { 137 ~Instance() override {
137 // Shutdown all bindings before we close the runner. This way the process 138 // Shutdown all bindings before we close the runner. This way the process
138 // should see the pipes closed and exit, as well as waking up any potential 139 // should see the pipes closed and exit, as well as waking up any potential
139 // sync/WaitForIncomingResponse(). 140 // sync/WaitForIncomingResponse().
140 service_.reset(); 141 service_.reset();
141 if (pid_receiver_binding_.is_bound()) 142 if (pid_receiver_binding_.is_bound())
142 pid_receiver_binding_.Close(); 143 pid_receiver_binding_.Close();
143 connectors_.CloseAllBindings(); 144 connectors_.CloseAllBindings();
144 service_manager_bindings_.CloseAllBindings(); 145 service_manager_bindings_.CloseAllBindings();
145 146
146 // Notify the ServiceManager that this Instance is really going away. 147 if (state_ == State::STARTING) {
147 service_manager_->OnInstanceStopped(identity_); 148 service_manager_->NotifyServiceFailedToStart(identity_);
149 } else {
150 // Notify the ServiceManager that this Instance is really going away.
151 service_manager_->OnInstanceStopped(identity_);
152 }
148 153
149 // Release |runner_| so that if we are called back to OnRunnerCompleted() 154 // Release |runner_| so that if we are called back to OnRunnerCompleted()
150 // we know we're in the destructor. 155 // we know we're in the destructor.
151 std::unique_ptr<NativeRunner> runner = std::move(runner_); 156 std::unique_ptr<NativeRunner> runner = std::move(runner_);
152 runner.reset(); 157 runner.reset();
153 } 158 }
154 159
155 Instance* parent() { return parent_; } 160 Instance* parent() const { return parent_; }
156 161
157 void AddChild(std::unique_ptr<Instance> child) { 162 void AddChild(std::unique_ptr<Instance> child) {
158 child->parent_ = this; 163 child->parent_ = this;
159 children_.insert(std::make_pair(child.get(), std::move(child))); 164 children_.insert(std::make_pair(child.get(), std::move(child)));
160 } 165 }
161 166
162 void RemoveChild(Instance* child) { 167 void RemoveChild(Instance* child) {
163 auto it = children_.find(child); 168 auto it = children_.find(child);
164 DCHECK(it != children_.end()); 169 DCHECK(it != children_.end());
165 170
(...skipping 29 matching lines...) Expand all
195 interfaces.erase("*"); 200 interfaces.erase("*");
196 } 201 }
197 202
198 service_->OnConnect(params->source(), params->TakeRemoteInterfaces(), 203 service_->OnConnect(params->source(), params->TakeRemoteInterfaces(),
199 interfaces, capabilities); 204 interfaces, capabilities);
200 return true; 205 return true;
201 } 206 }
202 207
203 void StartWithService(mojom::ServicePtr service) { 208 void StartWithService(mojom::ServicePtr service) {
204 CHECK(!service_); 209 CHECK(!service_);
210 state_ = State::STARTING;
205 service_ = std::move(service); 211 service_ = std::move(service);
206 service_.set_connection_error_handler( 212 service_.set_connection_error_handler(
207 base::Bind(&Instance::OnServiceLost, base::Unretained(this), 213 base::Bind(&Instance::OnServiceLost, base::Unretained(this),
208 service_manager_->GetWeakPtr())); 214 service_manager_->GetWeakPtr()));
209 service_->OnStart(identity_, 215 service_->OnStart(identity_,
210 base::Bind(&Instance::OnInitializeResponse, 216 base::Bind(&Instance::OnInitializeResponse,
211 base::Unretained(this))); 217 base::Unretained(this)));
212 } 218 }
213 219
214 void StartWithClientProcessConnection( 220 void StartWithClientProcessConnection(
(...skipping 22 matching lines...) Expand all
237 info->id = id_; 243 info->id = id_;
238 info->identity = identity_; 244 info->identity = identity_;
239 info->pid = pid_; 245 info->pid = pid_;
240 return info; 246 return info;
241 } 247 }
242 248
243 const InterfaceProviderSpec& connection_spec() const { 249 const InterfaceProviderSpec& connection_spec() const {
244 return connection_spec_; 250 return connection_spec_;
245 } 251 }
246 const Identity& identity() const { return identity_; } 252 const Identity& identity() const { return identity_; }
253 void set_identity(const Identity& identity) { identity_ = identity; }
247 uint32_t id() const { return id_; } 254 uint32_t id() const { return id_; }
248 255
249 // Service: 256 // Service:
250 bool OnConnect(const Identity& remote_identity, 257 bool OnConnect(const Identity& remote_identity,
251 InterfaceRegistry* registry) override { 258 InterfaceRegistry* registry) override {
252 Instance* source = service_manager_->GetExistingInstance(remote_identity); 259 Instance* source = service_manager_->GetExistingInstance(remote_identity);
253 DCHECK(source); 260 DCHECK(source);
254 if (HasCapability(source->connection_spec_, kCapability_ServiceManager)) { 261 if (HasCapability(source->connection_spec_, kCapability_ServiceManager)) {
255 registry->AddInterface<mojom::ServiceManager>(this); 262 registry->AddInterface<mojom::ServiceManager>(this);
256 return true; 263 return true;
257 } 264 }
258 return false; 265 return false;
259 } 266 }
260 267
261 private: 268 private:
269 enum class State {
270 // This connection was not started yet.
Ken Rockot(use gerrit already) 2016/10/21 19:52:33 nit: in these comments I think s/connection/instan
Jay Civelli 2016/10/21 20:48:33 Done.
271 IDLE,
272
273 // The connection was started but no success was reported.
274 STARTING,
275
276 // The connection was started successfully.
277 STARTED
278 };
279
262 // mojom::Connector implementation: 280 // mojom::Connector implementation:
263 void Connect(const service_manager::Identity& in_target, 281 void Connect(const service_manager::Identity& in_target,
264 mojom::InterfaceProviderRequest remote_interfaces, 282 mojom::InterfaceProviderRequest remote_interfaces,
265 mojom::ClientProcessConnectionPtr client_process_connection, 283 mojom::ClientProcessConnectionPtr client_process_connection,
266 const ConnectCallback& callback) override { 284 const ConnectCallback& callback) override {
267 Identity target = in_target; 285 Identity target = in_target;
268 if (target.user_id() == mojom::kInheritUserID) 286 if (target.user_id() == mojom::kInheritUserID)
269 target.set_user_id(identity_.user_id()); 287 target.set_user_id(identity_.user_id());
270 288
271 if (!ValidateIdentity(target, callback)) 289 if (!ValidateIdentity(target, callback))
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 CHECK_NE(mojom::kInvalidInstanceID, id); 427 CHECK_NE(mojom::kInvalidInstanceID, id);
410 return id; 428 return id;
411 } 429 }
412 430
413 void PIDAvailable(base::ProcessId pid) { 431 void PIDAvailable(base::ProcessId pid) {
414 if (pid == base::kNullProcessId) { 432 if (pid == base::kNullProcessId) {
415 service_manager_->OnInstanceError(this); 433 service_manager_->OnInstanceError(this);
416 return; 434 return;
417 } 435 }
418 pid_ = pid; 436 pid_ = pid;
419 service_manager_->NotifyPIDAvailable(identity_, pid_);
420 } 437 }
421 438
422 void OnServiceLost( 439 void OnServiceLost(
423 base::WeakPtr<service_manager::ServiceManager> service_manager) { 440 base::WeakPtr<service_manager::ServiceManager> service_manager) {
424 service_.reset(); 441 service_.reset();
425 OnConnectionLost(service_manager); 442 OnConnectionLost(service_manager);
426 } 443 }
427 444
428 void OnConnectionLost( 445 void OnConnectionLost(
429 base::WeakPtr<service_manager::ServiceManager> service_manager) { 446 base::WeakPtr<service_manager::ServiceManager> service_manager) {
430 // Any time a Connector is lost or we lose the Service connection, it 447 // Any time a Connector is lost or we lose the Service connection, it
431 // may have been the last pipe using this Instance. If so, clean up. 448 // may have been the last pipe using this Instance. If so, clean up.
432 if (service_manager && !service_) { 449 if (service_manager && !service_) {
433 if (connectors_.empty()) 450 if (connectors_.empty())
434 service_manager->OnInstanceError(this); 451 service_manager->OnInstanceError(this);
435 else 452 else
436 service_manager->OnInstanceUnreachable(this); 453 service_manager->OnInstanceUnreachable(this);
437 } 454 }
438 } 455 }
439 456
440 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { 457 void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
458 state_ = State::STARTED;
441 if (connector_request.is_pending()) { 459 if (connector_request.is_pending()) {
442 connectors_.AddBinding(this, std::move(connector_request)); 460 connectors_.AddBinding(this, std::move(connector_request));
443 connectors_.set_connection_error_handler( 461 connectors_.set_connection_error_handler(
444 base::Bind(&Instance::OnConnectionLost, base::Unretained(this), 462 base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
445 service_manager_->GetWeakPtr())); 463 service_manager_->GetWeakPtr()));
446 } 464 }
465 service_manager_->NotifyServiceStarted(identity_, pid_);
447 } 466 }
448 467
449 // Callback when NativeRunner completes. 468 // Callback when NativeRunner completes.
450 void OnRunnerCompleted() { 469 void OnRunnerCompleted() {
451 if (!runner_.get()) 470 if (!runner_.get())
452 return; // We're in the destructor. 471 return; // We're in the destructor.
453 472
454 service_manager_->OnInstanceError(this); 473 service_manager_->OnInstanceError(this);
455 } 474 }
456 475
457 service_manager::ServiceManager* const service_manager_; 476 service_manager::ServiceManager* const service_manager_;
458 477
459 // An id that identifies this instance. Distinct from pid, as a single process 478 // An id that identifies this instance. Distinct from pid, as a single process
460 // may vend multiple application instances, and this object may exist before a 479 // may vend multiple application instances, and this object may exist before a
461 // process is launched. 480 // process is launched.
462 const uint32_t id_; 481 const uint32_t id_;
463 const Identity identity_; 482 Identity identity_;
464 const InterfaceProviderSpec connection_spec_; 483 const InterfaceProviderSpec connection_spec_;
465 const bool allow_any_application_; 484 const bool allow_any_application_;
466 std::unique_ptr<NativeRunner> runner_; 485 std::unique_ptr<NativeRunner> runner_;
467 mojom::ServicePtr service_; 486 mojom::ServicePtr service_;
468 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; 487 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
469 mojo::BindingSet<mojom::Connector> connectors_; 488 mojo::BindingSet<mojom::Connector> connectors_;
470 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; 489 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_;
471 base::ProcessId pid_ = base::kNullProcessId; 490 base::ProcessId pid_ = base::kNullProcessId;
472 Instance* parent_ = nullptr; 491 Instance* parent_ = nullptr;
473 InstanceMap children_; 492 InstanceMap children_;
493 State state_;
474 base::WeakPtrFactory<Instance> weak_factory_; 494 base::WeakPtrFactory<Instance> weak_factory_;
475 495
476 DISALLOW_COPY_AND_ASSIGN(Instance); 496 DISALLOW_COPY_AND_ASSIGN(Instance);
477 }; 497 };
478 498
479 // static 499 // static
480 ServiceManager::TestAPI::TestAPI(ServiceManager* service_manager) 500 ServiceManager::TestAPI::TestAPI(ServiceManager* service_manager)
481 : service_manager_(service_manager) {} 501 : service_manager_(service_manager) {}
482 ServiceManager::TestAPI::~TestAPI() {} 502 ServiceManager::TestAPI::~TestAPI() {}
483 503
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 for (auto entry : identity_to_instance_) { 705 for (auto entry : identity_to_instance_) {
686 if (entry.first.name() == identity.name() && 706 if (entry.first.name() == identity.name() &&
687 entry.first.instance() == identity.instance()) { 707 entry.first.instance() == identity.instance()) {
688 return entry.second; 708 return entry.second;
689 } 709 }
690 } 710 }
691 } 711 }
692 return nullptr; 712 return nullptr;
693 } 713 }
694 714
695 void ServiceManager::NotifyPIDAvailable(const Identity& identity, 715 void ServiceManager::NotifyServiceStarted(const Identity& identity,
696 base::ProcessId pid) { 716 base::ProcessId pid) {
697 listeners_.ForAllPtrs( 717 listeners_.ForAllPtrs(
698 [identity, pid](mojom::ServiceManagerListener* listener) { 718 [identity, pid](mojom::ServiceManagerListener* listener) {
699 listener->OnServiceStarted(identity, pid); 719 listener->OnServiceStarted(identity, pid);
700 }); 720 });
701 } 721 }
702 722
723 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) {
724 listeners_.ForAllPtrs(
725 [identity](mojom::ServiceManagerListener* listener) {
726 listener->OnServiceFailedToStart(identity);
727 });
728 }
729
703 bool ServiceManager::ConnectToExistingInstance( 730 bool ServiceManager::ConnectToExistingInstance(
704 std::unique_ptr<ConnectParams>* params) { 731 std::unique_ptr<ConnectParams>* params) {
705 Instance* instance = GetExistingInstance((*params)->target()); 732 Instance* instance = GetExistingInstance((*params)->target());
706 return instance && instance->ConnectToService(params); 733 return instance && instance->ConnectToService(params);
707 } 734 }
708 735
709 ServiceManager::Instance* ServiceManager::CreateInstance( 736 ServiceManager::Instance* ServiceManager::CreateInstance(
710 const Identity& source, 737 const Identity& source,
711 const Identity& target, 738 const Identity& target,
712 const InterfaceProviderSpec& connection_spec) { 739 const InterfaceProviderSpec& connection_spec) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 if (instance_name == GetNamePath(params->target().name()) && 821 if (instance_name == GetNamePath(params->target().name()) &&
795 result->qualifier != GetNamePath(result->resolved_name)) { 822 result->qualifier != GetNamePath(result->resolved_name)) {
796 instance_name = result->qualifier; 823 instance_name = result->qualifier;
797 } 824 }
798 // |result->connection_spec| can be null when there is no manifest, e.g. for 825 // |result->connection_spec| can be null when there is no manifest, e.g. for
799 // URL types not resolvable by the resolver. 826 // URL types not resolvable by the resolver.
800 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); 827 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec();
801 if (result->connection_spec.has_value()) 828 if (result->connection_spec.has_value())
802 connection_spec = result->connection_spec.value(); 829 connection_spec = result->connection_spec.value();
803 830
831 const Identity original_target(params->target());
804 const std::string user_id = 832 const std::string user_id =
805 HasCapability(connection_spec, kCapability_AllUsers) 833 HasCapability(connection_spec, kCapability_AllUsers)
806 ? base::GenerateGUID() : params->target().user_id(); 834 ? base::GenerateGUID() : params->target().user_id();
807 const Identity target(params->target().name(), user_id, instance_name); 835 const Identity target(params->target().name(), user_id, instance_name);
808 params->set_target(target); 836 params->set_target(target);
809 837
810 // It's possible that when this manifest request was issued, another one was 838 // It's possible that when this manifest request was issued, another one was
811 // already in-progress and completed by the time this one did, and so the 839 // already in-progress and completed by the time this one did, and so the
812 // requested application may already be running. 840 // requested application may already be running.
813 if (ConnectToExistingInstance(&params)) 841 if (ConnectToExistingInstance(&params))
(...skipping 30 matching lines...) Expand all
844 // Likewise if a ClientProcessConnection was given via Connect(), it 872 // Likewise if a ClientProcessConnection was given via Connect(), it
845 // provides the Service proxy to use. 873 // provides the Service proxy to use.
846 instance->StartWithClientProcessConnection( 874 instance->StartWithClientProcessConnection(
847 std::move(client_process_connection)); 875 std::move(client_process_connection));
848 } else { 876 } else {
849 // Otherwise we create a new Service pipe. 877 // Otherwise we create a new Service pipe.
850 mojom::ServiceRequest request = GetProxy(&service); 878 mojom::ServiceRequest request = GetProxy(&service);
851 CHECK(!result->package_path.empty() && result->connection_spec.has_value()); 879 CHECK(!result->package_path.empty() && result->connection_spec.has_value());
852 880
853 if (target.name() != result->resolved_name) { 881 if (target.name() != result->resolved_name) {
882 // When part of a packaged app, use the original user ID.
Ken Rockot(use gerrit already) 2016/10/21 19:52:33 nit: s/app/service/
Jay Civelli 2016/10/21 20:48:33 Done.
883 Identity packaged_app_target(target);
884 packaged_app_target.set_user_id(original_target.user_id());
885 instance->set_identity(packaged_app_target);
854 instance->StartWithService(std::move(service)); 886 instance->StartWithService(std::move(service));
855 Identity factory(result->resolved_name, target.user_id(), 887 Identity factory(result->resolved_name, original_target.user_id(),
856 instance_name); 888 instance_name);
857 CreateServiceWithFactory(factory, target.name(), std::move(request)); 889 CreateServiceWithFactory(factory, target.name(), std::move(request));
858 } else { 890 } else {
859 base::FilePath package_path; 891 base::FilePath package_path;
860 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( 892 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride(
861 target.name(), &package_path)) { 893 target.name(), &package_path)) {
862 package_path = result->package_path; 894 package_path = result->package_path;
863 } 895 }
864 896
865 Identity source_instance_identity; 897 Identity source_instance_identity;
(...skipping 16 matching lines...) Expand all
882 // Now that the instance has a Service, we can connect to it. 914 // Now that the instance has a Service, we can connect to it.
883 bool connected = instance->ConnectToService(&params); 915 bool connected = instance->ConnectToService(&params);
884 DCHECK(connected); 916 DCHECK(connected);
885 } 917 }
886 918
887 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 919 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
888 return weak_ptr_factory_.GetWeakPtr(); 920 return weak_ptr_factory_.GetWeakPtr();
889 } 921 }
890 922
891 } // namespace service_manager 923 } // namespace service_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698