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

Unified Diff: services/service_manager/service_manager.cc

Issue 2440903002: Make "all user" services work when packaged. (Closed)
Patch Set: Addressed latest comments and synced. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/service_manager/service_manager.h ('k') | services/service_manager/standalone/context.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/service_manager/service_manager.cc
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc
index 6479d3950b021b29363e73bdd1a7ae597773a5c7..e8f1f9a1dd426b2d95ce66b19889a15af22e87b2 100644
--- a/services/service_manager/service_manager.cc
+++ b/services/service_manager/service_manager.cc
@@ -39,6 +39,8 @@ const char kCapability_UserID[] = "service_manager:user_id";
const char kCapability_ClientProcess[] = "service_manager:client_process";
const char kCapability_InstanceName[] = "service_manager:instance_name";
const char kCapability_AllUsers[] = "service_manager:all_users";
+const char kCapability_InstancePerChild[] =
+ "service_manager:instance_per_child";
const char kCapability_ServiceManager[] = "service_manager:service_manager";
} // namespace
@@ -85,6 +87,7 @@ class ServiceManager::Instance
interface_provider_specs_(interface_provider_specs),
allow_any_application_(GetConnectionSpec().requires.count("*") == 1),
pid_receiver_binding_(this),
+ state_(State::IDLE),
weak_factory_(this) {
if (identity_.name() == kServiceManagerName ||
identity_.name() == kCatalogName) {
@@ -103,8 +106,12 @@ class ServiceManager::Instance
connectors_.CloseAllBindings();
service_manager_bindings_.CloseAllBindings();
- // Notify the ServiceManager that this Instance is really going away.
- service_manager_->OnInstanceStopped(identity_);
+ if (state_ == State::STARTING) {
+ service_manager_->NotifyServiceFailedToStart(identity_);
+ } else {
+ // Notify the ServiceManager that this Instance is really going away.
+ service_manager_->OnInstanceStopped(identity_);
+ }
// Release |runner_| so that if we are called back to OnRunnerCompleted()
// we know we're in the destructor.
@@ -112,7 +119,7 @@ class ServiceManager::Instance
runner.reset();
}
- Instance* parent() { return parent_; }
+ Instance* parent() const { return parent_; }
void AddChild(std::unique_ptr<Instance> child) {
child->parent_ = this;
@@ -148,6 +155,7 @@ class ServiceManager::Instance
void StartWithService(mojom::ServicePtr service) {
CHECK(!service_);
+ state_ = State::STARTING;
service_ = std::move(service);
service_.set_connection_error_handler(
base::Bind(&Instance::OnServiceLost, base::Unretained(this),
@@ -192,6 +200,7 @@ class ServiceManager::Instance
return it != interface_provider_specs_.end() ? it->second : empty_spec_;
}
const Identity& identity() const { return identity_; }
+ void set_identity(const Identity& identity) { identity_ = identity; }
uint32_t id() const { return id_; }
// Service:
@@ -209,6 +218,18 @@ class ServiceManager::Instance
}
private:
+ enum class State {
+ // The service was not started yet.
+ IDLE,
+
+ // The service was started but the service manager hasn't received the
+ // initial response from it yet.
+ STARTING,
+
+ // The service was started successfully.
+ STARTED
+ };
+
// mojom::Connector implementation:
void Connect(const service_manager::Identity& in_target,
mojom::InterfaceProviderRequest remote_interfaces,
@@ -367,7 +388,6 @@ class ServiceManager::Instance
return;
}
pid_ = pid;
- service_manager_->NotifyPIDAvailable(identity_, pid_);
}
void OnServiceLost(
@@ -389,12 +409,14 @@ class ServiceManager::Instance
}
void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
+ state_ = State::STARTED;
if (connector_request.is_pending()) {
connectors_.AddBinding(this, std::move(connector_request));
connectors_.set_connection_error_handler(
base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
service_manager_->GetWeakPtr()));
}
+ service_manager_->NotifyServiceStarted(identity_, pid_);
}
// Callback when NativeRunner completes.
@@ -411,7 +433,7 @@ class ServiceManager::Instance
// may vend multiple application instances, and this object may exist before a
// process is launched.
const uint32_t id_;
- const Identity identity_;
+ Identity identity_;
const InterfaceProviderSpecMap interface_provider_specs_;
const InterfaceProviderSpec empty_spec_;
const bool allow_any_application_;
@@ -423,6 +445,7 @@ class ServiceManager::Instance
base::ProcessId pid_ = base::kNullProcessId;
Instance* parent_ = nullptr;
InstanceMap children_;
+ State state_;
base::WeakPtrFactory<Instance> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Instance);
@@ -649,14 +672,21 @@ ServiceManager::Instance* ServiceManager::GetExistingInstance(
return nullptr;
}
-void ServiceManager::NotifyPIDAvailable(const Identity& identity,
- base::ProcessId pid) {
+void ServiceManager::NotifyServiceStarted(const Identity& identity,
+ base::ProcessId pid) {
listeners_.ForAllPtrs(
[identity, pid](mojom::ServiceManagerListener* listener) {
listener->OnServiceStarted(identity, pid);
});
}
+void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) {
+ listeners_.ForAllPtrs(
+ [identity](mojom::ServiceManagerListener* listener) {
+ listener->OnServiceFailedToStart(identity);
+ });
+}
+
bool ServiceManager::ConnectToExistingInstance(
std::unique_ptr<ConnectParams>* params) {
Instance* instance = GetExistingInstance((*params)->target());
@@ -759,6 +789,7 @@ void ServiceManager::OnGotResolvedName(std::unique_ptr<ConnectParams> params,
if (it != result->interface_provider_specs.end())
connection_spec = it->second;
+ const Identity original_target(params->target());
const std::string user_id =
HasCapability(connection_spec, kCapability_AllUsers)
? base::GenerateGUID() : params->target().user_id();
@@ -819,9 +850,28 @@ void ServiceManager::OnGotResolvedName(std::unique_ptr<ConnectParams> params,
}
if (target.name() != result->resolved_name) {
+ // This service is part of a package.
+ std::string target_user_id = target.user_id();
+ std::string factory_instance_name = instance_name;
+ bool instance_per_child = result->package_spec.has_value() &&
+ HasCapability(result->package_spec.value(),
+ kCapability_InstancePerChild);
+ if (instance_per_child) {
+ // If configured to start a new instance, create a random instance name
+ // for the factory so that we don't reuse an existing process.
+ factory_instance_name = base::GenerateGUID();
+ } else {
+ // Use the original user ID so the existing embedder factory can
+ // be found and used to create the new service.
+ target_user_id = original_target.user_id();
+ Identity packaged_service_target(target);
+ packaged_service_target.set_user_id(original_target.user_id());
+ instance->set_identity(packaged_service_target);
+ }
instance->StartWithService(std::move(service));
- Identity factory(result->resolved_name, target.user_id(),
- instance_name);
+
+ Identity factory(result->resolved_name, target_user_id,
+ factory_instance_name);
CreateServiceWithFactory(factory, target.name(), std::move(request));
} else {
base::FilePath package_path;
« no previous file with comments | « services/service_manager/service_manager.h ('k') | services/service_manager/standalone/context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698