OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "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 29 matching lines...) Expand all Loading... |
40 namespace { | 40 namespace { |
41 | 41 |
42 const char kCapability_UserID[] = "service_manager:user_id"; | 42 const char kCapability_UserID[] = "service_manager:user_id"; |
43 const char kCapability_ClientProcess[] = "service_manager:client_process"; | 43 const char kCapability_ClientProcess[] = "service_manager:client_process"; |
44 const char kCapability_InstanceName[] = "service_manager:instance_name"; | 44 const char kCapability_InstanceName[] = "service_manager:instance_name"; |
45 const char kCapability_AllUsers[] = "service_manager:all_users"; | 45 const char kCapability_AllUsers[] = "service_manager:all_users"; |
46 const char kCapability_InstancePerChild[] = | 46 const char kCapability_InstancePerChild[] = |
47 "service_manager:instance_per_child"; | 47 "service_manager:instance_per_child"; |
48 const char kCapability_ServiceManager[] = "service_manager:service_manager"; | 48 const char kCapability_ServiceManager[] = "service_manager:service_manager"; |
49 | 49 |
| 50 bool Succeeded(mojom::ConnectResult result) { |
| 51 return result == mojom::ConnectResult::SUCCEEDED; |
| 52 } |
| 53 |
| 54 bool RunConnectCallback(ConnectParams* params, |
| 55 mojom::ConnectResult result, |
| 56 const std::string& user_id) { |
| 57 if (!params->connect_callback().is_null()) { |
| 58 params->connect_callback().Run(result, user_id); |
| 59 return true; |
| 60 } |
| 61 return false; |
| 62 } |
| 63 |
| 64 void RunBindInterfaceCallback(ConnectParams* params, |
| 65 mojom::ConnectResult result, |
| 66 const std::string& user_id) { |
| 67 if (!params->bind_interface_callback().is_null()) |
| 68 params->bind_interface_callback().Run(result, user_id); |
| 69 } |
| 70 |
| 71 void RunCallback(ConnectParams* params, |
| 72 mojom::ConnectResult result, |
| 73 const std::string& user_id) { |
| 74 if (!RunConnectCallback(params, result, user_id)) |
| 75 RunBindInterfaceCallback(params, result, user_id); |
| 76 } |
| 77 |
50 } // namespace | 78 } // namespace |
51 | 79 |
52 Identity CreateServiceManagerIdentity() { | 80 Identity CreateServiceManagerIdentity() { |
53 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); | 81 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); |
54 } | 82 } |
55 | 83 |
56 Identity CreateCatalogIdentity() { | 84 Identity CreateCatalogIdentity() { |
57 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); | 85 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); |
58 } | 86 } |
59 | 87 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } else { | 146 } else { |
119 // Notify the ServiceManager that this Instance is really going away. | 147 // Notify the ServiceManager that this Instance is really going away. |
120 service_manager_->OnInstanceStopped(identity_); | 148 service_manager_->OnInstanceStopped(identity_); |
121 } | 149 } |
122 } | 150 } |
123 | 151 |
124 ~Instance() override { | 152 ~Instance() override { |
125 Stop(); | 153 Stop(); |
126 } | 154 } |
127 | 155 |
128 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { | 156 bool OnConnect(std::unique_ptr<ConnectParams>* in_params) { |
129 if (!service_.is_bound()) | 157 if (!service_.is_bound()) { |
| 158 RunConnectCallback(in_params->get(), mojom::ConnectResult::ACCESS_DENIED, |
| 159 identity_.user_id()); |
130 return false; | 160 return false; |
131 | |
132 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); | |
133 if (!params->connect_callback().is_null()) { | |
134 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | |
135 identity_.user_id()); | |
136 } | 161 } |
137 | 162 |
| 163 std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
| 164 RunConnectCallback(params.get(), mojom::ConnectResult::SUCCEEDED, |
| 165 identity_.user_id()); |
| 166 |
138 InterfaceProviderSpecMap specs; | 167 InterfaceProviderSpecMap specs; |
139 Instance* source = service_manager_->GetExistingInstance(params->source()); | 168 Instance* source = |
| 169 service_manager_->GetExistingInstance(params->source()); |
140 if (source) | 170 if (source) |
141 specs = source->interface_provider_specs_; | 171 specs = source->interface_provider_specs_; |
142 | 172 |
143 pending_service_connections_++; | 173 pending_service_connections_++; |
144 service_->OnConnect(ServiceInfo(params->source(), specs), | 174 service_->OnConnect(ServiceInfo(params->source(), specs), |
145 params->TakeRemoteInterfaces(), | 175 params->TakeRemoteInterfaces(), |
146 base::Bind(&Instance::OnConnectComplete, | 176 base::Bind(&Instance::OnConnectComplete, |
147 base::Unretained(this))); | 177 base::Unretained(this))); |
148 return true; | 178 return true; |
149 } | 179 } |
150 | 180 |
| 181 bool OnBindInterface(std::unique_ptr<ConnectParams>* in_params) { |
| 182 if (!service_.is_bound()) { |
| 183 RunBindInterfaceCallback(in_params->get(), |
| 184 mojom::ConnectResult::ACCESS_DENIED, |
| 185 identity_.user_id()); |
| 186 return false; |
| 187 } |
| 188 |
| 189 std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
| 190 InterfaceProviderSpecMap source_specs; |
| 191 InterfaceProviderSpec source_connection_spec; |
| 192 Instance* source = |
| 193 service_manager_->GetExistingInstance(params->source()); |
| 194 if (source) { |
| 195 source_specs = source->interface_provider_specs_; |
| 196 source_connection_spec = source->GetConnectionSpec(); |
| 197 } |
| 198 |
| 199 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, |
| 200 identity_, |
| 201 GetConnectionSpec()); |
| 202 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || |
| 203 exposed.count(params->interface_name()) > 0; |
| 204 if (!allowed) { |
| 205 std::stringstream ss; |
| 206 ss << "Connection InterfaceProviderSpec prevented service: " |
| 207 << params->source().name() << " from binding interface: " |
| 208 << params->interface_name() << " exposed by: " << identity_.name(); |
| 209 LOG(ERROR) << ss.str(); |
| 210 params->bind_interface_callback().Run(mojom::ConnectResult::ACCESS_DENIED, |
| 211 identity_.user_id()); |
| 212 return false; |
| 213 } |
| 214 |
| 215 params->bind_interface_callback().Run(mojom::ConnectResult::SUCCEEDED, |
| 216 identity_.user_id()); |
| 217 |
| 218 pending_service_connections_++; |
| 219 service_->OnBindInterface( |
| 220 ServiceInfo(params->source(), source_specs), |
| 221 params->interface_name(), |
| 222 params->TakeInterfaceRequestPipe(), |
| 223 base::Bind(&Instance::OnConnectComplete, base::Unretained(this))); |
| 224 return true; |
| 225 } |
| 226 |
151 void OnConnectComplete() { | 227 void OnConnectComplete() { |
152 DCHECK_GT(pending_service_connections_, 0); | 228 DCHECK_GT(pending_service_connections_, 0); |
153 pending_service_connections_--; | 229 pending_service_connections_--; |
154 } | 230 } |
155 | 231 |
156 void StartWithService(mojom::ServicePtr service) { | 232 void StartWithService(mojom::ServicePtr service) { |
157 CHECK(!service_); | 233 CHECK(!service_); |
158 state_ = State::STARTING; | 234 state_ = State::STARTING; |
159 service_ = std::move(service); | 235 service_ = std::move(service); |
160 service_.set_connection_error_handler( | 236 service_.set_connection_error_handler( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 // The service was started but the service manager hasn't received the | 298 // The service was started but the service manager hasn't received the |
223 // initial response from it yet. | 299 // initial response from it yet. |
224 STARTING, | 300 STARTING, |
225 | 301 |
226 // The service was started successfully. | 302 // The service was started successfully. |
227 STARTED | 303 STARTED |
228 }; | 304 }; |
229 | 305 |
230 // mojom::Connector implementation: | 306 // mojom::Connector implementation: |
231 void StartService( | 307 void StartService( |
232 const Identity& target, | 308 const Identity& in_target, |
233 mojo::ScopedMessagePipeHandle service_handle, | 309 mojo::ScopedMessagePipeHandle service_handle, |
234 mojom::PIDReceiverRequest pid_receiver_request) override { | 310 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, | |
248 mojom::InterfaceProviderRequest remote_interfaces, | |
249 const ConnectCallback& callback) override { | |
250 ConnectImpl(target, std::move(remote_interfaces), mojom::ServicePtr(), | |
251 mojom::PIDReceiverRequest(), callback); | |
252 } | |
253 | |
254 void BindInterface(const service_manager::Identity& target, | |
255 const std::string& interface_name, | |
256 mojo::ScopedMessagePipeHandle interface_pipe, | |
257 const BindInterfaceCallback& callback) override { | |
258 mojom::InterfaceProviderPtr remote_interfaces; | |
259 ConnectImpl( | |
260 target, | |
261 MakeRequest(&remote_interfaces), | |
262 mojom::ServicePtr(), | |
263 mojom::PIDReceiverRequest(), | |
264 base::Bind( | |
265 &service_manager::ServiceManager::Instance::BindCallbackWrapper, | |
266 weak_factory_.GetWeakPtr(), | |
267 callback)); | |
268 remote_interfaces->GetInterface(interface_name, std::move(interface_pipe)); | |
269 // TODO(beng): Rather than just forwarding thru to InterfaceProvider, do | |
270 // manifest policy intersection here. | |
271 } | |
272 | |
273 void ConnectImpl(const service_manager::Identity& in_target, | |
274 mojom::InterfaceProviderRequest remote_interfaces, | |
275 mojom::ServicePtr service, | |
276 mojom::PIDReceiverRequest pid_receiver_request, | |
277 const ConnectCallback& callback) { | |
278 Identity target = in_target; | 311 Identity target = in_target; |
279 if (target.user_id() == mojom::kInheritUserID) | 312 mojom::ConnectResult result = |
280 target.set_user_id(identity_.user_id()); | 313 ValidateConnectParams(&target, nullptr, nullptr); |
281 | 314 if (!Succeeded(result)) |
282 if (!ValidateIdentity(target, callback)) | |
283 return; | |
284 if (!ValidateClientProcessInfo(&service, &pid_receiver_request, target, | |
285 callback)) { | |
286 return; | |
287 } | |
288 if (!ValidateConnectionSpec(target, callback)) | |
289 return; | 315 return; |
290 | 316 |
291 std::unique_ptr<ConnectParams> params(new ConnectParams); | 317 std::unique_ptr<ConnectParams> params(new ConnectParams); |
292 params->set_source(identity_); | 318 params->set_source(identity_); |
293 params->set_target(target); | 319 params->set_target(target); |
294 params->set_remote_interfaces(std::move(remote_interfaces)); | 320 |
| 321 mojom::ServicePtr service; |
| 322 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); |
295 params->set_client_process_info(std::move(service), | 323 params->set_client_process_info(std::move(service), |
296 std::move(pid_receiver_request)); | 324 std::move(pid_receiver_request)); |
| 325 service_manager_->Connect( |
| 326 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 327 } |
| 328 |
| 329 void Connect(const service_manager::Identity& in_target, |
| 330 mojom::InterfaceProviderRequest remote_interfaces, |
| 331 const ConnectCallback& callback) override { |
| 332 Identity target = in_target; |
| 333 mojom::ConnectResult result = |
| 334 ValidateConnectParams(&target, nullptr, nullptr); |
| 335 if (!Succeeded(result)) { |
| 336 callback.Run(result, mojom::kInheritUserID); |
| 337 return; |
| 338 } |
| 339 |
| 340 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 341 params->set_source(identity_); |
| 342 params->set_target(target); |
| 343 params->set_remote_interfaces(std::move(remote_interfaces)); |
297 params->set_connect_callback(callback); | 344 params->set_connect_callback(callback); |
298 service_manager_->Connect( | 345 service_manager_->Connect( |
299 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | 346 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
300 } | 347 } |
| 348 |
| 349 void BindInterface(const service_manager::Identity& in_target, |
| 350 const std::string& interface_name, |
| 351 mojo::ScopedMessagePipeHandle interface_pipe, |
| 352 const BindInterfaceCallback& callback) override { |
| 353 Identity target = in_target; |
| 354 mojom::ConnectResult result = |
| 355 ValidateConnectParams(&target, nullptr, nullptr); |
| 356 if (!Succeeded(result)) { |
| 357 callback.Run(result, mojom::kInheritUserID); |
| 358 return; |
| 359 } |
| 360 |
| 361 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 362 params->set_source(identity_); |
| 363 params->set_target(target); |
| 364 params->set_interface_request_info(interface_name, |
| 365 std::move(interface_pipe)); |
| 366 params->set_bind_interface_callback(callback); |
| 367 service_manager_->Connect( |
| 368 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 369 } |
301 | 370 |
302 void Clone(mojom::ConnectorRequest request) override { | 371 void Clone(mojom::ConnectorRequest request) override { |
303 connectors_.AddBinding(this, std::move(request)); | 372 connectors_.AddBinding(this, std::move(request)); |
304 } | 373 } |
305 | 374 |
306 // mojom::PIDReceiver: | 375 // mojom::PIDReceiver: |
307 void SetPID(uint32_t pid) override { | 376 void SetPID(uint32_t pid) override { |
308 PIDAvailable(pid); | 377 PIDAvailable(pid); |
309 } | 378 } |
310 | 379 |
311 // InterfaceFactory<mojom::ServiceManager>: | 380 // InterfaceFactory<mojom::ServiceManager>: |
312 void Create(const Identity& remote_identity, | 381 void Create(const Identity& remote_identity, |
313 mojom::ServiceManagerRequest request) override { | 382 mojom::ServiceManagerRequest request) override { |
314 service_manager_bindings_.AddBinding(this, std::move(request)); | 383 service_manager_bindings_.AddBinding(this, std::move(request)); |
315 } | 384 } |
316 | 385 |
317 // mojom::ServiceManager implementation: | 386 // mojom::ServiceManager implementation: |
318 void AddListener(mojom::ServiceManagerListenerPtr listener) override { | 387 void AddListener(mojom::ServiceManagerListenerPtr listener) override { |
319 // TODO(beng): this should only track the instances matching this user, and | 388 // TODO(beng): this should only track the instances matching this user, and |
320 // root. | 389 // root. |
321 service_manager_->AddListener(std::move(listener)); | 390 service_manager_->AddListener(std::move(listener)); |
322 } | 391 } |
323 | 392 |
324 bool ValidateIdentity(const Identity& identity, | 393 mojom::ConnectResult ValidateConnectParams( |
325 const ConnectCallback& callback) { | 394 Identity* target, |
| 395 mojom::ServicePtr* service, |
| 396 mojom::PIDReceiverRequest* pid_receiver_request) { |
| 397 if (target->user_id() == mojom::kInheritUserID) |
| 398 target->set_user_id(identity_.user_id()); |
| 399 |
| 400 mojom::ConnectResult result = ValidateIdentity(*target); |
| 401 if (!Succeeded(result)) |
| 402 return result; |
| 403 |
| 404 result = ValidateClientProcessInfo(service, pid_receiver_request, *target); |
| 405 if (!Succeeded(result)) |
| 406 return result; |
| 407 return ValidateConnectionSpec(*target); |
| 408 } |
| 409 |
| 410 mojom::ConnectResult ValidateIdentity(const Identity& identity) { |
326 if (identity.name().empty()) { | 411 if (identity.name().empty()) { |
327 LOG(ERROR) << "Error: empty service name."; | 412 LOG(ERROR) << "Error: empty service name."; |
328 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 413 return mojom::ConnectResult::INVALID_ARGUMENT; |
329 mojom::kInheritUserID); | |
330 return false; | |
331 } | 414 } |
332 if (!base::IsValidGUID(identity.user_id())) { | 415 if (!base::IsValidGUID(identity.user_id())) { |
333 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); | 416 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); |
334 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 417 return mojom::ConnectResult::INVALID_ARGUMENT; |
335 mojom::kInheritUserID); | |
336 return false; | |
337 } | 418 } |
338 return true; | 419 return mojom::ConnectResult::SUCCEEDED; |
339 } | 420 } |
340 | 421 |
341 bool ValidateClientProcessInfo( | 422 mojom::ConnectResult ValidateClientProcessInfo( |
342 mojom::ServicePtr* service, | 423 mojom::ServicePtr* service, |
343 mojom::PIDReceiverRequest* pid_receiver_request, | 424 mojom::PIDReceiverRequest* pid_receiver_request, |
344 const Identity& target, | 425 const Identity& target) { |
345 const ConnectCallback& callback) { | 426 if (service && pid_receiver_request && |
346 if (service->is_bound() || pid_receiver_request->is_pending()) { | 427 (service->is_bound() || pid_receiver_request->is_pending())) { |
347 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { | 428 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { |
348 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " | 429 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " |
349 << "to register an instance for a process it created for " | 430 << "to register an instance for a process it created for " |
350 << "target: " << target.name() << " without the " | 431 << "target: " << target.name() << " without the " |
351 << "service_manager{client_process} capability " | 432 << "service_manager{client_process} capability " |
352 << "class."; | 433 << "class."; |
353 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 434 return mojom::ConnectResult::ACCESS_DENIED; |
354 mojom::kInheritUserID); | |
355 return false; | |
356 } | 435 } |
357 | 436 |
358 if (!service->is_bound() || !pid_receiver_request->is_pending()) { | 437 if (!service->is_bound() || !pid_receiver_request->is_pending()) { |
359 LOG(ERROR) << "Must supply both service AND " | 438 LOG(ERROR) << "Must supply both service AND " |
360 << "pid_receiver_request when sending client process info"; | 439 << "pid_receiver_request when sending client process info"; |
361 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 440 return mojom::ConnectResult::INVALID_ARGUMENT; |
362 mojom::kInheritUserID); | |
363 return false; | |
364 } | 441 } |
365 if (service_manager_->GetExistingInstance(target)) { | 442 if (service_manager_->GetExistingInstance(target)) { |
366 LOG(ERROR) << "Cannot client process matching existing identity:" | 443 LOG(ERROR) << "Cannot client process matching existing identity:" |
367 << "Name: " << target.name() << " User: " | 444 << "Name: " << target.name() << " User: " |
368 << target.user_id() << " Instance: " << target.instance(); | 445 << target.user_id() << " Instance: " << target.instance(); |
369 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 446 return mojom::ConnectResult::INVALID_ARGUMENT; |
370 mojom::kInheritUserID); | |
371 return false; | |
372 } | 447 } |
373 } | 448 } |
374 return true; | 449 return mojom::ConnectResult::SUCCEEDED; |
375 } | 450 } |
376 | 451 |
377 bool ValidateConnectionSpec(const Identity& target, | 452 mojom::ConnectResult ValidateConnectionSpec(const Identity& target) { |
378 const ConnectCallback& callback) { | |
379 InterfaceProviderSpec connection_spec = GetConnectionSpec(); | 453 InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
380 // TODO(beng): Need to do the following additional policy validation of | 454 // TODO(beng): Need to do the following additional policy validation of |
381 // whether this instance is allowed to connect using: | 455 // whether this instance is allowed to connect using: |
382 // - non-null client process info. | 456 // - non-null client process info. |
383 if (target.user_id() != identity_.user_id() && | 457 if (target.user_id() != identity_.user_id() && |
384 target.user_id() != mojom::kRootUserID && | 458 target.user_id() != mojom::kRootUserID && |
385 !HasCapability(connection_spec, kCapability_UserID)) { | 459 !HasCapability(connection_spec, kCapability_UserID)) { |
386 LOG(ERROR) << "Instance: " << identity_.name() | 460 LOG(ERROR) << "Instance: " << identity_.name() |
387 << " running as: " << identity_.user_id() | 461 << " running as: " << identity_.user_id() |
388 << " attempting to connect to: " << target.name() | 462 << " attempting to connect to: " << target.name() |
389 << " as: " << target.user_id() << " without " | 463 << " as: " << target.user_id() << " without " |
390 << " the service:service_manager{user_id} capability."; | 464 << " the service:service_manager{user_id} capability."; |
391 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 465 return mojom::ConnectResult::ACCESS_DENIED; |
392 mojom::kInheritUserID); | |
393 return false; | |
394 } | 466 } |
395 if (!target.instance().empty() && | 467 if (!target.instance().empty() && |
396 target.instance() != target.name() && | 468 target.instance() != target.name() && |
397 !HasCapability(connection_spec, kCapability_InstanceName)) { | 469 !HasCapability(connection_spec, kCapability_InstanceName)) { |
398 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " | 470 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " |
399 << "connect to " << target.name() | 471 << "connect to " << target.name() |
400 << " using Instance name: " << target.instance() | 472 << " using Instance name: " << target.instance() |
401 << " without the " | 473 << " without the " |
402 << "service_manager{instance_name} capability."; | 474 << "service_manager{instance_name} capability."; |
403 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 475 return mojom::ConnectResult::ACCESS_DENIED; |
404 return false; | |
405 } | 476 } |
406 | 477 |
407 if (allow_any_application_ || | 478 if (allow_any_application_ || |
408 connection_spec.requires.find(target.name()) != | 479 connection_spec.requires.find(target.name()) != |
409 connection_spec.requires.end()) { | 480 connection_spec.requires.end()) { |
410 return true; | 481 return mojom::ConnectResult::SUCCEEDED; |
411 } | 482 } |
412 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " | 483 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " |
413 << identity_.name() << " to: " << target.name(); | 484 << identity_.name() << " to: " << target.name(); |
414 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 485 return mojom::ConnectResult::ACCESS_DENIED; |
415 return false; | |
416 } | 486 } |
417 | 487 |
418 uint32_t GenerateUniqueID() const { | 488 uint32_t GenerateUniqueID() const { |
419 static uint32_t id = mojom::kInvalidInstanceID; | 489 static uint32_t id = mojom::kInvalidInstanceID; |
420 ++id; | 490 ++id; |
421 CHECK_NE(mojom::kInvalidInstanceID, id); | 491 CHECK_NE(mojom::kInvalidInstanceID, id); |
422 return id; | 492 return id; |
423 } | 493 } |
424 | 494 |
425 void PIDAvailable(base::ProcessId pid) { | 495 void PIDAvailable(base::ProcessId pid) { |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { | 845 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { |
776 listeners_.ForAllPtrs( | 846 listeners_.ForAllPtrs( |
777 [identity](mojom::ServiceManagerListener* listener) { | 847 [identity](mojom::ServiceManagerListener* listener) { |
778 listener->OnServiceFailedToStart(identity); | 848 listener->OnServiceFailedToStart(identity); |
779 }); | 849 }); |
780 } | 850 } |
781 | 851 |
782 bool ServiceManager::ConnectToExistingInstance( | 852 bool ServiceManager::ConnectToExistingInstance( |
783 std::unique_ptr<ConnectParams>* params) { | 853 std::unique_ptr<ConnectParams>* params) { |
784 Instance* instance = GetExistingInstance((*params)->target()); | 854 Instance* instance = GetExistingInstance((*params)->target()); |
785 return instance && instance->ConnectToService(params); | 855 if (instance) { |
| 856 if ((*params)->HasInterfaceRequestInfo()) { |
| 857 instance->OnBindInterface(params); |
| 858 return true; |
| 859 } |
| 860 return instance->OnConnect(params); |
| 861 } |
| 862 return false; |
786 } | 863 } |
787 | 864 |
788 ServiceManager::Instance* ServiceManager::CreateInstance( | 865 ServiceManager::Instance* ServiceManager::CreateInstance( |
789 const Identity& source, | 866 const Identity& source, |
790 const Identity& target, | 867 const Identity& target, |
791 const InterfaceProviderSpecMap& specs) { | 868 const InterfaceProviderSpecMap& specs) { |
792 CHECK(target.user_id() != mojom::kInheritUserID); | 869 CHECK(target.user_id() != mojom::kInheritUserID); |
793 | 870 |
794 auto instance = base::MakeUnique<Instance>(this, target, specs); | 871 auto instance = base::MakeUnique<Instance>(this, target, specs); |
795 Instance* raw_instance = instance.get(); | 872 Instance* raw_instance = instance.get(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 mojom::ResolveResultPtr result, | 938 mojom::ResolveResultPtr result, |
862 mojom::ResolveResultPtr parent) { | 939 mojom::ResolveResultPtr parent) { |
863 // If this request was originated by a specific Instance and that Instance is | 940 // If this request was originated by a specific Instance and that Instance is |
864 // no longer around, we ignore this response. | 941 // no longer around, we ignore this response. |
865 if (has_source_instance && !source_instance) | 942 if (has_source_instance && !source_instance) |
866 return; | 943 return; |
867 | 944 |
868 // If name resolution failed, we drop the connection. | 945 // If name resolution failed, we drop the connection. |
869 if (!result) { | 946 if (!result) { |
870 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); | 947 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); |
871 if (!params->connect_callback().is_null()) { | 948 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
872 params->connect_callback().Run( | |
873 mojom::ConnectResult::INVALID_ARGUMENT, ""); | |
874 } | |
875 return; | 949 return; |
876 } | 950 } |
877 | 951 |
878 std::string instance_name = params->target().instance(); | 952 std::string instance_name = params->target().instance(); |
879 | 953 |
880 // |result->interface_provider_specs| can be empty when there is no manifest. | 954 // |result->interface_provider_specs| can be empty when there is no manifest. |
881 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); | 955 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); |
882 auto it = result->interface_provider_specs.find( | 956 auto it = result->interface_provider_specs.find( |
883 mojom::kServiceManager_ConnectorSpec); | 957 mojom::kServiceManager_ConnectorSpec); |
884 if (it != result->interface_provider_specs.end()) | 958 if (it != result->interface_provider_specs.end()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 mojom::ServiceRequest request(&service); | 1008 mojom::ServiceRequest request(&service); |
935 | 1009 |
936 // The catalog was unable to read a manifest for this service. We can't do | 1010 // The catalog was unable to read a manifest for this service. We can't do |
937 // anything more. | 1011 // anything more. |
938 // TODO(beng): There may be some cases where it's valid to have an empty | 1012 // TODO(beng): There may be some cases where it's valid to have an empty |
939 // spec, so we should probably include a return value in |result|. | 1013 // spec, so we should probably include a return value in |result|. |
940 if (result->interface_provider_specs.empty()) { | 1014 if (result->interface_provider_specs.empty()) { |
941 LOG(ERROR) | 1015 LOG(ERROR) |
942 << "Error: The catalog was unable to read a manifest for service \"" | 1016 << "Error: The catalog was unable to read a manifest for service \"" |
943 << result->name << "\"."; | 1017 << result->name << "\"."; |
944 if (!params->connect_callback().is_null()) | 1018 RunCallback(params.get(), mojom::ConnectResult::ACCESS_DENIED, ""); |
945 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); | |
946 return; | 1019 return; |
947 } | 1020 } |
948 | 1021 |
949 if (parent) { | 1022 if (parent) { |
950 // This service is provided by another service via a ServiceFactory. | 1023 // This service is provided by another service via a ServiceFactory. |
951 std::string target_user_id = target.user_id(); | 1024 std::string target_user_id = target.user_id(); |
952 std::string factory_instance_name = instance_name; | 1025 std::string factory_instance_name = instance_name; |
953 | 1026 |
954 auto spec_iter = parent->interface_provider_specs.find( | 1027 auto spec_iter = parent->interface_provider_specs.find( |
955 mojom::kServiceManager_ConnectorSpec); | 1028 mojom::kServiceManager_ConnectorSpec); |
(...skipping 17 matching lines...) Expand all Loading... |
973 } else { | 1046 } else { |
974 base::FilePath package_path; | 1047 base::FilePath package_path; |
975 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( | 1048 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( |
976 target.name(), &package_path)) { | 1049 target.name(), &package_path)) { |
977 package_path = result->package_path; | 1050 package_path = result->package_path; |
978 } | 1051 } |
979 DCHECK(!package_path.empty()); | 1052 DCHECK(!package_path.empty()); |
980 | 1053 |
981 if (!instance->StartWithFilePath(package_path)) { | 1054 if (!instance->StartWithFilePath(package_path)) { |
982 OnInstanceError(instance); | 1055 OnInstanceError(instance); |
983 if (!params->connect_callback().is_null()) { | 1056 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
984 params->connect_callback().Run( | |
985 mojom::ConnectResult::INVALID_ARGUMENT, ""); | |
986 } | |
987 return; | 1057 return; |
988 } | 1058 } |
989 } | 1059 } |
990 } | 1060 } |
991 | 1061 |
992 // Now that the instance has a Service, we can connect to it. | 1062 // Now that the instance has a Service, we can connect to it. |
993 bool connected = instance->ConnectToService(¶ms); | 1063 if (params->HasInterfaceRequestInfo()) { |
994 DCHECK(connected); | 1064 instance->OnBindInterface(¶ms); |
| 1065 } else { |
| 1066 bool connected = instance->OnConnect(¶ms); |
| 1067 DCHECK(connected); |
| 1068 } |
995 } | 1069 } |
996 | 1070 |
997 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 1071 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
998 return weak_ptr_factory_.GetWeakPtr(); | 1072 return weak_ptr_factory_.GetWeakPtr(); |
999 } | 1073 } |
1000 | 1074 |
1001 } // namespace service_manager | 1075 } // namespace service_manager |
OLD | NEW |