OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stdio.h> |
| 6 |
5 #include "mojo/service_manager/service_manager.h" | 7 #include "mojo/service_manager/service_manager.h" |
6 | 8 |
7 #include <stdio.h> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 10 #include "base/logging.h" |
12 #include "base/macros.h" | 11 #include "base/macros.h" |
13 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
14 #include "mojo/common/common_type_converters.h" | 13 #include "mojo/common/common_type_converters.h" |
15 #include "mojo/public/cpp/application/connect.h" | |
16 #include "mojo/public/interfaces/application/application.mojom.h" | 14 #include "mojo/public/interfaces/application/application.mojom.h" |
17 #include "mojo/public/interfaces/application/shell.mojom.h" | 15 #include "mojo/public/interfaces/application/shell.mojom.h" |
18 #include "mojo/service_manager/service_loader.h" | 16 #include "mojo/service_manager/service_loader.h" |
19 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom.
h" | |
20 | 17 |
21 namespace mojo { | 18 namespace mojo { |
22 | 19 |
23 namespace { | 20 namespace { |
24 // Used by TestAPI. | 21 // Used by TestAPI. |
25 bool has_created_instance = false; | 22 bool has_created_instance = false; |
26 | 23 |
27 class StubServiceProvider : public InterfaceImpl<ServiceProvider> { | 24 class StubServiceProvider : public InterfaceImpl<ServiceProvider> { |
28 public: | 25 public: |
29 ServiceProvider* GetRemoteServiceProvider() { | 26 ServiceProvider* GetRemoteServiceProvider() { |
30 return client(); | 27 return client(); |
31 } | 28 } |
32 | 29 |
33 private: | 30 private: |
34 virtual void ConnectToService( | 31 virtual void ConnectToService( |
35 const String& service_name, | 32 const String& service_name, |
36 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {} | 33 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {} |
37 }; | 34 }; |
38 | 35 |
39 } // namespace | 36 } |
40 | |
41 class ServiceManager::LoadCallbacksImpl : public ServiceLoader::LoadCallbacks { | |
42 public: | |
43 LoadCallbacksImpl(base::WeakPtr<ServiceManager> manager, | |
44 const GURL& requested_url, | |
45 const GURL& requestor_url, | |
46 ServiceProviderPtr service_provider) | |
47 : manager_(manager), | |
48 requested_url_(requested_url), | |
49 requestor_url_(requestor_url), | |
50 service_provider_(service_provider.Pass()) { | |
51 } | |
52 | |
53 private: | |
54 virtual ~LoadCallbacksImpl() { | |
55 } | |
56 | |
57 // LoadCallbacks implementation | |
58 virtual ScopedMessagePipeHandle RegisterApplication() OVERRIDE { | |
59 ScopedMessagePipeHandle shell_handle; | |
60 if (manager_) { | |
61 manager_->RegisterLoadedApplication(requested_url_, | |
62 requestor_url_, | |
63 service_provider_.Pass(), | |
64 &shell_handle); | |
65 } | |
66 return shell_handle.Pass(); | |
67 } | |
68 | |
69 virtual void LoadWithContentHandler(const GURL& content_handler_url, | |
70 URLResponsePtr content) OVERRIDE { | |
71 if (manager_) { | |
72 manager_->LoadWithContentHandler(requested_url_, | |
73 requestor_url_, | |
74 content_handler_url, | |
75 content.Pass(), | |
76 service_provider_.Pass()); | |
77 } | |
78 } | |
79 | |
80 base::WeakPtr<ServiceManager> manager_; | |
81 GURL requested_url_; | |
82 GURL requestor_url_; | |
83 ServiceProviderPtr service_provider_; | |
84 }; | |
85 | 37 |
86 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> { | 38 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> { |
87 public: | 39 public: |
88 ShellImpl(ServiceManager* manager, const GURL& url) | 40 ShellImpl(ServiceManager* manager, const GURL& url) |
89 : manager_(manager), | 41 : manager_(manager), |
90 url_(url) { | 42 url_(url) { |
91 } | 43 } |
92 | 44 |
93 virtual ~ShellImpl() { | 45 virtual ~ShellImpl() { |
94 } | 46 } |
(...skipping 22 matching lines...) Expand all Loading... |
117 virtual void OnConnectionError() OVERRIDE { | 69 virtual void OnConnectionError() OVERRIDE { |
118 manager_->OnShellImplError(this); | 70 manager_->OnShellImplError(this); |
119 } | 71 } |
120 | 72 |
121 ServiceManager* const manager_; | 73 ServiceManager* const manager_; |
122 const GURL url_; | 74 const GURL url_; |
123 | 75 |
124 DISALLOW_COPY_AND_ASSIGN(ShellImpl); | 76 DISALLOW_COPY_AND_ASSIGN(ShellImpl); |
125 }; | 77 }; |
126 | 78 |
127 struct ServiceManager::ContentHandlerConnection { | |
128 ContentHandlerConnection(ServiceManager* manager, | |
129 const GURL& content_handler_url) { | |
130 ServiceProviderPtr service_provider; | |
131 BindToProxy(&service_provider_impl, &service_provider); | |
132 manager->ConnectToApplication(content_handler_url, | |
133 GURL(), | |
134 service_provider.Pass()); | |
135 mojo::ConnectToService(service_provider_impl.client(), &content_handler); | |
136 } | |
137 | |
138 StubServiceProvider service_provider_impl; | |
139 ContentHandlerPtr content_handler; | |
140 }; | |
141 | |
142 // static | 79 // static |
143 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { | 80 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { |
144 } | 81 } |
145 | 82 |
146 ServiceManager::TestAPI::~TestAPI() { | 83 ServiceManager::TestAPI::~TestAPI() { |
147 } | 84 } |
148 | 85 |
149 bool ServiceManager::TestAPI::HasCreatedInstance() { | 86 bool ServiceManager::TestAPI::HasCreatedInstance() { |
150 return has_created_instance; | 87 return has_created_instance; |
151 } | 88 } |
152 | 89 |
153 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { | 90 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { |
154 return manager_->url_to_shell_impl_.find(url) != | 91 return manager_->url_to_shell_impl_.find(url) != |
155 manager_->url_to_shell_impl_.end(); | 92 manager_->url_to_shell_impl_.end(); |
156 } | 93 } |
157 | 94 |
158 ServiceManager::ServiceManager() | 95 ServiceManager::ServiceManager() : interceptor_(NULL) { |
159 : interceptor_(NULL), | |
160 weak_ptr_factory_(this) { | |
161 } | 96 } |
162 | 97 |
163 ServiceManager::~ServiceManager() { | 98 ServiceManager::~ServiceManager() { |
164 STLDeleteValues(&url_to_content_handler_); | |
165 TerminateShellConnections(); | 99 TerminateShellConnections(); |
166 STLDeleteValues(&url_to_loader_); | 100 STLDeleteValues(&url_to_loader_); |
167 STLDeleteValues(&scheme_to_loader_); | 101 STLDeleteValues(&scheme_to_loader_); |
168 } | 102 } |
169 | 103 |
170 void ServiceManager::TerminateShellConnections() { | 104 void ServiceManager::TerminateShellConnections() { |
171 STLDeleteValues(&url_to_shell_impl_); | 105 STLDeleteValues(&url_to_shell_impl_); |
172 } | 106 } |
173 | 107 |
174 // static | 108 // static |
175 ServiceManager* ServiceManager::GetInstance() { | 109 ServiceManager* ServiceManager::GetInstance() { |
176 static base::LazyInstance<ServiceManager> instance = | 110 static base::LazyInstance<ServiceManager> instance = |
177 LAZY_INSTANCE_INITIALIZER; | 111 LAZY_INSTANCE_INITIALIZER; |
178 has_created_instance = true; | 112 has_created_instance = true; |
179 return &instance.Get(); | 113 return &instance.Get(); |
180 } | 114 } |
181 | 115 |
182 void ServiceManager::ConnectToApplication(const GURL& url, | 116 void ServiceManager::ConnectToApplication(const GURL& url, |
183 const GURL& requestor_url, | 117 const GURL& requestor_url, |
184 ServiceProviderPtr service_provider) { | 118 ServiceProviderPtr service_provider) { |
185 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); | 119 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); |
| 120 ShellImpl* shell_impl; |
186 if (shell_it != url_to_shell_impl_.end()) { | 121 if (shell_it != url_to_shell_impl_.end()) { |
187 ConnectToClient(shell_it->second, url, requestor_url, | 122 shell_impl = shell_it->second; |
188 service_provider.Pass()); | 123 } else { |
189 return; | 124 MessagePipe pipe; |
| 125 GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass()); |
| 126 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); |
| 127 url_to_shell_impl_[url] = shell_impl; |
190 } | 128 } |
191 | |
192 scoped_refptr<LoadCallbacksImpl> callbacks( | |
193 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), | |
194 url, | |
195 requestor_url, | |
196 service_provider.Pass())); | |
197 GetLoaderForURL(url)->Load(this, url, callbacks); | |
198 } | |
199 | |
200 void ServiceManager::ConnectToClient(ShellImpl* shell_impl, | |
201 const GURL& url, | |
202 const GURL& requestor_url, | |
203 ServiceProviderPtr service_provider) { | |
204 if (interceptor_) { | 129 if (interceptor_) { |
205 shell_impl->ConnectToClient( | 130 shell_impl->ConnectToClient( |
206 requestor_url, | 131 requestor_url, |
207 interceptor_->OnConnectToClient(url, service_provider.Pass())); | 132 interceptor_->OnConnectToClient(url, service_provider.Pass())); |
208 } else { | 133 } else { |
209 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); | 134 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); |
210 } | 135 } |
211 } | 136 } |
212 | 137 |
213 void ServiceManager::RegisterLoadedApplication( | |
214 const GURL& url, | |
215 const GURL& requestor_url, | |
216 ServiceProviderPtr service_provider, | |
217 ScopedMessagePipeHandle* shell_handle) { | |
218 ShellImpl* shell_impl = NULL; | |
219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); | |
220 if (iter != url_to_shell_impl_.end()) { | |
221 // This can happen because services are loaded asynchronously. So if we get | |
222 // two requests for the same service close to each other, we might get here | |
223 // and find that we already have it. | |
224 shell_impl = iter->second; | |
225 } else { | |
226 MessagePipe pipe; | |
227 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); | |
228 url_to_shell_impl_[url] = shell_impl; | |
229 *shell_handle = pipe.handle0.Pass(); | |
230 } | |
231 | |
232 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); | |
233 } | |
234 | |
235 void ServiceManager::LoadWithContentHandler( | |
236 const GURL& content_url, | |
237 const GURL& requestor_url, | |
238 const GURL& content_handler_url, | |
239 URLResponsePtr content, | |
240 ServiceProviderPtr service_provider) { | |
241 ContentHandlerConnection* connection = NULL; | |
242 URLToContentHandlerMap::iterator iter = | |
243 url_to_content_handler_.find(content_handler_url); | |
244 if (iter != url_to_content_handler_.end()) { | |
245 connection = iter->second; | |
246 } else { | |
247 connection = new ContentHandlerConnection(this, content_handler_url); | |
248 url_to_content_handler_[content_handler_url] = connection; | |
249 } | |
250 connection->content_handler->OnConnect(content_url.spec(), | |
251 content.Pass(), | |
252 service_provider.Pass()); | |
253 } | |
254 | |
255 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader, | 138 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader, |
256 const GURL& url) { | 139 const GURL& url) { |
257 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 140 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
258 if (it != url_to_loader_.end()) | 141 if (it != url_to_loader_.end()) |
259 delete it->second; | 142 delete it->second; |
260 url_to_loader_[url] = loader.release(); | 143 url_to_loader_[url] = loader.release(); |
261 } | 144 } |
262 | 145 |
263 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader, | 146 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader, |
264 const std::string& scheme) { | 147 const std::string& scheme) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 StubServiceProvider* stub_sp = new StubServiceProvider; | 184 StubServiceProvider* stub_sp = new StubServiceProvider; |
302 ServiceProviderPtr spp; | 185 ServiceProviderPtr spp; |
303 BindToProxy(stub_sp, &spp); | 186 BindToProxy(stub_sp, &spp); |
304 ConnectToApplication(application_url, GURL(), spp.Pass()); | 187 ConnectToApplication(application_url, GURL(), spp.Pass()); |
305 MessagePipe pipe; | 188 MessagePipe pipe; |
306 stub_sp->GetRemoteServiceProvider()->ConnectToService( | 189 stub_sp->GetRemoteServiceProvider()->ConnectToService( |
307 interface_name, pipe.handle1.Pass()); | 190 interface_name, pipe.handle1.Pass()); |
308 return pipe.handle0.Pass(); | 191 return pipe.handle0.Pass(); |
309 } | 192 } |
310 } // namespace mojo | 193 } // namespace mojo |
OLD | NEW |