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 "mojo/application_manager/application_manager.h" | 5 #include "mojo/application_manager/application_manager.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 public: | 28 public: |
29 ServiceProvider* GetRemoteServiceProvider() { return client(); } | 29 ServiceProvider* GetRemoteServiceProvider() { return client(); } |
30 | 30 |
31 private: | 31 private: |
32 void ConnectToService(const String& service_name, | 32 void ConnectToService(const String& service_name, |
33 ScopedMessagePipeHandle client_handle) override {} | 33 ScopedMessagePipeHandle client_handle) override {} |
34 }; | 34 }; |
35 | 35 |
36 } // namespace | 36 } // namespace |
37 | 37 |
38 ApplicationManager::Delegate::~Delegate() {} | 38 |
39 ApplicationManager::Delegate::~Delegate() { | |
40 } | |
41 | |
42 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { | |
43 LOG(ERROR) << "Communication error with application: " << url.spec(); | |
44 } | |
45 | |
46 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { | |
47 return url; | |
48 } | |
49 | |
39 | 50 |
40 class ApplicationManager::LoadCallbacksImpl | 51 class ApplicationManager::LoadCallbacksImpl |
41 : public ApplicationLoader::LoadCallbacks { | 52 : public ApplicationLoader::LoadCallbacks { |
42 public: | 53 public: |
43 LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager, | 54 LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager, |
44 const GURL& requested_url, | 55 const GURL& requested_url, |
56 const GURL& resolved_url, | |
45 const GURL& requestor_url, | 57 const GURL& requestor_url, |
46 ServiceProviderPtr service_provider) | 58 ServiceProviderPtr service_provider) |
47 : manager_(manager), | 59 : manager_(manager), |
48 requested_url_(requested_url), | 60 requested_url_(requested_url), |
61 resolved_url_(resolved_url), | |
49 requestor_url_(requestor_url), | 62 requestor_url_(requestor_url), |
50 service_provider_(service_provider.Pass()) {} | 63 service_provider_(service_provider.Pass()) {} |
51 | 64 |
52 private: | 65 private: |
53 ~LoadCallbacksImpl() override {} | 66 ~LoadCallbacksImpl() override {} |
54 | 67 |
55 // LoadCallbacks implementation | 68 // LoadCallbacks implementation |
56 ScopedMessagePipeHandle RegisterApplication() override { | 69 ScopedMessagePipeHandle RegisterApplication() override { |
57 ScopedMessagePipeHandle shell_handle; | 70 ScopedMessagePipeHandle shell_handle; |
58 if (manager_) { | 71 if (manager_) { |
59 manager_->RegisterLoadedApplication(requested_url_, | 72 manager_->RegisterLoadedApplication(requested_url_, |
73 resolved_url_, | |
60 requestor_url_, | 74 requestor_url_, |
61 service_provider_.Pass(), | 75 service_provider_.Pass(), |
62 &shell_handle); | 76 &shell_handle); |
63 } | 77 } |
64 return shell_handle.Pass(); | 78 return shell_handle.Pass(); |
65 } | 79 } |
66 | 80 |
67 void LoadWithContentHandler(const GURL& content_handler_url, | 81 void LoadWithContentHandler(const GURL& content_handler_url, |
68 URLResponsePtr url_response) override { | 82 URLResponsePtr url_response) override { |
69 if (manager_) { | 83 if (manager_) { |
70 manager_->LoadWithContentHandler(requested_url_, | 84 manager_->LoadWithContentHandler(requested_url_, |
71 requestor_url_, | 85 requestor_url_, |
72 content_handler_url, | 86 content_handler_url, |
73 url_response.Pass(), | 87 url_response.Pass(), |
74 service_provider_.Pass()); | 88 service_provider_.Pass()); |
75 } | 89 } |
76 } | 90 } |
77 | 91 |
78 base::WeakPtr<ApplicationManager> manager_; | 92 base::WeakPtr<ApplicationManager> manager_; |
79 GURL requested_url_; | 93 GURL requested_url_; |
94 GURL resolved_url_; | |
80 GURL requestor_url_; | 95 GURL requestor_url_; |
81 ServiceProviderPtr service_provider_; | 96 ServiceProviderPtr service_provider_; |
82 }; | 97 }; |
83 | 98 |
84 class ApplicationManager::ShellImpl : public InterfaceImpl<Shell> { | 99 class ApplicationManager::ShellImpl : public InterfaceImpl<Shell> { |
85 public: | 100 public: |
86 ShellImpl(ApplicationManager* manager, const GURL& url) | 101 ShellImpl(ApplicationManager* manager, const GURL& requested_url, |
DaveMoore
2014/10/31 16:15:58
Nit: could you put these on their own lines?
Aaron Boodman
2014/10/31 18:14:02
Done.
| |
87 : manager_(manager), url_(url) {} | 102 const GURL& url) |
103 : manager_(manager), requested_url_(requested_url), url_(url) {} | |
88 | 104 |
89 ~ShellImpl() override {} | 105 ~ShellImpl() override {} |
90 | 106 |
91 void ConnectToClient(const GURL& requestor_url, | 107 void ConnectToClient(const GURL& requestor_url, |
92 ServiceProviderPtr service_provider) { | 108 ServiceProviderPtr service_provider) { |
93 client()->AcceptConnection(String::From(requestor_url), | 109 client()->AcceptConnection(String::From(requestor_url), |
94 service_provider.Pass()); | 110 service_provider.Pass()); |
95 } | 111 } |
96 | 112 |
97 // ServiceProvider implementation: | 113 // ServiceProvider implementation: |
98 void ConnectToApplication( | 114 void ConnectToApplication( |
99 const String& app_url, | 115 const String& app_url, |
100 InterfaceRequest<ServiceProvider> in_service_provider) override { | 116 InterfaceRequest<ServiceProvider> in_service_provider) override { |
101 ServiceProviderPtr out_service_provider; | 117 ServiceProviderPtr out_service_provider; |
102 out_service_provider.Bind(in_service_provider.PassMessagePipe()); | 118 out_service_provider.Bind(in_service_provider.PassMessagePipe()); |
103 manager_->ConnectToApplication( | 119 manager_->ConnectToApplication( |
104 app_url.To<GURL>(), url_, out_service_provider.Pass()); | 120 app_url.To<GURL>(), url_, out_service_provider.Pass()); |
105 } | 121 } |
106 | 122 |
107 const GURL& url() const { return url_; } | 123 const GURL& url() const { return url_; } |
124 const GURL& requested_url() const { return requested_url_; } | |
108 | 125 |
109 private: | 126 private: |
110 void OnConnectionError() override { manager_->OnShellImplError(this); } | 127 void OnConnectionError() override { manager_->OnShellImplError(this); } |
111 | 128 |
112 ApplicationManager* const manager_; | 129 ApplicationManager* const manager_; |
130 const GURL requested_url_; | |
113 const GURL url_; | 131 const GURL url_; |
114 | 132 |
115 DISALLOW_COPY_AND_ASSIGN(ShellImpl); | 133 DISALLOW_COPY_AND_ASSIGN(ShellImpl); |
116 }; | 134 }; |
117 | 135 |
118 struct ApplicationManager::ContentHandlerConnection { | 136 struct ApplicationManager::ContentHandlerConnection { |
119 ContentHandlerConnection(ApplicationManager* manager, | 137 ContentHandlerConnection(ApplicationManager* manager, |
120 const GURL& content_handler_url) { | 138 const GURL& content_handler_url) { |
121 ServiceProviderPtr service_provider; | 139 ServiceProviderPtr service_provider; |
122 BindToProxy(&service_provider_impl, &service_provider); | 140 BindToProxy(&service_provider_impl, &service_provider); |
(...skipping 16 matching lines...) Expand all Loading... | |
139 | 157 |
140 bool ApplicationManager::TestAPI::HasCreatedInstance() { | 158 bool ApplicationManager::TestAPI::HasCreatedInstance() { |
141 return has_created_instance; | 159 return has_created_instance; |
142 } | 160 } |
143 | 161 |
144 bool ApplicationManager::TestAPI::HasFactoryForURL(const GURL& url) const { | 162 bool ApplicationManager::TestAPI::HasFactoryForURL(const GURL& url) const { |
145 return manager_->url_to_shell_impl_.find(url) != | 163 return manager_->url_to_shell_impl_.find(url) != |
146 manager_->url_to_shell_impl_.end(); | 164 manager_->url_to_shell_impl_.end(); |
147 } | 165 } |
148 | 166 |
149 ApplicationManager::ApplicationManager() | 167 ApplicationManager::ApplicationManager(Delegate* delegate) |
150 : delegate_(NULL), | 168 : delegate_(delegate), |
151 interceptor_(NULL), | 169 interceptor_(NULL), |
152 weak_ptr_factory_(this) { | 170 weak_ptr_factory_(this) { |
153 } | 171 } |
154 | 172 |
155 ApplicationManager::~ApplicationManager() { | 173 ApplicationManager::~ApplicationManager() { |
156 STLDeleteValues(&url_to_content_handler_); | 174 STLDeleteValues(&url_to_content_handler_); |
157 TerminateShellConnections(); | 175 TerminateShellConnections(); |
158 STLDeleteValues(&url_to_loader_); | 176 STLDeleteValues(&url_to_loader_); |
159 STLDeleteValues(&scheme_to_loader_); | 177 STLDeleteValues(&scheme_to_loader_); |
160 } | 178 } |
161 | 179 |
162 void ApplicationManager::TerminateShellConnections() { | 180 void ApplicationManager::TerminateShellConnections() { |
163 STLDeleteValues(&url_to_shell_impl_); | 181 STLDeleteValues(&url_to_shell_impl_); |
164 } | 182 } |
165 | 183 |
166 // static | |
167 ApplicationManager* ApplicationManager::GetInstance() { | |
168 static base::LazyInstance<ApplicationManager> instance = | |
169 LAZY_INSTANCE_INITIALIZER; | |
170 has_created_instance = true; | |
171 return &instance.Get(); | |
172 } | |
173 | |
174 void ApplicationManager::ConnectToApplication( | 184 void ApplicationManager::ConnectToApplication( |
175 const GURL& url, | 185 const GURL& requested_url, |
176 const GURL& requestor_url, | 186 const GURL& requestor_url, |
177 ServiceProviderPtr service_provider) { | 187 ServiceProviderPtr service_provider) { |
178 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); | 188 GURL resolved_url = delegate_->ResolveURL(requested_url); |
189 | |
190 URLToShellImplMap::const_iterator shell_it = | |
191 url_to_shell_impl_.find(resolved_url); | |
179 if (shell_it != url_to_shell_impl_.end()) { | 192 if (shell_it != url_to_shell_impl_.end()) { |
180 ConnectToClient( | 193 ConnectToClient(shell_it->second, resolved_url, requestor_url, |
181 shell_it->second, url, requestor_url, service_provider.Pass()); | 194 service_provider.Pass()); |
182 return; | 195 return; |
183 } | 196 } |
184 | 197 |
185 scoped_refptr<LoadCallbacksImpl> callbacks( | 198 scoped_refptr<LoadCallbacksImpl> callbacks( |
186 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), | 199 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), |
187 url, | 200 requested_url, |
201 resolved_url, | |
188 requestor_url, | 202 requestor_url, |
189 service_provider.Pass())); | 203 service_provider.Pass())); |
190 GetLoaderForURL(url)->Load(this, url, callbacks); | 204 GetLoaderForURL(resolved_url)->Load(this, resolved_url, callbacks); |
191 } | 205 } |
192 | 206 |
193 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, | 207 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, |
194 const GURL& url, | 208 const GURL& url, |
195 const GURL& requestor_url, | 209 const GURL& requestor_url, |
196 ServiceProviderPtr service_provider) { | 210 ServiceProviderPtr service_provider) { |
197 if (interceptor_) { | 211 if (interceptor_) { |
198 shell_impl->ConnectToClient( | 212 shell_impl->ConnectToClient( |
199 requestor_url, | 213 requestor_url, |
200 interceptor_->OnConnectToClient(url, service_provider.Pass())); | 214 interceptor_->OnConnectToClient(url, service_provider.Pass())); |
201 } else { | 215 } else { |
202 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); | 216 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); |
203 } | 217 } |
204 } | 218 } |
205 | 219 |
206 void ApplicationManager::RegisterExternalApplication( | 220 void ApplicationManager::RegisterExternalApplication( |
207 const GURL& url, | 221 const GURL& url, |
208 ScopedMessagePipeHandle shell_handle) { | 222 ScopedMessagePipeHandle shell_handle) { |
209 url_to_shell_impl_[url] = | 223 url_to_shell_impl_[url] = |
210 WeakBindToPipe(new ShellImpl(this, url), shell_handle.Pass()); | 224 WeakBindToPipe(new ShellImpl(this, url, url), shell_handle.Pass()); |
211 } | 225 } |
212 | 226 |
213 void ApplicationManager::RegisterLoadedApplication( | 227 void ApplicationManager::RegisterLoadedApplication( |
214 const GURL& url, | 228 const GURL& requested_url, |
229 const GURL& resolved_url, | |
215 const GURL& requestor_url, | 230 const GURL& requestor_url, |
216 ServiceProviderPtr service_provider, | 231 ServiceProviderPtr service_provider, |
217 ScopedMessagePipeHandle* shell_handle) { | 232 ScopedMessagePipeHandle* shell_handle) { |
218 ShellImpl* shell_impl = NULL; | 233 ShellImpl* shell_impl = NULL; |
219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); | 234 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(resolved_url); |
220 if (iter != url_to_shell_impl_.end()) { | 235 if (iter != url_to_shell_impl_.end()) { |
221 // This can happen because services are loaded asynchronously. So if we get | 236 // 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 | 237 // two requests for the same service close to each other, we might get here |
223 // and find that we already have it. | 238 // and find that we already have it. |
224 shell_impl = iter->second; | 239 shell_impl = iter->second; |
225 } else { | 240 } else { |
226 MessagePipe pipe; | 241 MessagePipe pipe; |
227 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | 242 URLToArgsMap::const_iterator args_it = url_to_args_.find(resolved_url); |
228 Array<String> args; | 243 Array<String> args; |
229 if (args_it != url_to_args_.end()) | 244 if (args_it != url_to_args_.end()) |
230 args = Array<String>::From(args_it->second); | 245 args = Array<String>::From(args_it->second); |
231 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); | 246 shell_impl = WeakBindToPipe( |
232 url_to_shell_impl_[url] = shell_impl; | 247 new ShellImpl(this, requested_url, resolved_url), pipe.handle1.Pass()); |
248 url_to_shell_impl_[resolved_url] = shell_impl; | |
233 *shell_handle = pipe.handle0.Pass(); | 249 *shell_handle = pipe.handle0.Pass(); |
234 shell_impl->client()->Initialize(args.Pass()); | 250 shell_impl->client()->Initialize(args.Pass()); |
235 } | 251 } |
236 | 252 |
237 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); | 253 ConnectToClient(shell_impl, resolved_url, requestor_url, |
254 service_provider.Pass()); | |
238 } | 255 } |
239 | 256 |
240 void ApplicationManager::LoadWithContentHandler( | 257 void ApplicationManager::LoadWithContentHandler( |
241 const GURL& content_url, | 258 const GURL& content_url, |
242 const GURL& requestor_url, | 259 const GURL& requestor_url, |
243 const GURL& content_handler_url, | 260 const GURL& content_handler_url, |
244 URLResponsePtr url_response, | 261 URLResponsePtr url_response, |
245 ServiceProviderPtr service_provider) { | 262 ServiceProviderPtr service_provider) { |
246 ContentHandlerConnection* connection = NULL; | 263 ContentHandlerConnection* connection = NULL; |
247 URLToContentHandlerMap::iterator iter = | 264 URLToContentHandlerMap::iterator iter = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 SchemeToLoaderMap::const_iterator scheme_it = | 309 SchemeToLoaderMap::const_iterator scheme_it = |
293 scheme_to_loader_.find(url.scheme()); | 310 scheme_to_loader_.find(url.scheme()); |
294 if (scheme_it != scheme_to_loader_.end()) | 311 if (scheme_it != scheme_to_loader_.end()) |
295 return scheme_it->second; | 312 return scheme_it->second; |
296 return default_loader_.get(); | 313 return default_loader_.get(); |
297 } | 314 } |
298 | 315 |
299 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { | 316 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { |
300 // Called from ~ShellImpl, so we do not need to call Destroy here. | 317 // Called from ~ShellImpl, so we do not need to call Destroy here. |
301 const GURL url = shell_impl->url(); | 318 const GURL url = shell_impl->url(); |
319 const GURL requested_url = shell_impl->requested_url(); | |
302 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); | 320 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); |
303 DCHECK(it != url_to_shell_impl_.end()); | 321 DCHECK(it != url_to_shell_impl_.end()); |
304 delete it->second; | 322 delete it->second; |
305 url_to_shell_impl_.erase(it); | 323 url_to_shell_impl_.erase(it); |
306 ApplicationLoader* loader = GetLoaderForURL(url); | 324 ApplicationLoader* loader = GetLoaderForURL(requested_url); |
307 if (loader) | 325 if (loader) |
308 loader->OnApplicationError(this, url); | 326 loader->OnApplicationError(this, url); |
309 if (delegate_) | 327 delegate_->OnApplicationError(requested_url); |
310 delegate_->OnApplicationError(url); | |
311 } | 328 } |
312 | 329 |
313 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 330 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
314 const GURL& application_url, | 331 const GURL& application_url, |
315 const std::string& interface_name) { | 332 const std::string& interface_name) { |
316 StubServiceProvider* stub_sp = new StubServiceProvider; | 333 StubServiceProvider* stub_sp = new StubServiceProvider; |
317 ServiceProviderPtr spp; | 334 ServiceProviderPtr spp; |
318 BindToProxy(stub_sp, &spp); | 335 BindToProxy(stub_sp, &spp); |
319 ConnectToApplication(application_url, GURL(), spp.Pass()); | 336 ConnectToApplication(application_url, GURL(), spp.Pass()); |
320 MessagePipe pipe; | 337 MessagePipe pipe; |
321 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, | 338 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, |
322 pipe.handle1.Pass()); | 339 pipe.handle1.Pass()); |
323 return pipe.handle0.Pass(); | 340 return pipe.handle0.Pass(); |
324 } | 341 } |
325 } // namespace mojo | 342 } // namespace mojo |
OLD | NEW |