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

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

Issue 2610173003: Add RegisterService, split out of Connect(). (Closed)
Patch Set: . Created 3 years, 11 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 state_ = State::STARTING; 158 state_ = State::STARTING;
159 service_ = std::move(service); 159 service_ = std::move(service);
160 service_.set_connection_error_handler( 160 service_.set_connection_error_handler(
161 base::Bind(&Instance::OnServiceLost, base::Unretained(this), 161 base::Bind(&Instance::OnServiceLost, base::Unretained(this),
162 service_manager_->GetWeakPtr())); 162 service_manager_->GetWeakPtr()));
163 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), 163 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_),
164 base::Bind(&Instance::OnStartComplete, 164 base::Bind(&Instance::OnStartComplete,
165 base::Unretained(this))); 165 base::Unretained(this)));
166 } 166 }
167 167
168 void StartWithClientProcessConnection(
169 mojom::ClientProcessConnectionPtr client_process_connection) {
170 mojom::ServicePtr service;
171 service.Bind(mojom::ServicePtrInfo(
172 std::move(client_process_connection->service), 0));
173 pid_receiver_binding_.Bind(
174 std::move(client_process_connection->pid_receiver_request));
175 StartWithService(std::move(service));
176 }
177
178 bool StartWithFilePath(const base::FilePath& path) { 168 bool StartWithFilePath(const base::FilePath& path) {
179 DCHECK(!service_); 169 DCHECK(!service_);
180 DCHECK(!path.empty()); 170 DCHECK(!path.empty());
181 runner_ = service_manager_->service_process_launcher_factory_->Create(path); 171 runner_ = service_manager_->service_process_launcher_factory_->Create(path);
182 if (!runner_) 172 if (!runner_)
183 return false; 173 return false;
184 bool start_sandboxed = false; 174 bool start_sandboxed = false;
185 mojom::ServicePtr service = runner_->Start( 175 mojom::ServicePtr service = runner_->Start(
186 identity_, start_sandboxed, 176 identity_, start_sandboxed,
187 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr())); 177 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()));
188 StartWithService(std::move(service)); 178 StartWithService(std::move(service));
189 return true; 179 return true;
190 } 180 }
191 181
182 void BindPIDReceiver(mojom::PIDReceiverRequest request) {
183 pid_receiver_binding_.Bind(std::move(request));
184 }
185
192 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { 186 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const {
193 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); 187 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New());
194 info->id = id_; 188 info->id = id_;
195 info->identity = identity_; 189 info->identity = identity_;
196 info->pid = pid_; 190 info->pid = pid_;
197 return info; 191 return info;
198 } 192 }
199 193
200 const InterfaceProviderSpec& GetConnectionSpec() const { 194 const InterfaceProviderSpec& GetConnectionSpec() const {
201 auto it = interface_provider_specs_.find( 195 auto it = interface_provider_specs_.find(
(...skipping 25 matching lines...) Expand all
227 221
228 // The service was started but the service manager hasn't received the 222 // The service was started but the service manager hasn't received the
229 // initial response from it yet. 223 // initial response from it yet.
230 STARTING, 224 STARTING,
231 225
232 // The service was started successfully. 226 // The service was started successfully.
233 STARTED 227 STARTED
234 }; 228 };
235 229
236 // mojom::Connector implementation: 230 // mojom::Connector implementation:
237 void Connect(const service_manager::Identity& in_target, 231 void Start(
232 const Identity& target,
233 mojo::ScopedMessagePipeHandle service_handle,
234 mojom::PIDReceiverRequest pid_receiver_request) override {
235 mojom::ServicePtr service;
236 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0));
237 ConnectImpl(
238 target,
239 mojom::InterfaceProviderRequest(),
240 std::move(service),
241 std::move(pid_receiver_request),
242 base::Bind(
243 &service_manager::ServiceManager::Instance::EmptyConnectCallback,
244 weak_factory_.GetWeakPtr()));
245 }
246
247 void Connect(const service_manager::Identity& target,
238 mojom::InterfaceProviderRequest remote_interfaces, 248 mojom::InterfaceProviderRequest remote_interfaces,
239 mojom::ClientProcessConnectionPtr client_process_connection,
240 const ConnectCallback& callback) override { 249 const ConnectCallback& callback) override {
250 ConnectImpl(target, std::move(remote_interfaces), mojom::ServicePtr(),
251 mojom::PIDReceiverRequest(), callback);
252 }
253
254 void ConnectImpl(const service_manager::Identity& in_target,
255 mojom::InterfaceProviderRequest remote_interfaces,
256 mojom::ServicePtr service,
257 mojom::PIDReceiverRequest pid_receiver_request,
258 const ConnectCallback& callback) {
241 Identity target = in_target; 259 Identity target = in_target;
242 if (target.user_id() == mojom::kInheritUserID) 260 if (target.user_id() == mojom::kInheritUserID)
243 target.set_user_id(identity_.user_id()); 261 target.set_user_id(identity_.user_id());
244 262
245 if (!ValidateIdentity(target, callback)) 263 if (!ValidateIdentity(target, callback))
246 return; 264 return;
247 if (!ValidateClientProcessConnection(&client_process_connection, target, 265 if (!ValidateClientProcessInfo(&service, &pid_receiver_request, target,
248 callback)) { 266 callback)) {
249 return; 267 return;
250 } 268 }
251 if (!ValidateConnectionSpec(target, callback)) 269 if (!ValidateConnectionSpec(target, callback))
252 return; 270 return;
253 271
254 std::unique_ptr<ConnectParams> params(new ConnectParams); 272 std::unique_ptr<ConnectParams> params(new ConnectParams);
255 params->set_source(identity_); 273 params->set_source(identity_);
256 params->set_target(target); 274 params->set_target(target);
257 params->set_remote_interfaces(std::move(remote_interfaces)); 275 params->set_remote_interfaces(std::move(remote_interfaces));
258 params->set_client_process_connection(std::move(client_process_connection)); 276 params->set_client_process_info(std::move(service),
277 std::move(pid_receiver_request));
259 params->set_connect_callback(callback); 278 params->set_connect_callback(callback);
260 service_manager_->Connect( 279 service_manager_->Connect(
261 std::move(params), nullptr, weak_factory_.GetWeakPtr()); 280 std::move(params), nullptr, weak_factory_.GetWeakPtr());
262 } 281 }
263 282
264 void Clone(mojom::ConnectorRequest request) override { 283 void Clone(mojom::ConnectorRequest request) override {
265 connectors_.AddBinding(this, std::move(request)); 284 connectors_.AddBinding(this, std::move(request));
266 } 285 }
267 286
268 // mojom::PIDReceiver: 287 // mojom::PIDReceiver:
(...skipping 24 matching lines...) Expand all
293 } 312 }
294 if (!base::IsValidGUID(identity.user_id())) { 313 if (!base::IsValidGUID(identity.user_id())) {
295 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); 314 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id();
296 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, 315 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
297 mojom::kInheritUserID); 316 mojom::kInheritUserID);
298 return false; 317 return false;
299 } 318 }
300 return true; 319 return true;
301 } 320 }
302 321
303 bool ValidateClientProcessConnection( 322 bool ValidateClientProcessInfo(
304 mojom::ClientProcessConnectionPtr* client_process_connection, 323 mojom::ServicePtr* service,
324 mojom::PIDReceiverRequest* pid_receiver_request,
305 const Identity& target, 325 const Identity& target,
306 const ConnectCallback& callback) { 326 const ConnectCallback& callback) {
307 if (!client_process_connection->is_null()) { 327 if (service->is_bound() || pid_receiver_request->is_pending()) {
308 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { 328 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) {
309 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " 329 LOG(ERROR) << "Instance: " << identity_.name() << " attempting "
310 << "to register an instance for a process it created for " 330 << "to register an instance for a process it created for "
311 << "target: " << target.name() << " without the " 331 << "target: " << target.name() << " without the "
312 << "service_manager{client_process} capability " 332 << "service_manager{client_process} capability "
313 << "class."; 333 << "class.";
314 callback.Run(mojom::ConnectResult::ACCESS_DENIED, 334 callback.Run(mojom::ConnectResult::ACCESS_DENIED,
315 mojom::kInheritUserID); 335 mojom::kInheritUserID);
316 return false; 336 return false;
317 } 337 }
318 338
319 if (!(*client_process_connection)->service.is_valid() || 339 if (!service->is_bound() || !pid_receiver_request->is_pending()) {
320 !(*client_process_connection)->pid_receiver_request.is_valid()) {
321 LOG(ERROR) << "Must supply both service AND " 340 LOG(ERROR) << "Must supply both service AND "
322 << "pid_receiver_request when sending " 341 << "pid_receiver_request when sending client process info";
323 << "client_process_connection.";
324 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, 342 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
325 mojom::kInheritUserID); 343 mojom::kInheritUserID);
326 return false; 344 return false;
327 } 345 }
328 if (service_manager_->GetExistingInstance(target)) { 346 if (service_manager_->GetExistingInstance(target)) {
329 LOG(ERROR) << "Cannot client process matching existing identity:" 347 LOG(ERROR) << "Cannot client process matching existing identity:"
330 << "Name: " << target.name() << " User: " 348 << "Name: " << target.name() << " User: "
331 << target.user_id() << " Instance: " << target.instance(); 349 << target.user_id() << " Instance: " << target.instance();
332 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, 350 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT,
333 mojom::kInheritUserID); 351 mojom::kInheritUserID);
334 return false; 352 return false;
335 } 353 }
336 } 354 }
337 return true; 355 return true;
338 } 356 }
339 357
340 bool ValidateConnectionSpec(const Identity& target, 358 bool ValidateConnectionSpec(const Identity& target,
341 const ConnectCallback& callback) { 359 const ConnectCallback& callback) {
342 InterfaceProviderSpec connection_spec = GetConnectionSpec(); 360 InterfaceProviderSpec connection_spec = GetConnectionSpec();
343 // TODO(beng): Need to do the following additional policy validation of 361 // TODO(beng): Need to do the following additional policy validation of
344 // whether this instance is allowed to connect using: 362 // whether this instance is allowed to connect using:
345 // - a non-null client_process_connection. 363 // - non-null client process info.
346 if (target.user_id() != identity_.user_id() && 364 if (target.user_id() != identity_.user_id() &&
347 target.user_id() != mojom::kRootUserID && 365 target.user_id() != mojom::kRootUserID &&
348 !HasCapability(connection_spec, kCapability_UserID)) { 366 !HasCapability(connection_spec, kCapability_UserID)) {
349 LOG(ERROR) << "Instance: " << identity_.name() 367 LOG(ERROR) << "Instance: " << identity_.name()
350 << " running as: " << identity_.user_id() 368 << " running as: " << identity_.user_id()
351 << " attempting to connect to: " << target.name() 369 << " attempting to connect to: " << target.name()
352 << " as: " << target.user_id() << " without " 370 << " as: " << target.user_id() << " without "
353 << " the service:service_manager{user_id} capability."; 371 << " the service:service_manager{user_id} capability.";
354 callback.Run(mojom::ConnectResult::ACCESS_DENIED, 372 callback.Run(mojom::ConnectResult::ACCESS_DENIED,
355 mojom::kInheritUserID); 373 mojom::kInheritUserID);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 service_manager_->NotifyServiceStarted(identity_, pid_); 443 service_manager_->NotifyServiceStarted(identity_, pid_);
426 } 444 }
427 445
428 // mojom::ServiceControl: 446 // mojom::ServiceControl:
429 void RequestQuit() override { 447 void RequestQuit() override {
430 // If quit is requested, oblige when there are no pending OnConnects. 448 // If quit is requested, oblige when there are no pending OnConnects.
431 if (!pending_service_connections_) 449 if (!pending_service_connections_)
432 OnServiceLost(service_manager_->GetWeakPtr()); 450 OnServiceLost(service_manager_->GetWeakPtr());
433 } 451 }
434 452
453 void EmptyConnectCallback(mojom::ConnectResult result,
454 const std::string& user_id) {}
455
435 service_manager::ServiceManager* const service_manager_; 456 service_manager::ServiceManager* const service_manager_;
436 457
437 // An id that identifies this instance. Distinct from pid, as a single process 458 // An id that identifies this instance. Distinct from pid, as a single process
438 // may vend multiple application instances, and this object may exist before a 459 // may vend multiple application instances, and this object may exist before a
439 // process is launched. 460 // process is launched.
440 const uint32_t id_; 461 const uint32_t id_;
441 Identity identity_; 462 Identity identity_;
442 const InterfaceProviderSpecMap interface_provider_specs_; 463 const InterfaceProviderSpecMap interface_provider_specs_;
443 const InterfaceProviderSpec empty_spec_; 464 const InterfaceProviderSpec empty_spec_;
444 const bool allow_any_application_; 465 const bool allow_any_application_;
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 // the lifetime of the service that started them, instead they are owned by 886 // the lifetime of the service that started them, instead they are owned by
866 // the Service Manager. 887 // the Service Manager.
867 Identity source_identity_for_creation; 888 Identity source_identity_for_creation;
868 if (HasCapability(connection_spec, kCapability_AllUsers)) { 889 if (HasCapability(connection_spec, kCapability_AllUsers)) {
869 singletons_.insert(target.name()); 890 singletons_.insert(target.name());
870 source_identity_for_creation = CreateServiceManagerIdentity(); 891 source_identity_for_creation = CreateServiceManagerIdentity();
871 } else { 892 } else {
872 source_identity_for_creation = params->source(); 893 source_identity_for_creation = params->source();
873 } 894 }
874 895
875 mojom::ClientProcessConnectionPtr client_process_connection =
876 params->TakeClientProcessConnection();
877 Instance* instance = CreateInstance(source_identity_for_creation, 896 Instance* instance = CreateInstance(source_identity_for_creation,
878 target, result->interface_provider_specs); 897 target, result->interface_provider_specs);
879 898
880 // Below are various paths through which a new Instance can be bound to a 899 // Below are various paths through which a new Instance can be bound to a
881 // Service proxy. 900 // Service proxy.
882 if (service.is_bound()) { 901 if (service.is_bound()) {
883 // If a ServicePtr was provided, there's no more work to do: someone 902 // If a ServicePtr was provided, there's no more work to do: someone
884 // is already holding a corresponding ServiceRequest. 903 // is already holding a corresponding ServiceRequest.
885 instance->StartWithService(std::move(service)); 904 instance->StartWithService(std::move(service));
886 } else if (!client_process_connection.is_null()) { 905 } else if (params->HasClientProcessInfo()) {
887 // Likewise if a ClientProcessConnection was given via Connect(), it 906 // This branch should be reachable only via a call to RegisterService(). We
888 // provides the Service proxy to use. 907 // start the instance but return early before we connect to it. Clients will
889 instance->StartWithClientProcessConnection( 908 // call Connect() with the target identity subsequently.
890 std::move(client_process_connection)); 909 instance->BindPIDReceiver(params->TakePIDReceiverRequest());
910 instance->StartWithService(params->TakeService());
911 return;
891 } else { 912 } else {
892 // Otherwise we create a new Service pipe. 913 // Otherwise we create a new Service pipe.
893 mojom::ServiceRequest request(&service); 914 mojom::ServiceRequest request(&service);
894 CHECK(!result->package_path.empty()); 915 CHECK(!result->package_path.empty());
895 916
896 // The catalog was unable to read a manifest for this service. We can't do 917 // The catalog was unable to read a manifest for this service. We can't do
897 // anything more. 918 // anything more.
898 // TODO(beng): There may be some cases where it's valid to have an empty 919 // TODO(beng): There may be some cases where it's valid to have an empty
899 // spec, so we should probably include a return value in |result|. 920 // spec, so we should probably include a return value in |result|.
900 if (result->interface_provider_specs.empty()) { 921 if (result->interface_provider_specs.empty()) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 // Now that the instance has a Service, we can connect to it. 972 // Now that the instance has a Service, we can connect to it.
952 bool connected = instance->ConnectToService(&params); 973 bool connected = instance->ConnectToService(&params);
953 DCHECK(connected); 974 DCHECK(connected);
954 } 975 }
955 976
956 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 977 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
957 return weak_ptr_factory_.GetWeakPtr(); 978 return weak_ptr_factory_.GetWeakPtr();
958 } 979 }
959 980
960 } // namespace service_manager 981 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/public/interfaces/connector.mojom ('k') | services/service_manager/tests/connect/connect_test_app.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698