| 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/debug/alias.h" |   13 #include "base/debug/alias.h" | 
|   14 #include "base/guid.h" |   14 #include "base/guid.h" | 
|   15 #include "base/logging.h" |   15 #include "base/logging.h" | 
|   16 #include "base/macros.h" |   16 #include "base/macros.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" |  | 
|   23 #include "mojo/public/cpp/bindings/binding.h" |   22 #include "mojo/public/cpp/bindings/binding.h" | 
|   24 #include "mojo/public/cpp/bindings/binding_set.h" |   23 #include "mojo/public/cpp/bindings/binding_set.h" | 
|   25 #include "services/service_manager/connect_util.h" |   24 #include "services/service_manager/connect_util.h" | 
|   26 #include "services/service_manager/public/cpp/connector.h" |   25 #include "services/service_manager/public/cpp/connector.h" | 
|   27 #include "services/service_manager/public/cpp/interface_registry.h" |   26 #include "services/service_manager/public/cpp/interface_registry.h" | 
|   28 #include "services/service_manager/public/cpp/names.h" |   27 #include "services/service_manager/public/cpp/names.h" | 
|   29 #include "services/service_manager/public/cpp/service.h" |   28 #include "services/service_manager/public/cpp/service.h" | 
|   30 #include "services/service_manager/public/cpp/service_context.h" |   29 #include "services/service_manager/public/cpp/service_context.h" | 
|   31 #include "services/service_manager/public/interfaces/connector.mojom.h" |   30 #include "services/service_manager/public/interfaces/connector.mojom.h" | 
|   32 #include "services/service_manager/public/interfaces/service.mojom.h" |   31 #include "services/service_manager/public/interfaces/service.mojom.h" | 
|   33 #include "services/service_manager/public/interfaces/service_control.mojom.h" |  | 
|   34 #include "services/service_manager/public/interfaces/service_manager.mojom.h" |   32 #include "services/service_manager/public/interfaces/service_manager.mojom.h" | 
|   35  |   33  | 
|   36 namespace service_manager { |   34 namespace service_manager { | 
|   37  |   35  | 
|   38 namespace { |   36 namespace { | 
|   39  |   37  | 
|   40 const char kCatalogName[] = "service:catalog"; |   38 const char kCatalogName[] = "service:catalog"; | 
|   41 const char kServiceManagerName[] = "service:service_manager"; |   39 const char kServiceManagerName[] = "service:service_manager"; | 
|   42 const char kCapability_UserID[] = "service_manager:user_id"; |   40 const char kCapability_UserID[] = "service_manager:user_id"; | 
|   43 const char kCapability_ClientProcess[] = "service_manager:client_process"; |   41 const char kCapability_ClientProcess[] = "service_manager:client_process"; | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|   73   return it->second.find(capability) != it->second.end(); |   71   return it->second.find(capability) != it->second.end(); | 
|   74 } |   72 } | 
|   75  |   73  | 
|   76 // Encapsulates a connection to an instance of a service, tracked by the |   74 // Encapsulates a connection to an instance of a service, tracked by the | 
|   77 // Service Manager. |   75 // Service Manager. | 
|   78 class ServiceManager::Instance |   76 class ServiceManager::Instance | 
|   79     : public mojom::Connector, |   77     : public mojom::Connector, | 
|   80       public mojom::PIDReceiver, |   78       public mojom::PIDReceiver, | 
|   81       public Service, |   79       public Service, | 
|   82       public InterfaceFactory<mojom::ServiceManager>, |   80       public InterfaceFactory<mojom::ServiceManager>, | 
|   83       public mojom::ServiceManager, |   81       public mojom::ServiceManager { | 
|   84       public mojom::ServiceControl { |  | 
|   85  public: |   82  public: | 
|   86   Instance(service_manager::ServiceManager* service_manager, |   83   Instance(service_manager::ServiceManager* service_manager, | 
|   87            const Identity& identity, |   84            const Identity& identity, | 
|   88            const InterfaceProviderSpecMap& interface_provider_specs) |   85            const InterfaceProviderSpecMap& interface_provider_specs) | 
|   89       : service_manager_(service_manager), |   86       : service_manager_(service_manager), | 
|   90         id_(GenerateUniqueID()), |   87         id_(GenerateUniqueID()), | 
|   91         identity_(identity), |   88         identity_(identity), | 
|   92         interface_provider_specs_(interface_provider_specs), |   89         interface_provider_specs_(interface_provider_specs), | 
|   93         allow_any_application_(GetConnectionSpec().requires.count("*") == 1), |   90         allow_any_application_(GetConnectionSpec().requires.count("*") == 1), | 
|   94         pid_receiver_binding_(this), |   91         pid_receiver_binding_(this), | 
|   95         control_binding_(this), |  | 
|   96         state_(State::IDLE), |   92         state_(State::IDLE), | 
|   97         weak_factory_(this) { |   93         weak_factory_(this) { | 
|   98     if (identity_.name() == kServiceManagerName || |   94     if (identity_.name() == kServiceManagerName || | 
|   99         identity_.name() == kCatalogName) { |   95         identity_.name() == kCatalogName) { | 
|  100       pid_ = base::Process::Current().Pid(); |   96       pid_ = base::Process::Current().Pid(); | 
|  101     } |   97     } | 
|  102     DCHECK_NE(mojom::kInvalidInstanceID, id_); |   98     DCHECK_NE(mojom::kInvalidInstanceID, id_); | 
|  103   } |   99   } | 
|  104  |  100  | 
|  105   ~Instance() override { |  101   ~Instance() override { | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  148     std::unique_ptr<ConnectParams> params(std::move(*connect_params)); |  144     std::unique_ptr<ConnectParams> params(std::move(*connect_params)); | 
|  149     if (!params->connect_callback().is_null()) { |  145     if (!params->connect_callback().is_null()) { | 
|  150         params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |  146         params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 
|  151                                        identity_.user_id()); |  147                                        identity_.user_id()); | 
|  152     } |  148     } | 
|  153  |  149  | 
|  154     InterfaceProviderSpecMap specs; |  150     InterfaceProviderSpecMap specs; | 
|  155     Instance* source = service_manager_->GetExistingInstance(params->source()); |  151     Instance* source = service_manager_->GetExistingInstance(params->source()); | 
|  156     if (source) |  152     if (source) | 
|  157       specs = source->interface_provider_specs_; |  153       specs = source->interface_provider_specs_; | 
|  158  |  | 
|  159     pending_service_connections_++; |  | 
|  160     service_->OnConnect(ServiceInfo(params->source(), specs), |  154     service_->OnConnect(ServiceInfo(params->source(), specs), | 
|  161                         params->TakeRemoteInterfaces(), |  155                         params->TakeRemoteInterfaces()); | 
|  162                         base::Bind(&Instance::OnConnectComplete, |  | 
|  163                                    base::Unretained(this))); |  | 
|  164     return true; |  156     return true; | 
|  165   } |  157   } | 
|  166  |  158  | 
|  167   void OnConnectComplete() { |  | 
|  168     DCHECK_GT(pending_service_connections_, 0); |  | 
|  169     pending_service_connections_--; |  | 
|  170   } |  | 
|  171  |  | 
|  172   void StartWithService(mojom::ServicePtr service) { |  159   void StartWithService(mojom::ServicePtr service) { | 
|  173     CHECK(!service_); |  160     CHECK(!service_); | 
|  174     state_ = State::STARTING; |  161     state_ = State::STARTING; | 
|  175     service_ = std::move(service); |  162     service_ = std::move(service); | 
|  176     service_.set_connection_error_handler( |  163     service_.set_connection_error_handler( | 
|  177         base::Bind(&Instance::OnServiceLost, base::Unretained(this), |  164         base::Bind(&Instance::OnServiceLost, base::Unretained(this), | 
|  178                    service_manager_->GetWeakPtr())); |  165                    service_manager_->GetWeakPtr())); | 
|  179     service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), |  166     service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), | 
|  180                       base::Bind(&Instance::OnStartComplete, |  167                       base::Bind(&Instance::OnInitializeResponse, | 
|  181                                  base::Unretained(this))); |  168                                  base::Unretained(this))); | 
|  182   } |  169   } | 
|  183  |  170  | 
|  184   void StartWithClientProcessConnection( |  171   void StartWithClientProcessConnection( | 
|  185       mojom::ClientProcessConnectionPtr client_process_connection) { |  172       mojom::ClientProcessConnectionPtr client_process_connection) { | 
|  186     mojom::ServicePtr service; |  173     mojom::ServicePtr service; | 
|  187     service.Bind(mojom::ServicePtrInfo( |  174     service.Bind(mojom::ServicePtrInfo( | 
|  188         std::move(client_process_connection->service), 0)); |  175         std::move(client_process_connection->service), 0)); | 
|  189     pid_receiver_binding_.Bind( |  176     pid_receiver_binding_.Bind( | 
|  190         std::move(client_process_connection->pid_receiver_request)); |  177         std::move(client_process_connection->pid_receiver_request)); | 
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  417     // Any time a Connector is lost or we lose the Service connection, it |  404     // Any time a Connector is lost or we lose the Service connection, it | 
|  418     // may have been the last pipe using this Instance. If so, clean up. |  405     // may have been the last pipe using this Instance. If so, clean up. | 
|  419     if (service_manager && !service_) { |  406     if (service_manager && !service_) { | 
|  420       if (connectors_.empty()) |  407       if (connectors_.empty()) | 
|  421         service_manager->OnInstanceError(this); |  408         service_manager->OnInstanceError(this); | 
|  422       else |  409       else | 
|  423         service_manager->OnInstanceUnreachable(this); |  410         service_manager->OnInstanceUnreachable(this); | 
|  424     } |  411     } | 
|  425   } |  412   } | 
|  426  |  413  | 
|  427   void OnStartComplete(mojom::ConnectorRequest connector_request, |  414   void OnInitializeResponse(mojom::ConnectorRequest connector_request) { | 
|  428                        mojom::ServiceControlAssociatedRequest control_request) { |  | 
|  429     state_ = State::STARTED; |  415     state_ = State::STARTED; | 
|  430     if (connector_request.is_pending()) { |  416     if (connector_request.is_pending()) { | 
|  431       connectors_.AddBinding(this, std::move(connector_request)); |  417       connectors_.AddBinding(this, std::move(connector_request)); | 
|  432       connectors_.set_connection_error_handler( |  418       connectors_.set_connection_error_handler( | 
|  433           base::Bind(&Instance::OnConnectionLost, base::Unretained(this), |  419           base::Bind(&Instance::OnConnectionLost, base::Unretained(this), | 
|  434                      service_manager_->GetWeakPtr())); |  420                      service_manager_->GetWeakPtr())); | 
|  435     } |  421     } | 
|  436     if (control_request.is_pending()) |  | 
|  437       control_binding_.Bind(std::move(control_request)); |  | 
|  438     service_manager_->NotifyServiceStarted(identity_, pid_); |  422     service_manager_->NotifyServiceStarted(identity_, pid_); | 
|  439   } |  423   } | 
|  440  |  424  | 
|  441   // Callback when NativeRunner completes. |  425   // Callback when NativeRunner completes. | 
|  442   void OnRunnerCompleted() { |  426   void OnRunnerCompleted() { | 
|  443     if (!runner_.get()) |  427     if (!runner_.get()) | 
|  444       return;  // We're in the destructor. |  428       return;  // We're in the destructor. | 
|  445  |  429  | 
|  446     service_manager_->OnInstanceError(this); |  430     service_manager_->OnInstanceError(this); | 
|  447   } |  431   } | 
|  448  |  432  | 
|  449   // mojom::ServiceControl: |  | 
|  450   void RequestQuit() override { |  | 
|  451     // If quit is requested, oblige when there are no pending OnConnects. |  | 
|  452     if (!pending_service_connections_) |  | 
|  453       OnServiceLost(service_manager_->GetWeakPtr()); |  | 
|  454   } |  | 
|  455  |  | 
|  456   service_manager::ServiceManager* const service_manager_; |  433   service_manager::ServiceManager* const service_manager_; | 
|  457  |  434  | 
|  458   // An id that identifies this instance. Distinct from pid, as a single process |  435   // An id that identifies this instance. Distinct from pid, as a single process | 
|  459   // may vend multiple application instances, and this object may exist before a |  436   // may vend multiple application instances, and this object may exist before a | 
|  460   // process is launched. |  437   // process is launched. | 
|  461   const uint32_t id_; |  438   const uint32_t id_; | 
|  462   Identity identity_; |  439   Identity identity_; | 
|  463   const InterfaceProviderSpecMap interface_provider_specs_; |  440   const InterfaceProviderSpecMap interface_provider_specs_; | 
|  464   const InterfaceProviderSpec empty_spec_; |  441   const InterfaceProviderSpec empty_spec_; | 
|  465   const bool allow_any_application_; |  442   const bool allow_any_application_; | 
|  466   std::unique_ptr<NativeRunner> runner_; |  443   std::unique_ptr<NativeRunner> runner_; | 
|  467   mojom::ServicePtr service_; |  444   mojom::ServicePtr service_; | 
|  468   mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; |  445   mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; | 
|  469   mojo::BindingSet<mojom::Connector> connectors_; |  446   mojo::BindingSet<mojom::Connector> connectors_; | 
|  470   mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; |  447   mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; | 
|  471   mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; |  | 
|  472   base::ProcessId pid_ = base::kNullProcessId; |  448   base::ProcessId pid_ = base::kNullProcessId; | 
|  473   Instance* parent_ = nullptr; |  449   Instance* parent_ = nullptr; | 
|  474   InstanceMap children_; |  450   InstanceMap children_; | 
|  475   State state_; |  451   State state_; | 
|  476  |  | 
|  477   // The number of outstanding OnConnect requests which are in flight. |  | 
|  478   int pending_service_connections_ = 0; |  | 
|  479  |  | 
|  480   base::WeakPtrFactory<Instance> weak_factory_; |  452   base::WeakPtrFactory<Instance> weak_factory_; | 
|  481  |  453  | 
|  482   DISALLOW_COPY_AND_ASSIGN(Instance); |  454   DISALLOW_COPY_AND_ASSIGN(Instance); | 
|  483 }; |  455 }; | 
|  484  |  456  | 
|  485 class ServiceManager::ServiceImpl : public Service { |  457 class ServiceManager::ServiceImpl : public Service { | 
|  486  public: |  458  public: | 
|  487   explicit ServiceImpl(ServiceManager* service_manager) |  459   explicit ServiceImpl(ServiceManager* service_manager) | 
|  488       : service_manager_(service_manager) {} |  460       : service_manager_(service_manager) {} | 
|  489   ~ServiceImpl() override {} |  461   ~ServiceImpl() override {} | 
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  943   // Now that the instance has a Service, we can connect to it. |  915   // Now that the instance has a Service, we can connect to it. | 
|  944   bool connected = instance->ConnectToService(¶ms); |  916   bool connected = instance->ConnectToService(¶ms); | 
|  945   DCHECK(connected); |  917   DCHECK(connected); | 
|  946 } |  918 } | 
|  947  |  919  | 
|  948 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |  920 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 
|  949   return weak_ptr_factory_.GetWeakPtr(); |  921   return weak_ptr_factory_.GetWeakPtr(); | 
|  950 } |  922 } | 
|  951  |  923  | 
|  952 }  // namespace service_manager |  924 }  // namespace service_manager | 
| OLD | NEW |