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 "shell/application_manager/application_manager.h" | 5 #include "shell/application_manager/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 10 matching lines...) Expand all Loading... | |
21 #include "shell/switches.h" | 21 #include "shell/switches.h" |
22 | 22 |
23 namespace mojo { | 23 namespace mojo { |
24 namespace shell { | 24 namespace shell { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 // Used by TestAPI. | 28 // Used by TestAPI. |
29 bool has_created_instance = false; | 29 bool has_created_instance = false; |
30 | 30 |
31 std::vector<std::string> Concatenate(const std::vector<std::string>& v1, | |
32 const std::vector<std::string>& v2) { | |
33 if (!v1.size()) { | |
DaveMoore
2015/03/23 15:47:48
Nit: no braces
qsr
2015/03/23 16:04:38
Done.
| |
34 return v2; | |
35 } | |
36 if (!v2.size()) { | |
37 return v1; | |
DaveMoore
2015/03/23 15:47:48
Nit: ditto
qsr
2015/03/23 16:04:37
Done.
| |
38 } | |
39 std::vector<std::string> result(v1); | |
40 result.insert(result.end(), v1.begin(), v1.end()); | |
41 return result; | |
42 } | |
43 | |
31 } // namespace | 44 } // namespace |
32 | 45 |
33 ApplicationManager::Delegate::~Delegate() { | 46 ApplicationManager::Delegate::~Delegate() { |
34 } | 47 } |
35 | 48 |
36 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { | 49 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { |
37 LOG(ERROR) << "Communication error with application: " << url.spec(); | 50 LOG(ERROR) << "Communication error with application: " << url.spec(); |
38 } | 51 } |
39 | 52 |
40 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { | 53 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 | 117 |
105 void ApplicationManager::TerminateShellConnections() { | 118 void ApplicationManager::TerminateShellConnections() { |
106 STLDeleteValues(&identity_to_shell_impl_); | 119 STLDeleteValues(&identity_to_shell_impl_); |
107 } | 120 } |
108 | 121 |
109 void ApplicationManager::ConnectToApplication( | 122 void ApplicationManager::ConnectToApplication( |
110 const GURL& requested_url, | 123 const GURL& requested_url, |
111 const GURL& requestor_url, | 124 const GURL& requestor_url, |
112 InterfaceRequest<ServiceProvider> services, | 125 InterfaceRequest<ServiceProvider> services, |
113 ServiceProviderPtr exposed_services) { | 126 ServiceProviderPtr exposed_services) { |
127 ConnectToApplicationWithParameters(requested_url, requestor_url, | |
128 services.Pass(), exposed_services.Pass(), | |
129 std::vector<std::string>()); | |
130 } | |
131 | |
132 void ApplicationManager::ConnectToApplicationWithParameters( | |
133 const GURL& requested_url, | |
134 const GURL& requestor_url, | |
135 InterfaceRequest<ServiceProvider> services, | |
136 ServiceProviderPtr exposed_services, | |
137 const std::vector<std::string>& parameters) { | |
114 DCHECK(requested_url.is_valid()); | 138 DCHECK(requested_url.is_valid()); |
115 | 139 |
116 // We check both the mapped and resolved urls for existing shell_impls because | 140 // We check both the mapped and resolved urls for existing shell_impls because |
117 // external applications can be registered for the unresolved mojo:foo urls. | 141 // external applications can be registered for the unresolved mojo:foo urls. |
118 | 142 |
119 GURL mapped_url = delegate_->ResolveMappings(requested_url); | 143 GURL mapped_url = delegate_->ResolveMappings(requested_url); |
120 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, | 144 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, |
121 &exposed_services)) { | 145 &exposed_services)) { |
122 return; | 146 return; |
123 } | 147 } |
124 | 148 |
125 GURL resolved_url = delegate_->ResolveURL(mapped_url); | 149 GURL resolved_url = delegate_->ResolveURL(mapped_url); |
126 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, | 150 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, |
127 &exposed_services)) { | 151 &exposed_services)) { |
128 return; | 152 return; |
129 } | 153 } |
130 | 154 |
131 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, | 155 if (ConnectToApplicationWithLoader(requested_url, mapped_url, requestor_url, |
132 &services, &exposed_services, | 156 &services, &exposed_services, parameters, |
133 GetLoaderForURL(mapped_url))) { | 157 GetLoaderForURL(mapped_url))) { |
134 return; | 158 return; |
135 } | 159 } |
136 | 160 |
137 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, | 161 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, |
138 &services, &exposed_services, | 162 &services, &exposed_services, parameters, |
139 GetLoaderForURL(resolved_url))) { | 163 GetLoaderForURL(resolved_url))) { |
140 return; | 164 return; |
141 } | 165 } |
142 | 166 |
143 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, | 167 if (ConnectToApplicationWithLoader(requested_url, resolved_url, requestor_url, |
144 &services, &exposed_services, | 168 &services, &exposed_services, parameters, |
145 default_loader_.get())) { | 169 default_loader_.get())) { |
146 return; | 170 return; |
147 } | 171 } |
148 | 172 |
149 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, | 173 auto callback = base::Bind( |
150 weak_ptr_factory_.GetWeakPtr(), requested_url, | 174 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
151 requestor_url, base::Passed(services.Pass()), | 175 requested_url, requestor_url, base::Passed(services.Pass()), |
152 base::Passed(exposed_services.Pass())); | 176 base::Passed(exposed_services.Pass()), |
177 Concatenate(parameters, GetArgsForURL(resolved_url))); | |
153 | 178 |
154 if (resolved_url.SchemeIsFile()) { | 179 if (resolved_url.SchemeIsFile()) { |
155 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 180 new LocalFetcher(resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
156 base::Bind(callback, NativeRunner::DontDeleteAppPath)); | 181 base::Bind(callback, NativeRunner::DontDeleteAppPath)); |
157 return; | 182 return; |
158 } | 183 } |
159 | 184 |
160 if (!network_service_) | 185 if (!network_service_) |
161 ConnectToService(GURL("mojo:network_service"), &network_service_); | 186 ConnectToService(GURL("mojo:network_service"), &network_service_); |
162 | 187 |
(...skipping 21 matching lines...) Expand all Loading... | |
184 exposed_services->Pass()); | 209 exposed_services->Pass()); |
185 return true; | 210 return true; |
186 } | 211 } |
187 | 212 |
188 bool ApplicationManager::ConnectToApplicationWithLoader( | 213 bool ApplicationManager::ConnectToApplicationWithLoader( |
189 const GURL& requested_url, | 214 const GURL& requested_url, |
190 const GURL& resolved_url, | 215 const GURL& resolved_url, |
191 const GURL& requestor_url, | 216 const GURL& requestor_url, |
192 InterfaceRequest<ServiceProvider>* services, | 217 InterfaceRequest<ServiceProvider>* services, |
193 ServiceProviderPtr* exposed_services, | 218 ServiceProviderPtr* exposed_services, |
219 const std::vector<std::string>& parameters, | |
194 ApplicationLoader* loader) { | 220 ApplicationLoader* loader) { |
195 if (!loader) | 221 if (!loader) |
196 return false; | 222 return false; |
197 | 223 |
198 loader->Load(resolved_url, | 224 loader->Load( |
199 RegisterShell(requested_url, resolved_url, requestor_url, | 225 resolved_url, |
200 services->Pass(), exposed_services->Pass())); | 226 RegisterShell(requested_url, resolved_url, requestor_url, |
227 services->Pass(), exposed_services->Pass(), parameters)); | |
201 return true; | 228 return true; |
202 } | 229 } |
203 | 230 |
204 InterfaceRequest<Application> ApplicationManager::RegisterShell( | 231 InterfaceRequest<Application> ApplicationManager::RegisterShell( |
205 const GURL& original_url, | 232 const GURL& original_url, |
206 const GURL& resolved_url, | 233 const GURL& resolved_url, |
207 const GURL& requestor_url, | 234 const GURL& requestor_url, |
208 InterfaceRequest<ServiceProvider> services, | 235 InterfaceRequest<ServiceProvider> services, |
209 ServiceProviderPtr exposed_services) { | 236 ServiceProviderPtr exposed_services, |
237 const std::vector<std::string>& parameters) { | |
210 Identity app_identity(resolved_url); | 238 Identity app_identity(resolved_url); |
211 | 239 |
212 ApplicationPtr application; | 240 ApplicationPtr application; |
213 InterfaceRequest<Application> application_request = GetProxy(&application); | 241 InterfaceRequest<Application> application_request = GetProxy(&application); |
214 ShellImpl* shell = | 242 ShellImpl* shell = |
215 new ShellImpl(application.Pass(), this, original_url, app_identity); | 243 new ShellImpl(application.Pass(), this, original_url, app_identity); |
216 identity_to_shell_impl_[app_identity] = shell; | 244 identity_to_shell_impl_[app_identity] = shell; |
217 shell->InitializeApplication(GetArgsForURL(original_url)); | 245 shell->InitializeApplication(Array<String>::From( |
246 Concatenate(parameters, GetArgsForURL(app_identity.url)))); | |
218 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), | 247 ConnectToClient(shell, resolved_url, requestor_url, services.Pass(), |
219 exposed_services.Pass()); | 248 exposed_services.Pass()); |
220 return application_request.Pass(); | 249 return application_request.Pass(); |
221 } | 250 } |
222 | 251 |
223 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { | 252 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { |
224 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); | 253 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); |
225 if (shell_it != identity_to_shell_impl_.end()) | 254 if (shell_it != identity_to_shell_impl_.end()) |
226 return shell_it->second; | 255 return shell_it->second; |
227 return nullptr; | 256 return nullptr; |
228 } | 257 } |
229 | 258 |
230 void ApplicationManager::ConnectToClient( | 259 void ApplicationManager::ConnectToClient( |
231 ShellImpl* shell_impl, | 260 ShellImpl* shell_impl, |
232 const GURL& resolved_url, | 261 const GURL& resolved_url, |
233 const GURL& requestor_url, | 262 const GURL& requestor_url, |
234 InterfaceRequest<ServiceProvider> services, | 263 InterfaceRequest<ServiceProvider> services, |
235 ServiceProviderPtr exposed_services) { | 264 ServiceProviderPtr exposed_services) { |
236 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), | 265 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), |
237 exposed_services.Pass()); | 266 exposed_services.Pass()); |
238 } | 267 } |
239 | 268 |
240 void ApplicationManager::HandleFetchCallback( | 269 void ApplicationManager::HandleFetchCallback( |
241 const GURL& requested_url, | 270 const GURL& requested_url, |
242 const GURL& requestor_url, | 271 const GURL& requestor_url, |
243 InterfaceRequest<ServiceProvider> services, | 272 InterfaceRequest<ServiceProvider> services, |
244 ServiceProviderPtr exposed_services, | 273 ServiceProviderPtr exposed_services, |
274 const std::vector<std::string>& parameters, | |
245 NativeRunner::CleanupBehavior cleanup_behavior, | 275 NativeRunner::CleanupBehavior cleanup_behavior, |
246 scoped_ptr<Fetcher> fetcher) { | 276 scoped_ptr<Fetcher> fetcher) { |
247 if (!fetcher) { | 277 if (!fetcher) { |
248 // Network error. Drop |application_request| to tell requestor. | 278 // Network error. Drop |application_request| to tell requestor. |
249 return; | 279 return; |
250 } | 280 } |
251 | 281 |
252 GURL redirect_url = fetcher->GetRedirectURL(); | 282 GURL redirect_url = fetcher->GetRedirectURL(); |
253 if (!redirect_url.is_empty()) { | 283 if (!redirect_url.is_empty()) { |
254 // And around we go again... Whee! | 284 // And around we go again... Whee! |
255 ConnectToApplication(redirect_url, requestor_url, services.Pass(), | 285 ConnectToApplicationWithParameters(redirect_url, requestor_url, |
256 exposed_services.Pass()); | 286 services.Pass(), exposed_services.Pass(), |
287 parameters); | |
257 return; | 288 return; |
258 } | 289 } |
259 | 290 |
260 // We already checked if the application was running before we fetched it, but | 291 // We already checked if the application was running before we fetched it, but |
261 // it might have started while the fetch was outstanding. We don't want to | 292 // it might have started while the fetch was outstanding. We don't want to |
262 // have two copies of the app running, so check again. | 293 // have two copies of the app running, so check again. |
263 // | 294 // |
264 // Also, it's possible the original URL was redirected to an app that is | 295 // Also, it's possible the original URL was redirected to an app that is |
265 // already running. | 296 // already running. |
266 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, | 297 if (ConnectToRunningApplication(fetcher->GetURL(), requestor_url, &services, |
267 &exposed_services)) { | 298 &exposed_services)) { |
268 return; | 299 return; |
269 } | 300 } |
270 | 301 |
271 InterfaceRequest<Application> request( | 302 InterfaceRequest<Application> request( |
272 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, | 303 RegisterShell(requested_url, fetcher->GetURL(), requestor_url, |
273 services.Pass(), exposed_services.Pass())); | 304 services.Pass(), exposed_services.Pass(), parameters)); |
274 | 305 |
275 // If the response begins with a #!mojo <content-handler-url>, use it. | 306 // If the response begins with a #!mojo <content-handler-url>, use it. |
276 GURL content_handler_url; | 307 GURL content_handler_url; |
277 std::string shebang; | 308 std::string shebang; |
278 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { | 309 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { |
279 LoadWithContentHandler( | 310 LoadWithContentHandler( |
280 content_handler_url, request.Pass(), | 311 content_handler_url, request.Pass(), |
281 fetcher->AsURLResponse(blocking_pool_, | 312 fetcher->AsURLResponse(blocking_pool_, |
282 static_cast<int>(shebang.size()))); | 313 static_cast<int>(shebang.size()))); |
283 return; | 314 return; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 scoped_ptr<ApplicationLoader> loader, | 422 scoped_ptr<ApplicationLoader> loader, |
392 const std::string& scheme) { | 423 const std::string& scheme) { |
393 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); | 424 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme); |
394 if (it != scheme_to_loader_.end()) | 425 if (it != scheme_to_loader_.end()) |
395 delete it->second; | 426 delete it->second; |
396 scheme_to_loader_[scheme] = loader.release(); | 427 scheme_to_loader_[scheme] = loader.release(); |
397 } | 428 } |
398 | 429 |
399 void ApplicationManager::SetArgsForURL(const std::vector<std::string>& args, | 430 void ApplicationManager::SetArgsForURL(const std::vector<std::string>& args, |
400 const GURL& url) { | 431 const GURL& url) { |
401 url_to_args_[url] = args; | 432 url_to_args_[url].insert(url_to_args_[url].end(), args.begin(), args.end()); |
433 GURL mapped_url = delegate_->ResolveMappings(url); | |
434 if (mapped_url != url) { | |
435 url_to_args_[mapped_url].insert(url_to_args_[mapped_url].end(), | |
436 args.begin(), args.end()); | |
437 } | |
438 GURL resolved_url = delegate_->ResolveURL(mapped_url); | |
439 if (resolved_url != mapped_url) { | |
440 url_to_args_[resolved_url].insert(url_to_args_[resolved_url].end(), | |
441 args.begin(), args.end()); | |
442 } | |
402 } | 443 } |
403 | 444 |
404 void ApplicationManager::SetNativeOptionsForURL( | 445 void ApplicationManager::SetNativeOptionsForURL( |
405 const NativeRunnerFactory::Options& options, | 446 const NativeRunnerFactory::Options& options, |
406 const GURL& url) { | 447 const GURL& url) { |
407 DCHECK(!url.has_query()); // Precondition. | 448 DCHECK(!url.has_query()); // Precondition. |
408 // Apply mappings and resolution to get the resolved URL. | 449 // Apply mappings and resolution to get the resolved URL. |
409 GURL resolved_url = delegate_->ResolveURL(delegate_->ResolveMappings(url)); | 450 GURL resolved_url = delegate_->ResolveURL(delegate_->ResolveMappings(url)); |
410 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. | 451 DCHECK(!resolved_url.has_query()); // Still shouldn't have query. |
411 // TODO(vtl): We should probably also remove/disregard the query string (and | 452 // TODO(vtl): We should probably also remove/disregard the query string (and |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 491 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
451 const GURL& application_url, | 492 const GURL& application_url, |
452 const std::string& interface_name) { | 493 const std::string& interface_name) { |
453 ServiceProviderPtr services; | 494 ServiceProviderPtr services; |
454 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr); | 495 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr); |
455 MessagePipe pipe; | 496 MessagePipe pipe; |
456 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 497 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
457 return pipe.handle0.Pass(); | 498 return pipe.handle0.Pass(); |
458 } | 499 } |
459 | 500 |
460 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { | 501 std::vector<std::string> ApplicationManager::GetArgsForURL(const GURL& url) { |
461 const auto& args_it = url_to_args_.find(url); | 502 const auto& args_it = url_to_args_.find(url); |
462 if (args_it != url_to_args_.end()) | 503 if (args_it != url_to_args_.end()) |
463 return Array<String>::From(args_it->second); | 504 return args_it->second; |
464 return Array<String>(); | 505 return std::vector<std::string>(); |
465 } | 506 } |
466 | 507 |
467 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 508 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
468 native_runners_.erase( | 509 native_runners_.erase( |
469 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 510 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
470 } | 511 } |
471 | 512 |
472 } // namespace shell | 513 } // namespace shell |
473 } // namespace mojo | 514 } // namespace mojo |
OLD | NEW |