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/shell/application_manager.h" | 5 #include "mojo/shell/application_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { | 34 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { |
35 public: | 35 public: |
36 ContentHandlerConnection(ApplicationManager* manager, | 36 ContentHandlerConnection(ApplicationManager* manager, |
37 const GURL& content_handler_url, | 37 const GURL& content_handler_url, |
38 const GURL& requestor_url, | 38 const GURL& requestor_url, |
39 const std::string& qualifier) | 39 const std::string& qualifier) |
40 : manager_(manager), | 40 : manager_(manager), |
41 content_handler_url_(content_handler_url), | 41 content_handler_url_(content_handler_url), |
42 content_handler_qualifier_(qualifier) { | 42 content_handler_qualifier_(qualifier) { |
43 ServiceProviderPtr services; | 43 ServiceProviderPtr services; |
44 manager->ConnectToApplicationWithParameters( | 44 manager->ConnectToApplicationInternal( |
45 content_handler_url, qualifier, requestor_url, GetProxy(&services), | 45 content_handler_url, qualifier, requestor_url, GetProxy(&services), |
46 nullptr, base::Closure(), std::vector<std::string>()); | 46 nullptr, base::Closure()); |
47 MessagePipe pipe; | 47 MessagePipe pipe; |
48 content_handler_.Bind( | 48 content_handler_.Bind( |
49 InterfacePtrInfo<ContentHandler>(pipe.handle0.Pass(), 0u)); | 49 InterfacePtrInfo<ContentHandler>(pipe.handle0.Pass(), 0u)); |
50 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); | 50 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); |
51 content_handler_.set_error_handler(this); | 51 content_handler_.set_error_handler(this); |
52 } | 52 } |
53 | 53 |
54 ContentHandler* content_handler() { return content_handler_.get(); } | 54 ContentHandler* content_handler() { return content_handler_.get(); } |
55 | 55 |
56 GURL content_handler_url() { return content_handler_url_; } | 56 GURL content_handler_url() { return content_handler_url_; } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 void ApplicationManager::TerminateShellConnections() { | 99 void ApplicationManager::TerminateShellConnections() { |
100 STLDeleteValues(&identity_to_shell_impl_); | 100 STLDeleteValues(&identity_to_shell_impl_); |
101 } | 101 } |
102 | 102 |
103 void ApplicationManager::ConnectToApplication( | 103 void ApplicationManager::ConnectToApplication( |
104 const GURL& requested_url, | 104 const GURL& requested_url, |
105 const GURL& requestor_url, | 105 const GURL& requestor_url, |
106 InterfaceRequest<ServiceProvider> services, | 106 InterfaceRequest<ServiceProvider> services, |
107 ServiceProviderPtr exposed_services, | 107 ServiceProviderPtr exposed_services, |
108 const base::Closure& on_application_end) { | 108 const base::Closure& on_application_end) { |
109 ConnectToApplicationWithParameters( | 109 ConnectToApplicationInternal( |
110 requested_url, std::string(), requestor_url, services.Pass(), | 110 requested_url, std::string(), requestor_url, services.Pass(), |
111 exposed_services.Pass(), on_application_end, std::vector<std::string>()); | 111 exposed_services.Pass(), on_application_end); |
112 } | 112 } |
113 | 113 |
114 void ApplicationManager::ConnectToApplicationWithParameters( | 114 void ApplicationManager::ConnectToApplicationInternal( |
115 const GURL& requested_url, | 115 const GURL& requested_url, |
116 const std::string& qualifier, | 116 const std::string& qualifier, |
117 const GURL& requestor_url, | 117 const GURL& requestor_url, |
118 InterfaceRequest<ServiceProvider> services, | 118 InterfaceRequest<ServiceProvider> services, |
119 ServiceProviderPtr exposed_services, | 119 ServiceProviderPtr exposed_services, |
120 const base::Closure& on_application_end, | 120 const base::Closure& on_application_end) { |
121 const std::vector<std::string>& pre_redirect_parameters) { | |
122 TRACE_EVENT_INSTANT1( | 121 TRACE_EVENT_INSTANT1( |
123 "mojo_shell", "ApplicationManager::ConnectToApplicationWithParameters", | 122 "mojo_shell", "ApplicationManager::ConnectToApplication", |
124 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_url.spec()); | 123 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_url.spec()); |
125 DCHECK(requested_url.is_valid()); | 124 DCHECK(requested_url.is_valid()); |
126 | 125 |
127 // We check both the mapped and resolved urls for existing shell_impls because | 126 // We check both the mapped and resolved urls for existing shell_impls because |
128 // external applications can be registered for the unresolved mojo:foo urls. | 127 // external applications can be registered for the unresolved mojo:foo urls. |
129 | 128 |
130 GURL mapped_url = delegate_->ResolveMappings(requested_url); | 129 GURL mapped_url = delegate_->ResolveMappings(requested_url); |
131 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, | 130 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, |
132 &services, &exposed_services)) { | 131 &services, &exposed_services)) { |
133 return; | 132 return; |
134 } | 133 } |
135 | 134 |
136 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); | 135 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); |
137 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, | 136 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, |
138 &services, &exposed_services)) { | 137 &services, &exposed_services)) { |
139 return; | 138 return; |
140 } | 139 } |
141 | 140 |
142 // The application is not running, let's compute the parameters. | 141 // The application is not running, let's compute the parameters. |
143 if (ConnectToApplicationWithLoader( | 142 if (ConnectToApplicationWithLoader( |
144 requested_url, qualifier, mapped_url, requestor_url, &services, | 143 requested_url, qualifier, mapped_url, requestor_url, &services, |
145 &exposed_services, on_application_end, pre_redirect_parameters, | 144 &exposed_services, on_application_end, GetLoaderForURL(mapped_url))) { |
146 GetLoaderForURL(mapped_url))) { | |
147 return; | 145 return; |
148 } | 146 } |
149 | 147 |
150 if (ConnectToApplicationWithLoader( | 148 if (ConnectToApplicationWithLoader( |
151 requested_url, qualifier, resolved_url, requestor_url, &services, | 149 requested_url, qualifier, resolved_url, requestor_url, &services, |
152 &exposed_services, on_application_end, pre_redirect_parameters, | 150 &exposed_services, on_application_end, |
153 GetLoaderForURL(resolved_url))) { | 151 GetLoaderForURL(resolved_url))) { |
154 return; | 152 return; |
155 } | 153 } |
156 | 154 |
157 if (ConnectToApplicationWithLoader( | 155 if (ConnectToApplicationWithLoader( |
158 requested_url, qualifier, resolved_url, requestor_url, &services, | 156 requested_url, qualifier, resolved_url, requestor_url, &services, |
159 &exposed_services, on_application_end, pre_redirect_parameters, | 157 &exposed_services, on_application_end, default_loader_.get())) { |
160 default_loader_.get())) { | |
161 return; | 158 return; |
162 } | 159 } |
163 | 160 |
164 auto callback = base::Bind( | 161 auto callback = base::Bind( |
165 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), | 162 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
166 requested_url, qualifier, requestor_url, base::Passed(services.Pass()), | 163 requested_url, qualifier, requestor_url, base::Passed(services.Pass()), |
167 base::Passed(exposed_services.Pass()), on_application_end, | 164 base::Passed(exposed_services.Pass()), on_application_end); |
168 pre_redirect_parameters); | |
169 | 165 |
170 if (delegate_->CreateFetcher( | 166 if (delegate_->CreateFetcher( |
171 resolved_url, | 167 resolved_url, |
172 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { | 168 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { |
173 return; | 169 return; |
174 } | 170 } |
175 | 171 |
176 if (resolved_url.SchemeIsFile()) { | 172 if (resolved_url.SchemeIsFile()) { |
177 new LocalFetcher( | 173 new LocalFetcher( |
178 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 174 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } | 206 } |
211 | 207 |
212 bool ApplicationManager::ConnectToApplicationWithLoader( | 208 bool ApplicationManager::ConnectToApplicationWithLoader( |
213 const GURL& requested_url, | 209 const GURL& requested_url, |
214 const std::string& qualifier, | 210 const std::string& qualifier, |
215 const GURL& resolved_url, | 211 const GURL& resolved_url, |
216 const GURL& requestor_url, | 212 const GURL& requestor_url, |
217 InterfaceRequest<ServiceProvider>* services, | 213 InterfaceRequest<ServiceProvider>* services, |
218 ServiceProviderPtr* exposed_services, | 214 ServiceProviderPtr* exposed_services, |
219 const base::Closure& on_application_end, | 215 const base::Closure& on_application_end, |
220 const std::vector<std::string>& parameters, | |
221 ApplicationLoader* loader) { | 216 ApplicationLoader* loader) { |
222 if (!loader) | 217 if (!loader) |
223 return false; | 218 return false; |
224 | 219 |
225 const GURL app_url = | 220 const GURL app_url = |
226 requested_url.scheme() == "mojo" ? requested_url : resolved_url; | 221 requested_url.scheme() == "mojo" ? requested_url : resolved_url; |
227 | 222 |
228 loader->Load( | 223 loader->Load( |
229 resolved_url, | 224 resolved_url, |
230 RegisterShell(app_url, qualifier, requestor_url, services->Pass(), | 225 RegisterShell(app_url, qualifier, requestor_url, services->Pass(), |
231 exposed_services->Pass(), on_application_end, parameters)); | 226 exposed_services->Pass(), on_application_end)); |
232 return true; | 227 return true; |
233 } | 228 } |
234 | 229 |
235 InterfaceRequest<Application> ApplicationManager::RegisterShell( | 230 InterfaceRequest<Application> ApplicationManager::RegisterShell( |
236 const GURL& app_url, | 231 const GURL& app_url, |
237 const std::string& qualifier, | 232 const std::string& qualifier, |
238 const GURL& requestor_url, | 233 const GURL& requestor_url, |
239 InterfaceRequest<ServiceProvider> services, | 234 InterfaceRequest<ServiceProvider> services, |
240 ServiceProviderPtr exposed_services, | 235 ServiceProviderPtr exposed_services, |
241 const base::Closure& on_application_end, | 236 const base::Closure& on_application_end) { |
242 const std::vector<std::string>& parameters) { | |
243 Identity app_identity(app_url, qualifier); | 237 Identity app_identity(app_url, qualifier); |
244 | 238 |
245 ApplicationPtr application; | 239 ApplicationPtr application; |
246 InterfaceRequest<Application> application_request = GetProxy(&application); | 240 InterfaceRequest<Application> application_request = GetProxy(&application); |
247 ShellImpl* shell = | 241 ShellImpl* shell = |
248 new ShellImpl(application.Pass(), this, app_identity, on_application_end); | 242 new ShellImpl(application.Pass(), this, app_identity, on_application_end); |
249 identity_to_shell_impl_[app_identity] = shell; | 243 identity_to_shell_impl_[app_identity] = shell; |
250 shell->InitializeApplication(Array<String>::From(parameters)); | 244 shell->InitializeApplication(); |
251 ConnectToClient(shell, app_url, requestor_url, services.Pass(), | 245 ConnectToClient(shell, app_url, requestor_url, services.Pass(), |
252 exposed_services.Pass()); | 246 exposed_services.Pass()); |
253 return application_request.Pass(); | 247 return application_request.Pass(); |
254 } | 248 } |
255 | 249 |
256 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url, | 250 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url, |
257 const std::string& qualifier) { | 251 const std::string& qualifier) { |
258 const auto& shell_it = identity_to_shell_impl_.find(Identity(url, qualifier)); | 252 const auto& shell_it = identity_to_shell_impl_.find(Identity(url, qualifier)); |
259 if (shell_it != identity_to_shell_impl_.end()) | 253 if (shell_it != identity_to_shell_impl_.end()) |
260 return shell_it->second; | 254 return shell_it->second; |
(...skipping 10 matching lines...) Expand all Loading... |
271 exposed_services.Pass()); | 265 exposed_services.Pass()); |
272 } | 266 } |
273 | 267 |
274 void ApplicationManager::HandleFetchCallback( | 268 void ApplicationManager::HandleFetchCallback( |
275 const GURL& requested_url, | 269 const GURL& requested_url, |
276 const std::string& qualifier, | 270 const std::string& qualifier, |
277 const GURL& requestor_url, | 271 const GURL& requestor_url, |
278 InterfaceRequest<ServiceProvider> services, | 272 InterfaceRequest<ServiceProvider> services, |
279 ServiceProviderPtr exposed_services, | 273 ServiceProviderPtr exposed_services, |
280 const base::Closure& on_application_end, | 274 const base::Closure& on_application_end, |
281 const std::vector<std::string>& parameters, | |
282 NativeApplicationCleanup cleanup, | 275 NativeApplicationCleanup cleanup, |
283 scoped_ptr<Fetcher> fetcher) { | 276 scoped_ptr<Fetcher> fetcher) { |
284 if (!fetcher) { | 277 if (!fetcher) { |
285 // Network error. Drop |application_request| to tell requestor. | 278 // Network error. Drop |application_request| to tell requestor. |
286 return; | 279 return; |
287 } | 280 } |
288 | 281 |
289 GURL redirect_url = fetcher->GetRedirectURL(); | 282 GURL redirect_url = fetcher->GetRedirectURL(); |
290 if (!redirect_url.is_empty()) { | 283 if (!redirect_url.is_empty()) { |
291 // And around we go again... Whee! | 284 // And around we go again... Whee! |
292 // TODO(sky): this loses |requested_url|. | 285 // TODO(sky): this loses |requested_url|. |
293 ConnectToApplicationWithParameters(redirect_url, qualifier, requestor_url, | 286 ConnectToApplicationInternal(redirect_url, qualifier, requestor_url, |
294 services.Pass(), exposed_services.Pass(), | 287 services.Pass(), exposed_services.Pass(), |
295 on_application_end, parameters); | 288 on_application_end); |
296 return; | 289 return; |
297 } | 290 } |
298 | 291 |
299 // We already checked if the application was running before we fetched it, but | 292 // We already checked if the application was running before we fetched it, but |
300 // it might have started while the fetch was outstanding. We don't want to | 293 // it might have started while the fetch was outstanding. We don't want to |
301 // have two copies of the app running, so check again. | 294 // have two copies of the app running, so check again. |
302 // | 295 // |
303 // Also, it's possible the original URL was redirected to an app that is | 296 // Also, it's possible the original URL was redirected to an app that is |
304 // already running. | 297 // already running. |
305 if (ConnectToRunningApplication(requested_url, qualifier, requestor_url, | 298 if (ConnectToRunningApplication(requested_url, qualifier, requestor_url, |
306 &services, &exposed_services)) { | 299 &services, &exposed_services)) { |
307 return; | 300 return; |
308 } | 301 } |
309 | 302 |
310 const GURL app_url = | 303 const GURL app_url = |
311 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); | 304 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); |
312 | 305 |
313 InterfaceRequest<Application> request( | 306 InterfaceRequest<Application> request( |
314 RegisterShell(app_url, qualifier, requestor_url, services.Pass(), | 307 RegisterShell(app_url, qualifier, requestor_url, services.Pass(), |
315 exposed_services.Pass(), on_application_end, parameters)); | 308 exposed_services.Pass(), on_application_end)); |
316 | 309 |
317 // If the response begins with a #!mojo <content-handler-url>, use it. | 310 // If the response begins with a #!mojo <content-handler-url>, use it. |
318 GURL content_handler_url; | 311 GURL content_handler_url; |
319 std::string shebang; | 312 std::string shebang; |
320 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { | 313 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { |
321 LoadWithContentHandler( | 314 LoadWithContentHandler( |
322 content_handler_url, requestor_url, qualifier, request.Pass(), | 315 content_handler_url, requestor_url, qualifier, request.Pass(), |
323 fetcher->AsURLResponse(blocking_pool_, | 316 fetcher->AsURLResponse(blocking_pool_, |
324 static_cast<int>(shebang.size()))); | 317 static_cast<int>(shebang.size()))); |
325 return; | 318 return; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 return pipe.handle0.Pass(); | 515 return pipe.handle0.Pass(); |
523 } | 516 } |
524 | 517 |
525 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 518 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
526 native_runners_.erase( | 519 native_runners_.erase( |
527 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 520 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
528 } | 521 } |
529 | 522 |
530 } // namespace shell | 523 } // namespace shell |
531 } // namespace mojo | 524 } // namespace mojo |
OLD | NEW |