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

Side by Side Diff: services/service_manager/service_manager.cc

Issue 2610853013: Perform InterfaceProviderSpec intersection in the ServiceManager (Closed)
Patch Set: . Created 3 years, 11 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 unified diff | Download patch
« no previous file with comments | « services/service_manager/public/interfaces/service.mojom ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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(&params); 1063 if (params->HasInterfaceRequestInfo()) {
994 DCHECK(connected); 1064 instance->OnBindInterface(&params);
1065 } else {
1066 bool connected = instance->OnConnect(&params);
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
OLDNEW
« no previous file with comments | « services/service_manager/public/interfaces/service.mojom ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698