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