| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/guid.h" | 13 #include "base/guid.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 17 #include "base/process/process.h" | 17 #include "base/process/process.h" |
| 18 #include "base/process/process_handle.h" | 18 #include "base/process/process_handle.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 22 #include "mojo/public/cpp/bindings/associated_binding.h" | 22 #include "mojo/public/cpp/bindings/associated_binding.h" |
| 23 #include "mojo/public/cpp/bindings/binding.h" | 23 #include "mojo/public/cpp/bindings/binding.h" |
| 24 #include "mojo/public/cpp/bindings/binding_set.h" | 24 #include "mojo/public/cpp/bindings/binding_set.h" |
| 25 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 25 #include "services/catalog/public/interfaces/constants.mojom.h" | 26 #include "services/catalog/public/interfaces/constants.mojom.h" |
| 26 #include "services/service_manager/connect_util.h" | 27 #include "services/service_manager/connect_util.h" |
| 27 #include "services/service_manager/public/cpp/connector.h" | 28 #include "services/service_manager/public/cpp/connector.h" |
| 28 #include "services/service_manager/public/cpp/interface_registry.h" | 29 #include "services/service_manager/public/cpp/interface_registry.h" |
| 29 #include "services/service_manager/public/cpp/service.h" | 30 #include "services/service_manager/public/cpp/service.h" |
| 30 #include "services/service_manager/public/cpp/service_context.h" | 31 #include "services/service_manager/public/cpp/service_context.h" |
| 31 #include "services/service_manager/public/interfaces/connector.mojom.h" | 32 #include "services/service_manager/public/interfaces/connector.mojom.h" |
| 32 #include "services/service_manager/public/interfaces/constants.mojom.h" | 33 #include "services/service_manager/public/interfaces/constants.mojom.h" |
| 33 #include "services/service_manager/public/interfaces/service.mojom.h" | 34 #include "services/service_manager/public/interfaces/service.mojom.h" |
| 34 #include "services/service_manager/public/interfaces/service_control.mojom.h" | 35 #include "services/service_manager/public/interfaces/service_control.mojom.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 71 } |
| 71 | 72 |
| 72 bool HasCapability(const InterfaceProviderSpec& spec, | 73 bool HasCapability(const InterfaceProviderSpec& spec, |
| 73 const std::string& capability) { | 74 const std::string& capability) { |
| 74 auto it = spec.requires.find(service_manager::mojom::kServiceName); | 75 auto it = spec.requires.find(service_manager::mojom::kServiceName); |
| 75 if (it == spec.requires.end()) | 76 if (it == spec.requires.end()) |
| 76 return false; | 77 return false; |
| 77 return it->second.find(capability) != it->second.end(); | 78 return it->second.find(capability) != it->second.end(); |
| 78 } | 79 } |
| 79 | 80 |
| 81 bool AllowsInterface(const Identity& source, |
| 82 const InterfaceProviderSpec& source_spec, |
| 83 const Identity& target, |
| 84 const InterfaceProviderSpec& target_spec, |
| 85 const std::string& interface_name) { |
| 86 InterfaceSet exposed = |
| 87 GetInterfacesToExpose(source_spec, target, target_spec); |
| 88 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || |
| 89 exposed.count(interface_name) > 0; |
| 90 if (!allowed) { |
| 91 std::stringstream ss; |
| 92 ss << "Connection InterfaceProviderSpec prevented service: " |
| 93 << source.name() << " from binding interface: " << interface_name |
| 94 << " exposed by: " << target.name(); |
| 95 LOG(ERROR) << ss.str(); |
| 96 } |
| 97 return allowed; |
| 98 } |
| 99 |
| 80 // Encapsulates a connection to an instance of a service, tracked by the | 100 // Encapsulates a connection to an instance of a service, tracked by the |
| 81 // Service Manager. | 101 // Service Manager. |
| 82 class ServiceManager::Instance | 102 class ServiceManager::Instance |
| 83 : public mojom::Connector, | 103 : public mojom::Connector, |
| 84 public mojom::PIDReceiver, | 104 public mojom::PIDReceiver, |
| 85 public Service, | 105 public Service, |
| 86 public mojom::ServiceManager, | 106 public mojom::ServiceManager, |
| 87 public mojom::ServiceControl { | 107 public mojom::ServiceControl { |
| 88 public: | 108 public: |
| 89 Instance(service_manager::ServiceManager* service_manager, | 109 Instance(service_manager::ServiceManager* service_manager, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 std::unique_ptr<ConnectParams> params(std::move(*in_params)); | 158 std::unique_ptr<ConnectParams> params(std::move(*in_params)); |
| 139 InterfaceProviderSpecMap source_specs; | 159 InterfaceProviderSpecMap source_specs; |
| 140 InterfaceProviderSpec source_connection_spec; | 160 InterfaceProviderSpec source_connection_spec; |
| 141 Instance* source = | 161 Instance* source = |
| 142 service_manager_->GetExistingInstance(params->source()); | 162 service_manager_->GetExistingInstance(params->source()); |
| 143 if (source) { | 163 if (source) { |
| 144 source_specs = source->interface_provider_specs_; | 164 source_specs = source->interface_provider_specs_; |
| 145 source_connection_spec = source->GetConnectionSpec(); | 165 source_connection_spec = source->GetConnectionSpec(); |
| 146 } | 166 } |
| 147 | 167 |
| 148 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, | 168 if (!AllowsInterface(params->source(), source_connection_spec, identity_, |
| 149 identity_, | 169 GetConnectionSpec(), params->interface_name())) { |
| 150 GetConnectionSpec()); | |
| 151 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || | |
| 152 exposed.count(params->interface_name()) > 0; | |
| 153 if (!allowed) { | |
| 154 std::stringstream ss; | |
| 155 ss << "Connection InterfaceProviderSpec prevented service: " | |
| 156 << params->source().name() << " from binding interface: " | |
| 157 << params->interface_name() << " exposed by: " << identity_.name(); | |
| 158 LOG(ERROR) << ss.str(); | |
| 159 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); | 170 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); |
| 160 return false; | 171 return false; |
| 161 } | 172 } |
| 162 | 173 |
| 163 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_); | 174 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_); |
| 164 | 175 |
| 165 pending_service_connections_++; | 176 pending_service_connections_++; |
| 166 service_->OnBindInterface( | 177 service_->OnBindInterface( |
| 167 ServiceInfo(params->source(), source_specs), | 178 ServiceInfo(params->source(), source_specs), |
| 168 params->interface_name(), | 179 params->interface_name(), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 219 |
| 209 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { | 220 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { |
| 210 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); | 221 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); |
| 211 info->id = id_; | 222 info->id = id_; |
| 212 info->identity = identity_; | 223 info->identity = identity_; |
| 213 info->pid = pid_; | 224 info->pid = pid_; |
| 214 return info; | 225 return info; |
| 215 } | 226 } |
| 216 | 227 |
| 217 const InterfaceProviderSpec& GetConnectionSpec() const { | 228 const InterfaceProviderSpec& GetConnectionSpec() const { |
| 218 auto it = interface_provider_specs_.find( | 229 return GetSpec(mojom::kServiceManager_ConnectorSpec); |
| 219 mojom::kServiceManager_ConnectorSpec); | 230 } |
| 231 bool HasSpec(const std::string& spec) const { |
| 232 auto it = interface_provider_specs_.find(spec); |
| 233 return it != interface_provider_specs_.end(); |
| 234 } |
| 235 const InterfaceProviderSpec& GetSpec(const std::string& spec) const { |
| 236 auto it = interface_provider_specs_.find(spec); |
| 220 return it != interface_provider_specs_.end() ? it->second : empty_spec_; | 237 return it != interface_provider_specs_.end() ? it->second : empty_spec_; |
| 221 } | 238 } |
| 239 |
| 222 const Identity& identity() const { return identity_; } | 240 const Identity& identity() const { return identity_; } |
| 223 void set_identity(const Identity& identity) { identity_ = identity; } | 241 void set_identity(const Identity& identity) { identity_ = identity; } |
| 224 uint32_t id() const { return id_; } | 242 uint32_t id() const { return id_; } |
| 225 | 243 |
| 226 // Service: | 244 // Service: |
| 227 void OnBindInterface(const ServiceInfo& source_info, | 245 void OnBindInterface(const ServiceInfo& source_info, |
| 228 const std::string& interface_name, | 246 const std::string& interface_name, |
| 229 mojo::ScopedMessagePipeHandle interface_pipe) override { | 247 mojo::ScopedMessagePipeHandle interface_pipe) override { |
| 230 Instance* source = | 248 Instance* source = |
| 231 service_manager_->GetExistingInstance(source_info.identity); | 249 service_manager_->GetExistingInstance(source_info.identity); |
| 232 DCHECK(source); | 250 DCHECK(source); |
| 233 if (interface_name == mojom::ServiceManager::Name_ && | 251 if (interface_name == mojom::ServiceManager::Name_ && |
| 234 HasCapability(source->GetConnectionSpec(), | 252 HasCapability(source->GetConnectionSpec(), |
| 235 kCapability_ServiceManager)) { | 253 kCapability_ServiceManager)) { |
| 236 mojom::ServiceManagerRequest request = | 254 mojom::ServiceManagerRequest request = |
| 237 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe)); | 255 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe)); |
| 238 service_manager_bindings_.AddBinding(this, std::move(request)); | 256 service_manager_bindings_.AddBinding(this, std::move(request)); |
| 239 } | 257 } |
| 240 } | 258 } |
| 241 | 259 |
| 242 private: | 260 private: |
| 243 enum class State { | 261 enum class State { |
| 244 // The service was not started yet. | 262 // The service was not started yet. |
| 245 IDLE, | 263 IDLE, |
| 246 | 264 |
| 247 // The service was started but the service manager hasn't received the | 265 // The service was started but the service manager hasn't received the |
| 248 // initial response from it yet. | 266 // initial response from it yet. |
| 249 STARTING, | 267 STARTING, |
| 250 | 268 |
| 251 // The service was started successfully. | 269 // The service was started successfully. |
| 252 STARTED | 270 STARTED |
| 253 }; | 271 }; |
| 254 | 272 |
| 273 class InterfaceProviderImpl : public mojom::InterfaceProvider { |
| 274 public: |
| 275 InterfaceProviderImpl(const std::string& spec, |
| 276 const Identity& source_identity, |
| 277 const Identity& target_identity, |
| 278 service_manager::ServiceManager* service_manager, |
| 279 mojom::InterfaceProviderPtr target, |
| 280 mojom::InterfaceProviderRequest source_request) |
| 281 : spec_(spec), |
| 282 source_identity_(source_identity), |
| 283 target_identity_(target_identity), |
| 284 service_manager_(service_manager), |
| 285 target_(std::move(target)), |
| 286 source_binding_(this, std::move(source_request)) {} |
| 287 ~InterfaceProviderImpl() override {} |
| 288 |
| 289 private: |
| 290 // mojom::InterfaceProvider: |
| 291 void GetInterface(const std::string& interface_name, |
| 292 mojo::ScopedMessagePipeHandle interface_pipe) override { |
| 293 Instance* source = |
| 294 service_manager_->GetExistingInstance(source_identity_); |
| 295 Instance* target = |
| 296 service_manager_->GetExistingInstance(target_identity_); |
| 297 if (!source || !target) |
| 298 return; |
| 299 if (!ValidateSpec(source) || !ValidateSpec(target)) |
| 300 return; |
| 301 |
| 302 if (AllowsInterface(source_identity_, source->GetSpec(spec_), |
| 303 target_identity_, target->GetSpec(spec_), |
| 304 interface_name)) { |
| 305 target_->GetInterface(interface_name, std::move(interface_pipe)); |
| 306 } |
| 307 } |
| 308 |
| 309 bool ValidateSpec(Instance* instance) const { |
| 310 if (!instance->HasSpec(spec_)) { |
| 311 LOG(ERROR) << "Instance for: " << instance->identity().name() |
| 312 << " did not have spec named: " << spec_; |
| 313 return false; |
| 314 } |
| 315 return true; |
| 316 } |
| 317 |
| 318 const std::string spec_; |
| 319 const Identity source_identity_; |
| 320 const Identity target_identity_; |
| 321 const service_manager::ServiceManager* service_manager_; |
| 322 |
| 323 mojom::InterfaceProviderPtr target_; |
| 324 mojo::Binding<mojom::InterfaceProvider> source_binding_; |
| 325 |
| 326 DISALLOW_COPY_AND_ASSIGN(InterfaceProviderImpl); |
| 327 }; |
| 328 |
| 255 // mojom::Connector implementation: | 329 // mojom::Connector implementation: |
| 256 void BindInterface(const service_manager::Identity& in_target, | 330 void BindInterface(const service_manager::Identity& in_target, |
| 257 const std::string& interface_name, | 331 const std::string& interface_name, |
| 258 mojo::ScopedMessagePipeHandle interface_pipe, | 332 mojo::ScopedMessagePipeHandle interface_pipe, |
| 259 const BindInterfaceCallback& callback) override { | 333 const BindInterfaceCallback& callback) override { |
| 260 Identity target = in_target; | 334 Identity target = in_target; |
| 261 mojom::ConnectResult result = | 335 mojom::ConnectResult result = |
| 262 ValidateConnectParams(&target, nullptr, nullptr); | 336 ValidateConnectParams(&target, nullptr, nullptr); |
| 263 if (!Succeeded(result)) { | 337 if (!Succeeded(result)) { |
| 264 callback.Run(result, Identity()); | 338 callback.Run(result, Identity()); |
| 265 return; | 339 return; |
| 266 } | 340 } |
| 267 | 341 |
| 268 std::unique_ptr<ConnectParams> params(new ConnectParams); | 342 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 269 params->set_source(identity_); | 343 params->set_source(identity_); |
| 270 params->set_target(target); | 344 params->set_target(target); |
| 271 params->set_interface_request_info(interface_name, | 345 params->set_interface_request_info(interface_name, |
| 272 std::move(interface_pipe)); | 346 std::move(interface_pipe)); |
| 273 params->set_start_service_callback(callback); | 347 params->set_start_service_callback(callback); |
| 274 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 348 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); |
| 275 } | 349 } |
| 276 | 350 |
| 277 void StartService(const Identity& in_target, | 351 void StartService(const Identity& in_target, |
| 278 const StartServiceCallback& callback) override { | 352 const StartServiceCallback& callback) override { |
| 279 Identity target = in_target; | 353 Identity target = in_target; |
| 280 mojom::ConnectResult result = | 354 mojom::ConnectResult result = |
| 281 ValidateConnectParams(&target, nullptr, nullptr); | 355 ValidateConnectParams(&target, nullptr, nullptr); |
| 282 if (!Succeeded(result)) { | 356 if (!Succeeded(result)) { |
| 283 callback.Run(result, Identity()); | 357 callback.Run(result, Identity()); |
| 284 return; | 358 return; |
| 285 } | 359 } |
| 286 | 360 |
| 287 std::unique_ptr<ConnectParams> params(new ConnectParams); | 361 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 288 params->set_source(identity_); | 362 params->set_source(identity_); |
| 289 params->set_target(target); | 363 params->set_target(target); |
| 290 params->set_start_service_callback(callback); | 364 params->set_start_service_callback(callback); |
| 291 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 365 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); |
| 292 } | 366 } |
| 293 | 367 |
| 294 void StartServiceWithProcess( | 368 void StartServiceWithProcess( |
| 295 const Identity& in_target, | 369 const Identity& in_target, |
| 296 mojo::ScopedMessagePipeHandle service_handle, | 370 mojo::ScopedMessagePipeHandle service_handle, |
| 297 mojom::PIDReceiverRequest pid_receiver_request, | 371 mojom::PIDReceiverRequest pid_receiver_request, |
| 298 const StartServiceWithProcessCallback& callback) override { | 372 const StartServiceWithProcessCallback& callback) override { |
| 299 Identity target = in_target; | 373 Identity target = in_target; |
| 300 mojom::ConnectResult result = | 374 mojom::ConnectResult result = |
| 301 ValidateConnectParams(&target, nullptr, nullptr); | 375 ValidateConnectParams(&target, nullptr, nullptr); |
| 302 if (!Succeeded(result)) { | 376 if (!Succeeded(result)) { |
| 303 callback.Run(result, Identity()); | 377 callback.Run(result, Identity()); |
| 304 return; | 378 return; |
| 305 } | 379 } |
| 306 | 380 |
| 307 std::unique_ptr<ConnectParams> params(new ConnectParams); | 381 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 308 params->set_source(identity_); | 382 params->set_source(identity_); |
| 309 params->set_target(target); | 383 params->set_target(target); |
| 310 | 384 |
| 311 mojom::ServicePtr service; | 385 mojom::ServicePtr service; |
| 312 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); | 386 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); |
| 313 params->set_client_process_info(std::move(service), | 387 params->set_client_process_info(std::move(service), |
| 314 std::move(pid_receiver_request)); | 388 std::move(pid_receiver_request)); |
| 315 params->set_start_service_callback(callback); | 389 params->set_start_service_callback(callback); |
| 316 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 390 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); |
| 317 } | 391 } |
| 318 | 392 |
| 319 void Clone(mojom::ConnectorRequest request) override { | 393 void Clone(mojom::ConnectorRequest request) override { |
| 320 connectors_.AddBinding(this, std::move(request)); | 394 connectors_.AddBinding(this, std::move(request)); |
| 321 } | 395 } |
| 322 | 396 |
| 397 void FilterInterfaces(const std::string& spec, |
| 398 const Identity& source, |
| 399 mojom::InterfaceProviderRequest source_request, |
| 400 mojom::InterfaceProviderPtr target) override { |
| 401 filters_.push_back(base::MakeUnique<InterfaceProviderImpl>( |
| 402 spec, source, identity_, service_manager_, std::move(target), |
| 403 std::move(source_request))); |
| 404 } |
| 405 |
| 323 // mojom::PIDReceiver: | 406 // mojom::PIDReceiver: |
| 324 void SetPID(uint32_t pid) override { | 407 void SetPID(uint32_t pid) override { |
| 325 PIDAvailable(pid); | 408 PIDAvailable(pid); |
| 326 } | 409 } |
| 327 | 410 |
| 328 // mojom::ServiceManager implementation: | 411 // mojom::ServiceManager implementation: |
| 329 void AddListener(mojom::ServiceManagerListenerPtr listener) override { | 412 void AddListener(mojom::ServiceManagerListenerPtr listener) override { |
| 330 // TODO(beng): this should only track the instances matching this user, and | 413 // TODO(beng): this should only track the instances matching this user, and |
| 331 // root. | 414 // root. |
| 332 service_manager_->AddListener(std::move(listener)); | 415 service_manager_->AddListener(std::move(listener)); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 const bool allow_any_application_; | 576 const bool allow_any_application_; |
| 494 std::unique_ptr<ServiceProcessLauncher> runner_; | 577 std::unique_ptr<ServiceProcessLauncher> runner_; |
| 495 mojom::ServicePtr service_; | 578 mojom::ServicePtr service_; |
| 496 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; | 579 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; |
| 497 mojo::BindingSet<mojom::Connector> connectors_; | 580 mojo::BindingSet<mojom::Connector> connectors_; |
| 498 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; | 581 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; |
| 499 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; | 582 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; |
| 500 base::ProcessId pid_ = base::kNullProcessId; | 583 base::ProcessId pid_ = base::kNullProcessId; |
| 501 State state_; | 584 State state_; |
| 502 | 585 |
| 586 std::vector<std::unique_ptr<InterfaceProviderImpl>> filters_; |
| 587 |
| 503 // The number of outstanding OnBindInterface requests which are in flight. | 588 // The number of outstanding OnBindInterface requests which are in flight. |
| 504 int pending_service_connections_ = 0; | 589 int pending_service_connections_ = 0; |
| 505 | 590 |
| 506 base::WeakPtrFactory<Instance> weak_factory_; | 591 base::WeakPtrFactory<Instance> weak_factory_; |
| 507 | 592 |
| 508 DISALLOW_COPY_AND_ASSIGN(Instance); | 593 DISALLOW_COPY_AND_ASSIGN(Instance); |
| 509 }; | 594 }; |
| 510 | 595 |
| 511 class ServiceManager::ServiceImpl : public Service { | 596 class ServiceManager::ServiceImpl : public Service { |
| 512 public: | 597 public: |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 instance->identity()); | 1085 instance->identity()); |
| 1001 if (params->HasInterfaceRequestInfo()) | 1086 if (params->HasInterfaceRequestInfo()) |
| 1002 instance->CallOnBindInterface(¶ms); | 1087 instance->CallOnBindInterface(¶ms); |
| 1003 } | 1088 } |
| 1004 | 1089 |
| 1005 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 1090 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
| 1006 return weak_ptr_factory_.GetWeakPtr(); | 1091 return weak_ptr_factory_.GetWeakPtr(); |
| 1007 } | 1092 } |
| 1008 | 1093 |
| 1009 } // namespace service_manager | 1094 } // namespace service_manager |
| OLD | NEW |