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/public/cpp/service_context.h" | 5 #include "services/service_manager/public/cpp/service_context.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 connector_(std::move(connector)), | 35 connector_(std::move(connector)), |
36 weak_factory_(this) { | 36 weak_factory_(this) { |
37 DCHECK(binding_.is_bound()); | 37 DCHECK(binding_.is_bound()); |
38 binding_.set_connection_error_handler( | 38 binding_.set_connection_error_handler( |
39 base::Bind(&ServiceContext::OnConnectionError, base::Unretained(this))); | 39 base::Bind(&ServiceContext::OnConnectionError, base::Unretained(this))); |
40 if (!connector_) { | 40 if (!connector_) { |
41 connector_ = Connector::Create(&pending_connector_request_); | 41 connector_ = Connector::Create(&pending_connector_request_); |
42 } else { | 42 } else { |
43 DCHECK(pending_connector_request_.is_pending()); | 43 DCHECK(pending_connector_request_.is_pending()); |
44 } | 44 } |
| 45 service_->SetContext(this); |
45 } | 46 } |
46 | 47 |
47 ServiceContext::~ServiceContext() {} | 48 ServiceContext::~ServiceContext() {} |
48 | 49 |
49 void ServiceContext::SetConnectionLostClosure(const base::Closure& closure) { | 50 void ServiceContext::SetQuitClosure(const base::Closure& closure) { |
50 connection_lost_closure_ = closure; | 51 if (service_quit_) { |
51 if (service_quit_) | 52 // CAUTION: May delete |this|. |
52 QuitNow(); | 53 closure.Run(); |
| 54 } else { |
| 55 quit_closure_ = closure; |
| 56 } |
53 } | 57 } |
54 | 58 |
55 void ServiceContext::RequestQuit() { | 59 void ServiceContext::RequestQuit() { |
56 DCHECK(service_control_.is_bound()); | 60 DCHECK(service_control_.is_bound()); |
57 service_control_->RequestQuit(); | 61 service_control_->RequestQuit(); |
58 } | 62 } |
59 | 63 |
60 void ServiceContext::DisconnectFromServiceManager() { | 64 void ServiceContext::DisconnectFromServiceManager() { |
61 if (binding_.is_bound()) | 65 if (binding_.is_bound()) |
62 binding_.Close(); | 66 binding_.Close(); |
63 connector_.reset(); | 67 connector_.reset(); |
64 } | 68 } |
65 | 69 |
66 void ServiceContext::QuitNow() { | 70 void ServiceContext::QuitNow() { |
| 71 service_quit_ = true; |
67 if (binding_.is_bound()) | 72 if (binding_.is_bound()) |
68 binding_.Close(); | 73 binding_.Close(); |
69 if (!connection_lost_closure_.is_null()) | 74 if (!quit_closure_.is_null()) { |
70 base::ResetAndReturn(&connection_lost_closure_).Run(); | 75 // CAUTION: May delete |this|. |
71 } | 76 base::ResetAndReturn(&quit_closure_).Run(); |
72 | 77 } |
73 void ServiceContext::DestroyService() { | |
74 QuitNow(); | |
75 service_.reset(); | |
76 } | 78 } |
77 | 79 |
78 //////////////////////////////////////////////////////////////////////////////// | 80 //////////////////////////////////////////////////////////////////////////////// |
79 // ServiceContext, mojom::Service implementation: | 81 // ServiceContext, mojom::Service implementation: |
80 | 82 |
81 void ServiceContext::OnStart(const ServiceInfo& info, | 83 void ServiceContext::OnStart(const ServiceInfo& info, |
82 const OnStartCallback& callback) { | 84 const OnStartCallback& callback) { |
83 local_info_ = info; | 85 local_info_ = info; |
84 callback.Run(std::move(pending_connector_request_), | 86 callback.Run(std::move(pending_connector_request_), |
85 mojo::MakeRequest(&service_control_)); | 87 mojo::MakeRequest(&service_control_)); |
86 | |
87 service_->set_context(this); | |
88 service_->OnStart(); | 88 service_->OnStart(); |
89 } | 89 } |
90 | 90 |
91 void ServiceContext::OnConnect( | 91 void ServiceContext::OnConnect( |
92 const ServiceInfo& source_info, | 92 const ServiceInfo& source_info, |
93 mojom::InterfaceProviderRequest interfaces, | 93 mojom::InterfaceProviderRequest interfaces, |
94 const OnConnectCallback& callback) { | 94 const OnConnectCallback& callback) { |
95 InterfaceProviderSpec source_spec, target_spec; | 95 InterfaceProviderSpec source_spec, target_spec; |
96 GetInterfaceProviderSpec(mojom::kServiceManager_ConnectorSpec, | 96 GetInterfaceProviderSpec(mojom::kServiceManager_ConnectorSpec, |
97 local_info_.interface_provider_specs, &target_spec); | 97 local_info_.interface_provider_specs, &target_spec); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 133 |
134 InterfaceRegistry* raw_registry = registry.get(); | 134 InterfaceRegistry* raw_registry = registry.get(); |
135 registry->AddConnectionLostClosure(base::Bind( | 135 registry->AddConnectionLostClosure(base::Bind( |
136 &ServiceContext::OnRegistryConnectionError, base::Unretained(this), | 136 &ServiceContext::OnRegistryConnectionError, base::Unretained(this), |
137 raw_registry)); | 137 raw_registry)); |
138 connection_interface_registries_.insert( | 138 connection_interface_registries_.insert( |
139 std::make_pair(raw_registry, std::move(registry))); | 139 std::make_pair(raw_registry, std::move(registry))); |
140 } | 140 } |
141 | 141 |
142 void ServiceContext::OnConnectionError() { | 142 void ServiceContext::OnConnectionError() { |
143 // Note that the Service doesn't technically have to quit now, it may live | 143 if (service_->OnServiceManagerConnectionLost()) { |
144 // on to service existing connections. All existing Connectors however are | 144 // CAUTION: May delete |this|. |
145 // invalid. | |
146 service_quit_ = service_->OnStop(); | |
147 if (service_quit_) { | |
148 QuitNow(); | 145 QuitNow(); |
149 // NOTE: This call may delete |this|, so don't access any ServiceContext | |
150 // state beyond this point. | |
151 return; | |
152 } | 146 } |
153 | |
154 // We don't reset the connector as clients may have taken a raw pointer to it. | |
155 // Connect() will return nullptr if they try to connect to anything. | |
156 } | 147 } |
157 | 148 |
158 void ServiceContext::OnRegistryConnectionError(InterfaceRegistry* registry) { | 149 void ServiceContext::OnRegistryConnectionError(InterfaceRegistry* registry) { |
159 // NOTE: We destroy the InterfaceRegistry asynchronously since it's calling | 150 // NOTE: We destroy the InterfaceRegistry asynchronously since it's calling |
160 // into us from its own connection error handler which may continue to access | 151 // into us from its own connection error handler which may continue to access |
161 // the InterfaceRegistry's own state after we return. | 152 // the InterfaceRegistry's own state after we return. |
162 base::ThreadTaskRunnerHandle::Get()->PostTask( | 153 base::ThreadTaskRunnerHandle::Get()->PostTask( |
163 FROM_HERE, | 154 FROM_HERE, |
164 base::Bind(&ServiceContext::DestroyConnectionInterfaceRegistry, | 155 base::Bind(&ServiceContext::DestroyConnectionInterfaceRegistry, |
165 weak_factory_.GetWeakPtr(), registry)); | 156 weak_factory_.GetWeakPtr(), registry)); |
166 } | 157 } |
167 | 158 |
168 void ServiceContext::DestroyConnectionInterfaceRegistry( | 159 void ServiceContext::DestroyConnectionInterfaceRegistry( |
169 InterfaceRegistry* registry) { | 160 InterfaceRegistry* registry) { |
170 auto it = connection_interface_registries_.find(registry); | 161 auto it = connection_interface_registries_.find(registry); |
171 CHECK(it != connection_interface_registries_.end()); | 162 CHECK(it != connection_interface_registries_.end()); |
172 connection_interface_registries_.erase(it); | 163 connection_interface_registries_.erase(it); |
173 } | 164 } |
174 | 165 |
175 } // namespace service_manager | 166 } // namespace service_manager |
OLD | NEW |