Chromium Code Reviews| 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 void RunCallback(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; | |
| 60 } | |
| 61 if (!params->bind_interface_callback().is_null()) | |
| 62 params->bind_interface_callback().Run(result, user_id); | |
| 63 } | |
| 64 | |
| 50 } // namespace | 65 } // namespace |
| 51 | 66 |
| 52 Identity CreateServiceManagerIdentity() { | 67 Identity CreateServiceManagerIdentity() { |
| 53 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); | 68 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); |
| 54 } | 69 } |
| 55 | 70 |
| 56 Identity CreateCatalogIdentity() { | 71 Identity CreateCatalogIdentity() { |
| 57 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); | 72 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); |
| 58 } | 73 } |
| 59 | 74 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 } else { | 133 } else { |
| 119 // Notify the ServiceManager that this Instance is really going away. | 134 // Notify the ServiceManager that this Instance is really going away. |
| 120 service_manager_->OnInstanceStopped(identity_); | 135 service_manager_->OnInstanceStopped(identity_); |
| 121 } | 136 } |
| 122 } | 137 } |
| 123 | 138 |
| 124 ~Instance() override { | 139 ~Instance() override { |
| 125 Stop(); | 140 Stop(); |
| 126 } | 141 } |
| 127 | 142 |
| 128 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { | 143 bool OnConnect(std::unique_ptr<ConnectParams>* in_params) { |
| 129 if (!service_.is_bound()) | 144 if (!service_.is_bound()) |
| 130 return false; | 145 return false; |
| 131 | 146 |
| 132 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); | 147 std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
| 133 if (!params->connect_callback().is_null()) { | 148 if (!params->connect_callback().is_null()) { |
| 134 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 149 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
| 135 identity_.user_id()); | 150 identity_.user_id()); |
| 136 } | 151 } |
| 137 | 152 |
| 138 InterfaceProviderSpecMap specs; | 153 InterfaceProviderSpecMap specs; |
| 139 Instance* source = service_manager_->GetExistingInstance(params->source()); | 154 Instance* source = |
| 155 service_manager_->GetExistingInstance(params->source()); | |
| 140 if (source) | 156 if (source) |
| 141 specs = source->interface_provider_specs_; | 157 specs = source->interface_provider_specs_; |
| 142 | 158 |
| 143 pending_service_connections_++; | 159 pending_service_connections_++; |
| 144 service_->OnConnect(ServiceInfo(params->source(), specs), | 160 service_->OnConnect(ServiceInfo(params->source(), specs), |
| 145 params->TakeRemoteInterfaces(), | 161 params->TakeRemoteInterfaces(), |
| 146 base::Bind(&Instance::OnConnectComplete, | 162 base::Bind(&Instance::OnConnectComplete, |
| 147 base::Unretained(this))); | 163 base::Unretained(this))); |
| 148 return true; | 164 return true; |
| 149 } | 165 } |
| 150 | 166 |
| 167 bool OnBindInterface(std::unique_ptr<ConnectParams>* in_params) { | |
| 168 if (!service_.is_bound()) | |
|
Ken Rockot(use gerrit already)
2017/01/12 23:05:00
We need to run the response callback in this case.
| |
| 169 return false; | |
| 170 | |
| 171 std::unique_ptr<ConnectParams> params(std::move(*in_params)); | |
| 172 InterfaceProviderSpecMap source_specs; | |
| 173 InterfaceProviderSpec source_connection_spec; | |
| 174 Instance* source = | |
| 175 service_manager_->GetExistingInstance(params->source()); | |
| 176 if (source) { | |
| 177 source_specs = source->interface_provider_specs_; | |
| 178 source_connection_spec = source->GetConnectionSpec(); | |
| 179 } | |
| 180 | |
| 181 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, | |
| 182 identity_, | |
| 183 GetConnectionSpec()); | |
| 184 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || | |
| 185 exposed.count(params->interface_name()) > 0; | |
| 186 if (!allowed) { | |
| 187 std::stringstream ss; | |
| 188 ss << "Connection InterfaceProviderSpec prevented service: " | |
| 189 << params->source().name() << " from binding interface: " | |
| 190 << params->interface_name() << " exposed by: " << identity_.name(); | |
| 191 LOG(ERROR) << ss.str(); | |
| 192 params->bind_interface_callback().Run(mojom::ConnectResult::ACCESS_DENIED, | |
| 193 identity_.user_id()); | |
| 194 return false; | |
| 195 } | |
| 196 | |
| 197 params->bind_interface_callback().Run(mojom::ConnectResult::SUCCEEDED, | |
| 198 identity_.user_id()); | |
| 199 | |
| 200 pending_service_connections_++; | |
| 201 service_->OnBindInterface( | |
| 202 ServiceInfo(params->source(), source_specs), | |
| 203 params->interface_name(), | |
| 204 params->TakeInterfaceRequestPipe(), | |
| 205 base::Bind(&Instance::OnConnectComplete, base::Unretained(this))); | |
| 206 return true; | |
| 207 } | |
| 208 | |
| 151 void OnConnectComplete() { | 209 void OnConnectComplete() { |
| 152 DCHECK_GT(pending_service_connections_, 0); | 210 DCHECK_GT(pending_service_connections_, 0); |
| 153 pending_service_connections_--; | 211 pending_service_connections_--; |
| 154 } | 212 } |
| 155 | 213 |
| 156 void StartWithService(mojom::ServicePtr service) { | 214 void StartWithService(mojom::ServicePtr service) { |
| 157 CHECK(!service_); | 215 CHECK(!service_); |
| 158 state_ = State::STARTING; | 216 state_ = State::STARTING; |
| 159 service_ = std::move(service); | 217 service_ = std::move(service); |
| 160 service_.set_connection_error_handler( | 218 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 | 280 // The service was started but the service manager hasn't received the |
| 223 // initial response from it yet. | 281 // initial response from it yet. |
| 224 STARTING, | 282 STARTING, |
| 225 | 283 |
| 226 // The service was started successfully. | 284 // The service was started successfully. |
| 227 STARTED | 285 STARTED |
| 228 }; | 286 }; |
| 229 | 287 |
| 230 // mojom::Connector implementation: | 288 // mojom::Connector implementation: |
| 231 void StartService( | 289 void StartService( |
| 232 const Identity& target, | 290 const Identity& in_target, |
| 233 mojo::ScopedMessagePipeHandle service_handle, | 291 mojo::ScopedMessagePipeHandle service_handle, |
| 234 mojom::PIDReceiverRequest pid_receiver_request) override { | 292 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; | 293 Identity target = in_target; |
| 279 if (target.user_id() == mojom::kInheritUserID) | 294 mojom::ConnectResult result = |
| 280 target.set_user_id(identity_.user_id()); | 295 ValidateConnectParams(&target, nullptr, nullptr); |
| 281 | 296 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; | 297 return; |
| 290 | 298 |
| 291 std::unique_ptr<ConnectParams> params(new ConnectParams); | 299 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 292 params->set_source(identity_); | 300 params->set_source(identity_); |
| 293 params->set_target(target); | 301 params->set_target(target); |
| 294 params->set_remote_interfaces(std::move(remote_interfaces)); | 302 |
| 303 mojom::ServicePtr service; | |
| 304 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); | |
| 295 params->set_client_process_info(std::move(service), | 305 params->set_client_process_info(std::move(service), |
| 296 std::move(pid_receiver_request)); | 306 std::move(pid_receiver_request)); |
| 307 service_manager_->Connect( | |
| 308 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | |
| 309 } | |
| 310 | |
| 311 void Connect(const service_manager::Identity& in_target, | |
| 312 mojom::InterfaceProviderRequest remote_interfaces, | |
| 313 const ConnectCallback& callback) override { | |
| 314 Identity target = in_target; | |
| 315 mojom::ConnectResult result = | |
| 316 ValidateConnectParams(&target, nullptr, nullptr); | |
| 317 if (!Succeeded(result)) { | |
| 318 callback.Run(result, mojom::kInheritUserID); | |
| 319 return; | |
| 320 } | |
| 321 | |
| 322 std::unique_ptr<ConnectParams> params(new ConnectParams); | |
| 323 params->set_source(identity_); | |
| 324 params->set_target(target); | |
| 325 params->set_remote_interfaces(std::move(remote_interfaces)); | |
| 297 params->set_connect_callback(callback); | 326 params->set_connect_callback(callback); |
| 298 service_manager_->Connect( | 327 service_manager_->Connect( |
| 299 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | 328 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 300 } | 329 } |
| 330 | |
| 331 void BindInterface(const service_manager::Identity& in_target, | |
| 332 const std::string& interface_name, | |
| 333 mojo::ScopedMessagePipeHandle interface_pipe, | |
| 334 const BindInterfaceCallback& callback) override { | |
| 335 Identity target = in_target; | |
| 336 mojom::ConnectResult result = | |
| 337 ValidateConnectParams(&target, nullptr, nullptr); | |
| 338 if (!Succeeded(result)) { | |
| 339 callback.Run(result, mojom::kInheritUserID); | |
| 340 return; | |
| 341 } | |
| 342 | |
| 343 std::unique_ptr<ConnectParams> params(new ConnectParams); | |
| 344 params->set_source(identity_); | |
| 345 params->set_target(target); | |
| 346 params->set_interface_request_info(interface_name, | |
| 347 std::move(interface_pipe)); | |
| 348 params->set_bind_interface_callback(callback); | |
| 349 service_manager_->Connect( | |
| 350 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | |
| 351 } | |
| 301 | 352 |
| 302 void Clone(mojom::ConnectorRequest request) override { | 353 void Clone(mojom::ConnectorRequest request) override { |
| 303 connectors_.AddBinding(this, std::move(request)); | 354 connectors_.AddBinding(this, std::move(request)); |
| 304 } | 355 } |
| 305 | 356 |
| 306 // mojom::PIDReceiver: | 357 // mojom::PIDReceiver: |
| 307 void SetPID(uint32_t pid) override { | 358 void SetPID(uint32_t pid) override { |
| 308 PIDAvailable(pid); | 359 PIDAvailable(pid); |
| 309 } | 360 } |
| 310 | 361 |
| 311 // InterfaceFactory<mojom::ServiceManager>: | 362 // InterfaceFactory<mojom::ServiceManager>: |
| 312 void Create(const Identity& remote_identity, | 363 void Create(const Identity& remote_identity, |
| 313 mojom::ServiceManagerRequest request) override { | 364 mojom::ServiceManagerRequest request) override { |
| 314 service_manager_bindings_.AddBinding(this, std::move(request)); | 365 service_manager_bindings_.AddBinding(this, std::move(request)); |
| 315 } | 366 } |
| 316 | 367 |
| 317 // mojom::ServiceManager implementation: | 368 // mojom::ServiceManager implementation: |
| 318 void AddListener(mojom::ServiceManagerListenerPtr listener) override { | 369 void AddListener(mojom::ServiceManagerListenerPtr listener) override { |
| 319 // TODO(beng): this should only track the instances matching this user, and | 370 // TODO(beng): this should only track the instances matching this user, and |
| 320 // root. | 371 // root. |
| 321 service_manager_->AddListener(std::move(listener)); | 372 service_manager_->AddListener(std::move(listener)); |
| 322 } | 373 } |
| 323 | 374 |
| 324 bool ValidateIdentity(const Identity& identity, | 375 mojom::ConnectResult ValidateConnectParams( |
| 325 const ConnectCallback& callback) { | 376 Identity* target, |
| 377 mojom::ServicePtr* service, | |
| 378 mojom::PIDReceiverRequest* pid_receiver_request) { | |
| 379 if (target->user_id() == mojom::kInheritUserID) | |
| 380 target->set_user_id(identity_.user_id()); | |
| 381 | |
| 382 mojom::ConnectResult result = ValidateIdentity(*target); | |
| 383 if (!Succeeded(result)) | |
| 384 return result; | |
| 385 | |
| 386 result = ValidateClientProcessInfo(service, pid_receiver_request, *target); | |
| 387 if (!Succeeded(result)) | |
| 388 return result; | |
| 389 return ValidateConnectionSpec(*target); | |
| 390 } | |
| 391 | |
| 392 mojom::ConnectResult ValidateIdentity(const Identity& identity) { | |
| 326 if (identity.name().empty()) { | 393 if (identity.name().empty()) { |
| 327 LOG(ERROR) << "Error: empty service name."; | 394 LOG(ERROR) << "Error: empty service name."; |
| 328 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 395 return mojom::ConnectResult::INVALID_ARGUMENT; |
| 329 mojom::kInheritUserID); | |
| 330 return false; | |
| 331 } | 396 } |
| 332 if (!base::IsValidGUID(identity.user_id())) { | 397 if (!base::IsValidGUID(identity.user_id())) { |
| 333 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); | 398 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); |
| 334 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 399 return mojom::ConnectResult::INVALID_ARGUMENT; |
| 335 mojom::kInheritUserID); | |
| 336 return false; | |
| 337 } | 400 } |
| 338 return true; | 401 return mojom::ConnectResult::SUCCEEDED; |
| 339 } | 402 } |
| 340 | 403 |
| 341 bool ValidateClientProcessInfo( | 404 mojom::ConnectResult ValidateClientProcessInfo( |
| 342 mojom::ServicePtr* service, | 405 mojom::ServicePtr* service, |
| 343 mojom::PIDReceiverRequest* pid_receiver_request, | 406 mojom::PIDReceiverRequest* pid_receiver_request, |
| 344 const Identity& target, | 407 const Identity& target) { |
| 345 const ConnectCallback& callback) { | 408 if (service && pid_receiver_request && |
| 346 if (service->is_bound() || pid_receiver_request->is_pending()) { | 409 (service->is_bound() || pid_receiver_request->is_pending())) { |
| 347 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { | 410 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { |
| 348 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " | 411 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " |
| 349 << "to register an instance for a process it created for " | 412 << "to register an instance for a process it created for " |
| 350 << "target: " << target.name() << " without the " | 413 << "target: " << target.name() << " without the " |
| 351 << "service_manager{client_process} capability " | 414 << "service_manager{client_process} capability " |
| 352 << "class."; | 415 << "class."; |
| 353 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 416 return mojom::ConnectResult::ACCESS_DENIED; |
| 354 mojom::kInheritUserID); | |
| 355 return false; | |
| 356 } | 417 } |
| 357 | 418 |
| 358 if (!service->is_bound() || !pid_receiver_request->is_pending()) { | 419 if (!service->is_bound() || !pid_receiver_request->is_pending()) { |
| 359 LOG(ERROR) << "Must supply both service AND " | 420 LOG(ERROR) << "Must supply both service AND " |
| 360 << "pid_receiver_request when sending client process info"; | 421 << "pid_receiver_request when sending client process info"; |
| 361 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 422 return mojom::ConnectResult::INVALID_ARGUMENT; |
| 362 mojom::kInheritUserID); | |
| 363 return false; | |
| 364 } | 423 } |
| 365 if (service_manager_->GetExistingInstance(target)) { | 424 if (service_manager_->GetExistingInstance(target)) { |
| 366 LOG(ERROR) << "Cannot client process matching existing identity:" | 425 LOG(ERROR) << "Cannot client process matching existing identity:" |
| 367 << "Name: " << target.name() << " User: " | 426 << "Name: " << target.name() << " User: " |
| 368 << target.user_id() << " Instance: " << target.instance(); | 427 << target.user_id() << " Instance: " << target.instance(); |
| 369 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 428 return mojom::ConnectResult::INVALID_ARGUMENT; |
| 370 mojom::kInheritUserID); | |
| 371 return false; | |
| 372 } | 429 } |
| 373 } | 430 } |
| 374 return true; | 431 return mojom::ConnectResult::SUCCEEDED; |
| 375 } | 432 } |
| 376 | 433 |
| 377 bool ValidateConnectionSpec(const Identity& target, | 434 mojom::ConnectResult ValidateConnectionSpec(const Identity& target) { |
| 378 const ConnectCallback& callback) { | |
| 379 InterfaceProviderSpec connection_spec = GetConnectionSpec(); | 435 InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
| 380 // TODO(beng): Need to do the following additional policy validation of | 436 // TODO(beng): Need to do the following additional policy validation of |
| 381 // whether this instance is allowed to connect using: | 437 // whether this instance is allowed to connect using: |
| 382 // - non-null client process info. | 438 // - non-null client process info. |
| 383 if (target.user_id() != identity_.user_id() && | 439 if (target.user_id() != identity_.user_id() && |
| 384 target.user_id() != mojom::kRootUserID && | 440 target.user_id() != mojom::kRootUserID && |
| 385 !HasCapability(connection_spec, kCapability_UserID)) { | 441 !HasCapability(connection_spec, kCapability_UserID)) { |
| 386 LOG(ERROR) << "Instance: " << identity_.name() | 442 LOG(ERROR) << "Instance: " << identity_.name() |
| 387 << " running as: " << identity_.user_id() | 443 << " running as: " << identity_.user_id() |
| 388 << " attempting to connect to: " << target.name() | 444 << " attempting to connect to: " << target.name() |
| 389 << " as: " << target.user_id() << " without " | 445 << " as: " << target.user_id() << " without " |
| 390 << " the service:service_manager{user_id} capability."; | 446 << " the service:service_manager{user_id} capability."; |
| 391 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 447 return mojom::ConnectResult::ACCESS_DENIED; |
| 392 mojom::kInheritUserID); | |
| 393 return false; | |
| 394 } | 448 } |
| 395 if (!target.instance().empty() && | 449 if (!target.instance().empty() && |
| 396 target.instance() != target.name() && | 450 target.instance() != target.name() && |
| 397 !HasCapability(connection_spec, kCapability_InstanceName)) { | 451 !HasCapability(connection_spec, kCapability_InstanceName)) { |
| 398 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " | 452 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " |
| 399 << "connect to " << target.name() | 453 << "connect to " << target.name() |
| 400 << " using Instance name: " << target.instance() | 454 << " using Instance name: " << target.instance() |
| 401 << " without the " | 455 << " without the " |
| 402 << "service_manager{instance_name} capability."; | 456 << "service_manager{instance_name} capability."; |
| 403 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 457 return mojom::ConnectResult::ACCESS_DENIED; |
| 404 return false; | |
| 405 } | 458 } |
| 406 | 459 |
| 407 if (allow_any_application_ || | 460 if (allow_any_application_ || |
| 408 connection_spec.requires.find(target.name()) != | 461 connection_spec.requires.find(target.name()) != |
| 409 connection_spec.requires.end()) { | 462 connection_spec.requires.end()) { |
| 410 return true; | 463 return mojom::ConnectResult::SUCCEEDED; |
| 411 } | 464 } |
| 412 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " | 465 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " |
| 413 << identity_.name() << " to: " << target.name(); | 466 << identity_.name() << " to: " << target.name(); |
| 414 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 467 return mojom::ConnectResult::ACCESS_DENIED; |
| 415 return false; | |
| 416 } | 468 } |
| 417 | 469 |
| 418 uint32_t GenerateUniqueID() const { | 470 uint32_t GenerateUniqueID() const { |
| 419 static uint32_t id = mojom::kInvalidInstanceID; | 471 static uint32_t id = mojom::kInvalidInstanceID; |
| 420 ++id; | 472 ++id; |
| 421 CHECK_NE(mojom::kInvalidInstanceID, id); | 473 CHECK_NE(mojom::kInvalidInstanceID, id); |
| 422 return id; | 474 return id; |
| 423 } | 475 } |
| 424 | 476 |
| 425 void PIDAvailable(base::ProcessId pid) { | 477 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) { | 827 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { |
| 776 listeners_.ForAllPtrs( | 828 listeners_.ForAllPtrs( |
| 777 [identity](mojom::ServiceManagerListener* listener) { | 829 [identity](mojom::ServiceManagerListener* listener) { |
| 778 listener->OnServiceFailedToStart(identity); | 830 listener->OnServiceFailedToStart(identity); |
| 779 }); | 831 }); |
| 780 } | 832 } |
| 781 | 833 |
| 782 bool ServiceManager::ConnectToExistingInstance( | 834 bool ServiceManager::ConnectToExistingInstance( |
| 783 std::unique_ptr<ConnectParams>* params) { | 835 std::unique_ptr<ConnectParams>* params) { |
| 784 Instance* instance = GetExistingInstance((*params)->target()); | 836 Instance* instance = GetExistingInstance((*params)->target()); |
| 785 return instance && instance->ConnectToService(params); | 837 if (instance) { |
| 838 if ((*params)->HasInterfaceRequestInfo()) { | |
| 839 instance->OnBindInterface(params); | |
| 840 return true; | |
| 841 } | |
| 842 return instance->OnConnect(params); | |
| 843 } | |
| 844 return false; | |
| 786 } | 845 } |
| 787 | 846 |
| 788 ServiceManager::Instance* ServiceManager::CreateInstance( | 847 ServiceManager::Instance* ServiceManager::CreateInstance( |
| 789 const Identity& source, | 848 const Identity& source, |
| 790 const Identity& target, | 849 const Identity& target, |
| 791 const InterfaceProviderSpecMap& specs) { | 850 const InterfaceProviderSpecMap& specs) { |
| 792 CHECK(target.user_id() != mojom::kInheritUserID); | 851 CHECK(target.user_id() != mojom::kInheritUserID); |
| 793 | 852 |
| 794 auto instance = base::MakeUnique<Instance>(this, target, specs); | 853 auto instance = base::MakeUnique<Instance>(this, target, specs); |
| 795 Instance* raw_instance = instance.get(); | 854 Instance* raw_instance = instance.get(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 mojom::ResolveResultPtr result, | 920 mojom::ResolveResultPtr result, |
| 862 mojom::ResolveResultPtr parent) { | 921 mojom::ResolveResultPtr parent) { |
| 863 // If this request was originated by a specific Instance and that Instance is | 922 // If this request was originated by a specific Instance and that Instance is |
| 864 // no longer around, we ignore this response. | 923 // no longer around, we ignore this response. |
| 865 if (has_source_instance && !source_instance) | 924 if (has_source_instance && !source_instance) |
| 866 return; | 925 return; |
| 867 | 926 |
| 868 // If name resolution failed, we drop the connection. | 927 // If name resolution failed, we drop the connection. |
| 869 if (!result) { | 928 if (!result) { |
| 870 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); | 929 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); |
| 871 if (!params->connect_callback().is_null()) { | 930 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
| 872 params->connect_callback().Run( | |
| 873 mojom::ConnectResult::INVALID_ARGUMENT, ""); | |
| 874 } | |
| 875 return; | 931 return; |
| 876 } | 932 } |
| 877 | 933 |
| 878 std::string instance_name = params->target().instance(); | 934 std::string instance_name = params->target().instance(); |
| 879 | 935 |
| 880 // |result->interface_provider_specs| can be empty when there is no manifest. | 936 // |result->interface_provider_specs| can be empty when there is no manifest. |
| 881 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); | 937 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); |
| 882 auto it = result->interface_provider_specs.find( | 938 auto it = result->interface_provider_specs.find( |
| 883 mojom::kServiceManager_ConnectorSpec); | 939 mojom::kServiceManager_ConnectorSpec); |
| 884 if (it != result->interface_provider_specs.end()) | 940 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); | 990 mojom::ServiceRequest request(&service); |
| 935 | 991 |
| 936 // The catalog was unable to read a manifest for this service. We can't do | 992 // The catalog was unable to read a manifest for this service. We can't do |
| 937 // anything more. | 993 // anything more. |
| 938 // TODO(beng): There may be some cases where it's valid to have an empty | 994 // 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|. | 995 // spec, so we should probably include a return value in |result|. |
| 940 if (result->interface_provider_specs.empty()) { | 996 if (result->interface_provider_specs.empty()) { |
| 941 LOG(ERROR) | 997 LOG(ERROR) |
| 942 << "Error: The catalog was unable to read a manifest for service \"" | 998 << "Error: The catalog was unable to read a manifest for service \"" |
| 943 << result->name << "\"."; | 999 << result->name << "\"."; |
| 944 if (!params->connect_callback().is_null()) | 1000 RunCallback(params.get(), mojom::ConnectResult::ACCESS_DENIED, ""); |
| 945 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); | |
| 946 return; | 1001 return; |
| 947 } | 1002 } |
| 948 | 1003 |
| 949 if (parent) { | 1004 if (parent) { |
| 950 // This service is provided by another service via a ServiceFactory. | 1005 // This service is provided by another service via a ServiceFactory. |
| 951 std::string target_user_id = target.user_id(); | 1006 std::string target_user_id = target.user_id(); |
| 952 std::string factory_instance_name = instance_name; | 1007 std::string factory_instance_name = instance_name; |
| 953 | 1008 |
| 954 auto spec_iter = parent->interface_provider_specs.find( | 1009 auto spec_iter = parent->interface_provider_specs.find( |
| 955 mojom::kServiceManager_ConnectorSpec); | 1010 mojom::kServiceManager_ConnectorSpec); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 973 } else { | 1028 } else { |
| 974 base::FilePath package_path; | 1029 base::FilePath package_path; |
| 975 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( | 1030 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( |
| 976 target.name(), &package_path)) { | 1031 target.name(), &package_path)) { |
| 977 package_path = result->package_path; | 1032 package_path = result->package_path; |
| 978 } | 1033 } |
| 979 DCHECK(!package_path.empty()); | 1034 DCHECK(!package_path.empty()); |
| 980 | 1035 |
| 981 if (!instance->StartWithFilePath(package_path)) { | 1036 if (!instance->StartWithFilePath(package_path)) { |
| 982 OnInstanceError(instance); | 1037 OnInstanceError(instance); |
| 983 if (!params->connect_callback().is_null()) { | 1038 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); |
| 984 params->connect_callback().Run( | |
| 985 mojom::ConnectResult::INVALID_ARGUMENT, ""); | |
| 986 } | |
| 987 return; | 1039 return; |
| 988 } | 1040 } |
| 989 } | 1041 } |
| 990 } | 1042 } |
| 991 | 1043 |
| 992 // Now that the instance has a Service, we can connect to it. | 1044 // Now that the instance has a Service, we can connect to it. |
| 993 bool connected = instance->ConnectToService(¶ms); | 1045 if (params->HasInterfaceRequestInfo()) { |
| 994 DCHECK(connected); | 1046 instance->OnBindInterface(¶ms); |
| 1047 } else { | |
| 1048 bool connected = instance->OnConnect(¶ms); | |
| 1049 DCHECK(connected); | |
| 1050 } | |
| 995 } | 1051 } |
| 996 | 1052 |
| 997 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 1053 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
| 998 return weak_ptr_factory_.GetWeakPtr(); | 1054 return weak_ptr_factory_.GetWeakPtr(); |
| 999 } | 1055 } |
| 1000 | 1056 |
| 1001 } // namespace service_manager | 1057 } // namespace service_manager |
| OLD | NEW |