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

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

Issue 2440903002: Make "all user" services work when packaged. (Closed)
Patch Set: Addressed latest comments and synced. Created 4 years, 1 month 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 21 matching lines...) Expand all
32 namespace service_manager { 32 namespace service_manager {
33 33
34 namespace { 34 namespace {
35 35
36 const char kCatalogName[] = "service:catalog"; 36 const char kCatalogName[] = "service:catalog";
37 const char kServiceManagerName[] = "service:service_manager"; 37 const char kServiceManagerName[] = "service:service_manager";
38 const char kCapability_UserID[] = "service_manager:user_id"; 38 const char kCapability_UserID[] = "service_manager:user_id";
39 const char kCapability_ClientProcess[] = "service_manager:client_process"; 39 const char kCapability_ClientProcess[] = "service_manager:client_process";
40 const char kCapability_InstanceName[] = "service_manager:instance_name"; 40 const char kCapability_InstanceName[] = "service_manager:instance_name";
41 const char kCapability_AllUsers[] = "service_manager:all_users"; 41 const char kCapability_AllUsers[] = "service_manager:all_users";
42 const char kCapability_InstancePerChild[] =
43 "service_manager:instance_per_child";
42 const char kCapability_ServiceManager[] = "service_manager:service_manager"; 44 const char kCapability_ServiceManager[] = "service_manager:service_manager";
43 45
44 } // namespace 46 } // namespace
45 47
46 Identity CreateServiceManagerIdentity() { 48 Identity CreateServiceManagerIdentity() {
47 return Identity(kServiceManagerName, mojom::kRootUserID); 49 return Identity(kServiceManagerName, mojom::kRootUserID);
48 } 50 }
49 51
50 Identity CreateCatalogIdentity() { 52 Identity CreateCatalogIdentity() {
51 return Identity(kCatalogName, mojom::kRootUserID); 53 return Identity(kCatalogName, mojom::kRootUserID);
(...skipping 26 matching lines...) Expand all
78 public: 80 public:
79 Instance(service_manager::ServiceManager* service_manager, 81 Instance(service_manager::ServiceManager* service_manager,
80 const Identity& identity, 82 const Identity& identity,
81 const InterfaceProviderSpecMap& interface_provider_specs) 83 const InterfaceProviderSpecMap& interface_provider_specs)
82 : service_manager_(service_manager), 84 : service_manager_(service_manager),
83 id_(GenerateUniqueID()), 85 id_(GenerateUniqueID()),
84 identity_(identity), 86 identity_(identity),
85 interface_provider_specs_(interface_provider_specs), 87 interface_provider_specs_(interface_provider_specs),
86 allow_any_application_(GetConnectionSpec().requires.count("*") == 1), 88 allow_any_application_(GetConnectionSpec().requires.count("*") == 1),
87 pid_receiver_binding_(this), 89 pid_receiver_binding_(this),
90 state_(State::IDLE),
88 weak_factory_(this) { 91 weak_factory_(this) {
89 if (identity_.name() == kServiceManagerName || 92 if (identity_.name() == kServiceManagerName ||
90 identity_.name() == kCatalogName) { 93 identity_.name() == kCatalogName) {
91 pid_ = base::Process::Current().Pid(); 94 pid_ = base::Process::Current().Pid();
92 } 95 }
93 DCHECK_NE(mojom::kInvalidInstanceID, id_); 96 DCHECK_NE(mojom::kInvalidInstanceID, id_);
94 } 97 }
95 98
96 ~Instance() override { 99 ~Instance() override {
97 // Shutdown all bindings before we close the runner. This way the process 100 // Shutdown all bindings before we close the runner. This way the process
98 // should see the pipes closed and exit, as well as waking up any potential 101 // should see the pipes closed and exit, as well as waking up any potential
99 // sync/WaitForIncomingResponse(). 102 // sync/WaitForIncomingResponse().
100 service_.reset(); 103 service_.reset();
101 if (pid_receiver_binding_.is_bound()) 104 if (pid_receiver_binding_.is_bound())
102 pid_receiver_binding_.Close(); 105 pid_receiver_binding_.Close();
103 connectors_.CloseAllBindings(); 106 connectors_.CloseAllBindings();
104 service_manager_bindings_.CloseAllBindings(); 107 service_manager_bindings_.CloseAllBindings();
105 108
106 // Notify the ServiceManager that this Instance is really going away. 109 if (state_ == State::STARTING) {
107 service_manager_->OnInstanceStopped(identity_); 110 service_manager_->NotifyServiceFailedToStart(identity_);
111 } else {
112 // Notify the ServiceManager that this Instance is really going away.
113 service_manager_->OnInstanceStopped(identity_);
114 }
108 115
109 // Release |runner_| so that if we are called back to OnRunnerCompleted() 116 // Release |runner_| so that if we are called back to OnRunnerCompleted()
110 // we know we're in the destructor. 117 // we know we're in the destructor.
111 std::unique_ptr<NativeRunner> runner = std::move(runner_); 118 std::unique_ptr<NativeRunner> runner = std::move(runner_);
112 runner.reset(); 119 runner.reset();
113 } 120 }
114 121
115 Instance* parent() { return parent_; } 122 Instance* parent() const { return parent_; }
116 123
117 void AddChild(std::unique_ptr<Instance> child) { 124 void AddChild(std::unique_ptr<Instance> child) {
118 child->parent_ = this; 125 child->parent_ = this;
119 children_.insert(std::make_pair(child.get(), std::move(child))); 126 children_.insert(std::make_pair(child.get(), std::move(child)));
120 } 127 }
121 128
122 void RemoveChild(Instance* child) { 129 void RemoveChild(Instance* child) {
123 auto it = children_.find(child); 130 auto it = children_.find(child);
124 DCHECK(it != children_.end()); 131 DCHECK(it != children_.end());
125 132
(...skipping 15 matching lines...) Expand all
141 Instance* source = service_manager_->GetExistingInstance(params->source()); 148 Instance* source = service_manager_->GetExistingInstance(params->source());
142 if (source) 149 if (source)
143 specs = source->interface_provider_specs_; 150 specs = source->interface_provider_specs_;
144 service_->OnConnect(ServiceInfo(params->source(), specs), 151 service_->OnConnect(ServiceInfo(params->source(), specs),
145 params->TakeRemoteInterfaces()); 152 params->TakeRemoteInterfaces());
146 return true; 153 return true;
147 } 154 }
148 155
149 void StartWithService(mojom::ServicePtr service) { 156 void StartWithService(mojom::ServicePtr service) {
150 CHECK(!service_); 157 CHECK(!service_);
158 state_ = State::STARTING;
151 service_ = std::move(service); 159 service_ = std::move(service);
152 service_.set_connection_error_handler( 160 service_.set_connection_error_handler(
153 base::Bind(&Instance::OnServiceLost, base::Unretained(this), 161 base::Bind(&Instance::OnServiceLost, base::Unretained(this),
154 service_manager_->GetWeakPtr())); 162 service_manager_->GetWeakPtr()));
155 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), 163 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_),
156 base::Bind(&Instance::OnInitializeResponse, 164 base::Bind(&Instance::OnInitializeResponse,
157 base::Unretained(this))); 165 base::Unretained(this)));
158 } 166 }
159 167
160 void StartWithClientProcessConnection( 168 void StartWithClientProcessConnection(
(...skipping 24 matching lines...) Expand all
185 info->pid = pid_; 193 info->pid = pid_;
186 return info; 194 return info;
187 } 195 }
188 196
189 const InterfaceProviderSpec& GetConnectionSpec() const { 197 const InterfaceProviderSpec& GetConnectionSpec() const {
190 auto it = interface_provider_specs_.find( 198 auto it = interface_provider_specs_.find(
191 mojom::kServiceManager_ConnectorSpec); 199 mojom::kServiceManager_ConnectorSpec);
192 return it != interface_provider_specs_.end() ? it->second : empty_spec_; 200 return it != interface_provider_specs_.end() ? it->second : empty_spec_;
193 } 201 }
194 const Identity& identity() const { return identity_; } 202 const Identity& identity() const { return identity_; }
203 void set_identity(const Identity& identity) { identity_ = identity; }
195 uint32_t id() const { return id_; } 204 uint32_t id() const { return id_; }
196 205
197 // Service: 206 // Service:
198 bool OnConnect(const ServiceInfo& remote_info, 207 bool OnConnect(const ServiceInfo& remote_info,
199 InterfaceRegistry* registry) override { 208 InterfaceRegistry* registry) override {
200 Instance* source = 209 Instance* source =
201 service_manager_->GetExistingInstance(remote_info.identity); 210 service_manager_->GetExistingInstance(remote_info.identity);
202 DCHECK(source); 211 DCHECK(source);
203 if (HasCapability(source->GetConnectionSpec(), 212 if (HasCapability(source->GetConnectionSpec(),
204 kCapability_ServiceManager)) { 213 kCapability_ServiceManager)) {
205 registry->AddInterface<mojom::ServiceManager>(this); 214 registry->AddInterface<mojom::ServiceManager>(this);
206 return true; 215 return true;
207 } 216 }
208 return false; 217 return false;
209 } 218 }
210 219
211 private: 220 private:
221 enum class State {
222 // The service was not started yet.
223 IDLE,
224
225 // The service was started but the service manager hasn't received the
226 // initial response from it yet.
227 STARTING,
228
229 // The service was started successfully.
230 STARTED
231 };
232
212 // mojom::Connector implementation: 233 // mojom::Connector implementation:
213 void Connect(const service_manager::Identity& in_target, 234 void Connect(const service_manager::Identity& in_target,
214 mojom::InterfaceProviderRequest remote_interfaces, 235 mojom::InterfaceProviderRequest remote_interfaces,
215 mojom::ClientProcessConnectionPtr client_process_connection, 236 mojom::ClientProcessConnectionPtr client_process_connection,
216 const ConnectCallback& callback) override { 237 const ConnectCallback& callback) override {
217 Identity target = in_target; 238 Identity target = in_target;
218 if (target.user_id() == mojom::kInheritUserID) 239 if (target.user_id() == mojom::kInheritUserID)
219 target.set_user_id(identity_.user_id()); 240 target.set_user_id(identity_.user_id());
220 241
221 if (!ValidateIdentity(target, callback)) 242 if (!ValidateIdentity(target, callback))
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 CHECK_NE(mojom::kInvalidInstanceID, id); 381 CHECK_NE(mojom::kInvalidInstanceID, id);
361 return id; 382 return id;
362 } 383 }
363 384
364 void PIDAvailable(base::ProcessId pid) { 385 void PIDAvailable(base::ProcessId pid) {
365 if (pid == base::kNullProcessId) { 386 if (pid == base::kNullProcessId) {
366 service_manager_->OnInstanceError(this); 387 service_manager_->OnInstanceError(this);
367 return; 388 return;
368 } 389 }
369 pid_ = pid; 390 pid_ = pid;
370 service_manager_->NotifyPIDAvailable(identity_, pid_);
371 } 391 }
372 392
373 void OnServiceLost( 393 void OnServiceLost(
374 base::WeakPtr<service_manager::ServiceManager> service_manager) { 394 base::WeakPtr<service_manager::ServiceManager> service_manager) {
375 service_.reset(); 395 service_.reset();
376 OnConnectionLost(service_manager); 396 OnConnectionLost(service_manager);
377 } 397 }
378 398
379 void OnConnectionLost( 399 void OnConnectionLost(
380 base::WeakPtr<service_manager::ServiceManager> service_manager) { 400 base::WeakPtr<service_manager::ServiceManager> service_manager) {
381 // Any time a Connector is lost or we lose the Service connection, it 401 // Any time a Connector is lost or we lose the Service connection, it
382 // may have been the last pipe using this Instance. If so, clean up. 402 // may have been the last pipe using this Instance. If so, clean up.
383 if (service_manager && !service_) { 403 if (service_manager && !service_) {
384 if (connectors_.empty()) 404 if (connectors_.empty())
385 service_manager->OnInstanceError(this); 405 service_manager->OnInstanceError(this);
386 else 406 else
387 service_manager->OnInstanceUnreachable(this); 407 service_manager->OnInstanceUnreachable(this);
388 } 408 }
389 } 409 }
390 410
391 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { 411 void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
412 state_ = State::STARTED;
392 if (connector_request.is_pending()) { 413 if (connector_request.is_pending()) {
393 connectors_.AddBinding(this, std::move(connector_request)); 414 connectors_.AddBinding(this, std::move(connector_request));
394 connectors_.set_connection_error_handler( 415 connectors_.set_connection_error_handler(
395 base::Bind(&Instance::OnConnectionLost, base::Unretained(this), 416 base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
396 service_manager_->GetWeakPtr())); 417 service_manager_->GetWeakPtr()));
397 } 418 }
419 service_manager_->NotifyServiceStarted(identity_, pid_);
398 } 420 }
399 421
400 // Callback when NativeRunner completes. 422 // Callback when NativeRunner completes.
401 void OnRunnerCompleted() { 423 void OnRunnerCompleted() {
402 if (!runner_.get()) 424 if (!runner_.get())
403 return; // We're in the destructor. 425 return; // We're in the destructor.
404 426
405 service_manager_->OnInstanceError(this); 427 service_manager_->OnInstanceError(this);
406 } 428 }
407 429
408 service_manager::ServiceManager* const service_manager_; 430 service_manager::ServiceManager* const service_manager_;
409 431
410 // An id that identifies this instance. Distinct from pid, as a single process 432 // An id that identifies this instance. Distinct from pid, as a single process
411 // may vend multiple application instances, and this object may exist before a 433 // may vend multiple application instances, and this object may exist before a
412 // process is launched. 434 // process is launched.
413 const uint32_t id_; 435 const uint32_t id_;
414 const Identity identity_; 436 Identity identity_;
415 const InterfaceProviderSpecMap interface_provider_specs_; 437 const InterfaceProviderSpecMap interface_provider_specs_;
416 const InterfaceProviderSpec empty_spec_; 438 const InterfaceProviderSpec empty_spec_;
417 const bool allow_any_application_; 439 const bool allow_any_application_;
418 std::unique_ptr<NativeRunner> runner_; 440 std::unique_ptr<NativeRunner> runner_;
419 mojom::ServicePtr service_; 441 mojom::ServicePtr service_;
420 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; 442 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
421 mojo::BindingSet<mojom::Connector> connectors_; 443 mojo::BindingSet<mojom::Connector> connectors_;
422 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; 444 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_;
423 base::ProcessId pid_ = base::kNullProcessId; 445 base::ProcessId pid_ = base::kNullProcessId;
424 Instance* parent_ = nullptr; 446 Instance* parent_ = nullptr;
425 InstanceMap children_; 447 InstanceMap children_;
448 State state_;
426 base::WeakPtrFactory<Instance> weak_factory_; 449 base::WeakPtrFactory<Instance> weak_factory_;
427 450
428 DISALLOW_COPY_AND_ASSIGN(Instance); 451 DISALLOW_COPY_AND_ASSIGN(Instance);
429 }; 452 };
430 453
431 // static 454 // static
432 ServiceManager::TestAPI::TestAPI(ServiceManager* service_manager) 455 ServiceManager::TestAPI::TestAPI(ServiceManager* service_manager)
433 : service_manager_(service_manager) {} 456 : service_manager_(service_manager) {}
434 ServiceManager::TestAPI::~TestAPI() {} 457 ServiceManager::TestAPI::~TestAPI() {}
435 458
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 for (auto entry : identity_to_instance_) { 665 for (auto entry : identity_to_instance_) {
643 if (entry.first.name() == identity.name() && 666 if (entry.first.name() == identity.name() &&
644 entry.first.instance() == identity.instance()) { 667 entry.first.instance() == identity.instance()) {
645 return entry.second; 668 return entry.second;
646 } 669 }
647 } 670 }
648 } 671 }
649 return nullptr; 672 return nullptr;
650 } 673 }
651 674
652 void ServiceManager::NotifyPIDAvailable(const Identity& identity, 675 void ServiceManager::NotifyServiceStarted(const Identity& identity,
653 base::ProcessId pid) { 676 base::ProcessId pid) {
654 listeners_.ForAllPtrs( 677 listeners_.ForAllPtrs(
655 [identity, pid](mojom::ServiceManagerListener* listener) { 678 [identity, pid](mojom::ServiceManagerListener* listener) {
656 listener->OnServiceStarted(identity, pid); 679 listener->OnServiceStarted(identity, pid);
657 }); 680 });
658 } 681 }
659 682
683 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) {
684 listeners_.ForAllPtrs(
685 [identity](mojom::ServiceManagerListener* listener) {
686 listener->OnServiceFailedToStart(identity);
687 });
688 }
689
660 bool ServiceManager::ConnectToExistingInstance( 690 bool ServiceManager::ConnectToExistingInstance(
661 std::unique_ptr<ConnectParams>* params) { 691 std::unique_ptr<ConnectParams>* params) {
662 Instance* instance = GetExistingInstance((*params)->target()); 692 Instance* instance = GetExistingInstance((*params)->target());
663 return instance && instance->ConnectToService(params); 693 return instance && instance->ConnectToService(params);
664 } 694 }
665 695
666 ServiceManager::Instance* ServiceManager::CreateInstance( 696 ServiceManager::Instance* ServiceManager::CreateInstance(
667 const Identity& source, 697 const Identity& source,
668 const Identity& target, 698 const Identity& target,
669 const InterfaceProviderSpecMap& specs) { 699 const InterfaceProviderSpecMap& specs) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 instance_name = result->qualifier; 782 instance_name = result->qualifier;
753 } 783 }
754 // |result->interface_provider_specs| can be empty when there is no manifest, 784 // |result->interface_provider_specs| can be empty when there is no manifest,
755 // e.g. for URL types not resolvable by the resolver. 785 // e.g. for URL types not resolvable by the resolver.
756 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); 786 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec();
757 auto it = result->interface_provider_specs.find( 787 auto it = result->interface_provider_specs.find(
758 mojom::kServiceManager_ConnectorSpec); 788 mojom::kServiceManager_ConnectorSpec);
759 if (it != result->interface_provider_specs.end()) 789 if (it != result->interface_provider_specs.end())
760 connection_spec = it->second; 790 connection_spec = it->second;
761 791
792 const Identity original_target(params->target());
762 const std::string user_id = 793 const std::string user_id =
763 HasCapability(connection_spec, kCapability_AllUsers) 794 HasCapability(connection_spec, kCapability_AllUsers)
764 ? base::GenerateGUID() : params->target().user_id(); 795 ? base::GenerateGUID() : params->target().user_id();
765 const Identity target(params->target().name(), user_id, instance_name); 796 const Identity target(params->target().name(), user_id, instance_name);
766 params->set_target(target); 797 params->set_target(target);
767 798
768 // It's possible that when this manifest request was issued, another one was 799 // It's possible that when this manifest request was issued, another one was
769 // already in-progress and completed by the time this one did, and so the 800 // already in-progress and completed by the time this one did, and so the
770 // requested application may already be running. 801 // requested application may already be running.
771 if (ConnectToExistingInstance(&params)) 802 if (ConnectToExistingInstance(&params))
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 // anything more. 843 // anything more.
813 // TODO(beng): There may be some cases where it's valid to have an empty 844 // TODO(beng): There may be some cases where it's valid to have an empty
814 // spec, so we should probably include a return value in |result|. 845 // spec, so we should probably include a return value in |result|.
815 if (result->interface_provider_specs.empty()) { 846 if (result->interface_provider_specs.empty()) {
816 if (!params->connect_callback().is_null()) 847 if (!params->connect_callback().is_null())
817 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); 848 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, "");
818 return; 849 return;
819 } 850 }
820 851
821 if (target.name() != result->resolved_name) { 852 if (target.name() != result->resolved_name) {
853 // This service is part of a package.
854 std::string target_user_id = target.user_id();
855 std::string factory_instance_name = instance_name;
856 bool instance_per_child = result->package_spec.has_value() &&
857 HasCapability(result->package_spec.value(),
858 kCapability_InstancePerChild);
859 if (instance_per_child) {
860 // If configured to start a new instance, create a random instance name
861 // for the factory so that we don't reuse an existing process.
862 factory_instance_name = base::GenerateGUID();
863 } else {
864 // Use the original user ID so the existing embedder factory can
865 // be found and used to create the new service.
866 target_user_id = original_target.user_id();
867 Identity packaged_service_target(target);
868 packaged_service_target.set_user_id(original_target.user_id());
869 instance->set_identity(packaged_service_target);
870 }
822 instance->StartWithService(std::move(service)); 871 instance->StartWithService(std::move(service));
823 Identity factory(result->resolved_name, target.user_id(), 872
824 instance_name); 873 Identity factory(result->resolved_name, target_user_id,
874 factory_instance_name);
825 CreateServiceWithFactory(factory, target.name(), std::move(request)); 875 CreateServiceWithFactory(factory, target.name(), std::move(request));
826 } else { 876 } else {
827 base::FilePath package_path; 877 base::FilePath package_path;
828 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( 878 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride(
829 target.name(), &package_path)) { 879 target.name(), &package_path)) {
830 package_path = result->package_path; 880 package_path = result->package_path;
831 } 881 }
832 882
833 Identity source_instance_identity; 883 Identity source_instance_identity;
834 base::debug::Alias(&has_source_instance); 884 base::debug::Alias(&has_source_instance);
(...skipping 15 matching lines...) Expand all
850 // Now that the instance has a Service, we can connect to it. 900 // Now that the instance has a Service, we can connect to it.
851 bool connected = instance->ConnectToService(&params); 901 bool connected = instance->ConnectToService(&params);
852 DCHECK(connected); 902 DCHECK(connected);
853 } 903 }
854 904
855 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 905 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
856 return weak_ptr_factory_.GetWeakPtr(); 906 return weak_ptr_factory_.GetWeakPtr();
857 } 907 }
858 908
859 } // namespace service_manager 909 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/service_manager.h ('k') | services/service_manager/standalone/context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698