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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 TerminateShellConnections(); | 62 TerminateShellConnections(); |
63 STLDeleteValues(&url_to_loader_); | 63 STLDeleteValues(&url_to_loader_); |
64 STLDeleteValues(&scheme_to_loader_); | 64 STLDeleteValues(&scheme_to_loader_); |
65 } | 65 } |
66 | 66 |
67 void ApplicationManager::TerminateShellConnections() { | 67 void ApplicationManager::TerminateShellConnections() { |
68 STLDeleteValues(&identity_to_instance_); | 68 STLDeleteValues(&identity_to_instance_); |
69 } | 69 } |
70 | 70 |
71 void ApplicationManager::ConnectToApplication( | 71 void ApplicationManager::ConnectToApplication( |
| 72 ApplicationInstance* originator, |
72 mojo::URLRequestPtr requested_url, | 73 mojo::URLRequestPtr requested_url, |
73 const std::string& qualifier, | 74 const std::string& qualifier, |
74 const GURL& requestor_url, | 75 const GURL& requestor_url, |
75 InterfaceRequest<ServiceProvider> services, | 76 InterfaceRequest<ServiceProvider> services, |
76 ServiceProviderPtr exposed_services, | 77 ServiceProviderPtr exposed_services, |
| 78 CapabilityFilterPtr filter, |
77 const base::Closure& on_application_end) { | 79 const base::Closure& on_application_end) { |
78 GURL requested_gurl(requested_url->url.To<std::string>()); | 80 GURL requested_gurl(requested_url->url.To<std::string>()); |
79 TRACE_EVENT_INSTANT1( | 81 TRACE_EVENT_INSTANT1( |
80 "mojo_shell", "ApplicationManager::ConnectToApplication", | 82 "mojo_shell", "ApplicationManager::ConnectToApplication", |
81 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_gurl.spec()); | 83 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_gurl.spec()); |
82 DCHECK(requested_gurl.is_valid()); | 84 DCHECK(requested_gurl.is_valid()); |
83 | 85 |
84 // We check both the mapped and resolved urls for existing instances because | 86 // We check both the mapped and resolved urls for existing instances because |
85 // external applications can be registered for the unresolved mojo:foo urls. | 87 // external applications can be registered for the unresolved mojo:foo urls. |
86 | 88 |
87 GURL mapped_url = delegate_->ResolveMappings(requested_gurl); | 89 GURL mapped_url = delegate_->ResolveMappings(requested_gurl); |
88 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, | 90 if (ConnectToRunningApplication(originator, mapped_url, qualifier, |
89 &services, &exposed_services)) { | 91 requestor_url, &services, |
| 92 &exposed_services, &filter)) { |
90 return; | 93 return; |
91 } | 94 } |
92 | 95 |
93 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); | 96 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); |
94 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, | 97 if (ConnectToRunningApplication(originator, resolved_url, qualifier, |
95 &services, &exposed_services)) { | 98 requestor_url, &services, |
| 99 &exposed_services, &filter)) { |
96 return; | 100 return; |
97 } | 101 } |
98 | 102 |
99 // The application is not running, let's compute the parameters. | 103 // The application is not running, let's compute the parameters. |
100 if (ConnectToApplicationWithLoader( | 104 if (ConnectToApplicationWithLoader( |
101 requested_gurl, qualifier, mapped_url, requestor_url, &services, | 105 originator, requested_gurl, qualifier, mapped_url, requestor_url, |
102 &exposed_services, on_application_end, GetLoaderForURL(mapped_url))) { | 106 &services, &exposed_services, &filter, on_application_end, |
| 107 GetLoaderForURL(mapped_url))) { |
103 return; | 108 return; |
104 } | 109 } |
105 | 110 |
106 if (ConnectToApplicationWithLoader( | 111 if (ConnectToApplicationWithLoader( |
107 requested_gurl, qualifier, resolved_url, requestor_url, &services, | 112 originator, requested_gurl, qualifier, resolved_url, requestor_url, |
108 &exposed_services, on_application_end, | 113 &services, &exposed_services, &filter, on_application_end, |
109 GetLoaderForURL(resolved_url))) { | 114 GetLoaderForURL(resolved_url))) { |
110 return; | 115 return; |
111 } | 116 } |
112 | 117 |
113 if (ConnectToApplicationWithLoader( | 118 if (ConnectToApplicationWithLoader( |
114 requested_gurl, qualifier, resolved_url, requestor_url, &services, | 119 originator, requested_gurl, qualifier, resolved_url, requestor_url, |
115 &exposed_services, on_application_end, default_loader_.get())) { | 120 &services, &exposed_services, &filter, on_application_end, |
| 121 default_loader_.get())) { |
116 return; | 122 return; |
117 } | 123 } |
118 | 124 |
119 auto callback = base::Bind( | 125 auto callback = base::Bind( |
120 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), | 126 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
121 requested_gurl, qualifier, requestor_url, base::Passed(services.Pass()), | 127 originator, requested_gurl, qualifier, requestor_url, |
122 base::Passed(exposed_services.Pass()), on_application_end); | 128 base::Passed(services.Pass()), base::Passed(exposed_services.Pass()), |
| 129 base::Passed(filter.Pass()), |
| 130 on_application_end); |
123 | 131 |
124 if (delegate_->CreateFetcher( | 132 if (delegate_->CreateFetcher( |
125 resolved_url, | 133 resolved_url, |
126 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { | 134 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE))) { |
127 return; | 135 return; |
128 } | 136 } |
129 | 137 |
130 if (resolved_url.SchemeIsFile()) { | 138 if (resolved_url.SchemeIsFile()) { |
131 new LocalFetcher( | 139 new LocalFetcher( |
132 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 140 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
(...skipping 28 matching lines...) Expand all Loading... |
161 url_loader_factory_.get(), | 169 url_loader_factory_.get(), |
162 base::Bind(callback, cleanup)); | 170 base::Bind(callback, cleanup)); |
163 return; | 171 return; |
164 } | 172 } |
165 | 173 |
166 new NetworkFetcher(disable_cache_, requested_url.Pass(), | 174 new NetworkFetcher(disable_cache_, requested_url.Pass(), |
167 url_loader_factory_.get(), base::Bind(callback, cleanup)); | 175 url_loader_factory_.get(), base::Bind(callback, cleanup)); |
168 } | 176 } |
169 | 177 |
170 bool ApplicationManager::ConnectToRunningApplication( | 178 bool ApplicationManager::ConnectToRunningApplication( |
| 179 ApplicationInstance* originator, |
171 const GURL& resolved_url, | 180 const GURL& resolved_url, |
172 const std::string& qualifier, | 181 const std::string& qualifier, |
173 const GURL& requestor_url, | 182 const GURL& requestor_url, |
174 InterfaceRequest<ServiceProvider>* services, | 183 InterfaceRequest<ServiceProvider>* services, |
175 ServiceProviderPtr* exposed_services) { | 184 ServiceProviderPtr* exposed_services, |
| 185 CapabilityFilterPtr* filter) { |
176 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); | 186 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); |
177 ApplicationInstance* instance = | 187 ApplicationInstance* instance = |
178 GetApplicationInstance(application_url, qualifier); | 188 GetApplicationInstance(application_url, qualifier); |
179 if (!instance) | 189 if (!instance) |
180 return false; | 190 return false; |
181 | 191 |
182 ConnectToClient(instance, resolved_url, requestor_url, services->Pass(), | 192 instance->ConnectToClient(originator, resolved_url, requestor_url, |
183 exposed_services->Pass()); | 193 services->Pass(), exposed_services->Pass(), |
| 194 filter->Pass()); |
184 return true; | 195 return true; |
185 } | 196 } |
186 | 197 |
187 bool ApplicationManager::ConnectToApplicationWithLoader( | 198 bool ApplicationManager::ConnectToApplicationWithLoader( |
| 199 ApplicationInstance* originator, |
188 const GURL& requested_url, | 200 const GURL& requested_url, |
189 const std::string& qualifier, | 201 const std::string& qualifier, |
190 const GURL& resolved_url, | 202 const GURL& resolved_url, |
191 const GURL& requestor_url, | 203 const GURL& requestor_url, |
192 InterfaceRequest<ServiceProvider>* services, | 204 InterfaceRequest<ServiceProvider>* services, |
193 ServiceProviderPtr* exposed_services, | 205 ServiceProviderPtr* exposed_services, |
| 206 CapabilityFilterPtr* filter, |
194 const base::Closure& on_application_end, | 207 const base::Closure& on_application_end, |
195 ApplicationLoader* loader) { | 208 ApplicationLoader* loader) { |
196 if (!loader) | 209 if (!loader) |
197 return false; | 210 return false; |
198 | 211 |
199 const GURL app_url = | 212 const GURL app_url = |
200 requested_url.SchemeIs("mojo") ? requested_url : resolved_url; | 213 requested_url.SchemeIs("mojo") ? requested_url : resolved_url; |
201 | 214 |
202 loader->Load( | 215 loader->Load( |
203 resolved_url, | 216 resolved_url, |
204 RegisterInstance(app_url, qualifier, requestor_url, services->Pass(), | 217 RegisterInstance(originator, app_url, qualifier, requestor_url, |
205 exposed_services->Pass(), on_application_end)); | 218 services->Pass(), exposed_services->Pass(), |
| 219 filter->Pass(), on_application_end)); |
206 return true; | 220 return true; |
207 } | 221 } |
208 | 222 |
209 InterfaceRequest<Application> ApplicationManager::RegisterInstance( | 223 InterfaceRequest<Application> ApplicationManager::RegisterInstance( |
| 224 ApplicationInstance* originator, |
210 const GURL& app_url, | 225 const GURL& app_url, |
211 const std::string& qualifier, | 226 const std::string& qualifier, |
212 const GURL& requestor_url, | 227 const GURL& requestor_url, |
213 InterfaceRequest<ServiceProvider> services, | 228 InterfaceRequest<ServiceProvider> services, |
214 ServiceProviderPtr exposed_services, | 229 ServiceProviderPtr exposed_services, |
| 230 CapabilityFilterPtr filter, |
215 const base::Closure& on_application_end) { | 231 const base::Closure& on_application_end) { |
216 Identity app_identity(app_url, qualifier); | 232 Identity app_identity(app_url, qualifier); |
217 | 233 |
218 ApplicationPtr application; | 234 ApplicationPtr application; |
219 InterfaceRequest<Application> application_request = GetProxy(&application); | 235 InterfaceRequest<Application> application_request = GetProxy(&application); |
220 ApplicationInstance* instance = new ApplicationInstance(application.Pass(), | 236 ApplicationInstance::CapabilityFilter capability_filter; |
221 this, | 237 std::set<std::string> interfaces; |
222 app_identity, | 238 interfaces.insert("*"); |
223 on_application_end); | 239 capability_filter["*"] = interfaces; |
| 240 if (!filter.is_null()) { |
| 241 capability_filter = |
| 242 filter->filter.To<ApplicationInstance::CapabilityFilter>(); |
| 243 } |
| 244 ApplicationInstance* instance = new ApplicationInstance( |
| 245 application.Pass(), this, app_identity, capability_filter, |
| 246 on_application_end); |
224 identity_to_instance_[app_identity] = instance; | 247 identity_to_instance_[app_identity] = instance; |
225 instance->InitializeApplication(); | 248 instance->InitializeApplication(); |
226 ConnectToClient(instance, app_url, requestor_url, services.Pass(), | 249 instance->ConnectToClient(originator, app_url, requestor_url, services.Pass(), |
227 exposed_services.Pass()); | 250 exposed_services.Pass(), filter.Pass()); |
228 return application_request.Pass(); | 251 return application_request.Pass(); |
229 } | 252 } |
230 | 253 |
231 ApplicationInstance* ApplicationManager::GetApplicationInstance( | 254 ApplicationInstance* ApplicationManager::GetApplicationInstance( |
232 const GURL& url, | 255 const GURL& url, |
233 const std::string& qualifier) { | 256 const std::string& qualifier) { |
234 const auto& instance_it = | 257 const auto& instance_it = |
235 identity_to_instance_.find(Identity(url, qualifier)); | 258 identity_to_instance_.find(Identity(url, qualifier)); |
236 if (instance_it != identity_to_instance_.end()) | 259 if (instance_it != identity_to_instance_.end()) |
237 return instance_it->second; | 260 return instance_it->second; |
238 return nullptr; | 261 return nullptr; |
239 } | 262 } |
240 | 263 |
241 void ApplicationManager::ConnectToClient( | |
242 ApplicationInstance* instance, | |
243 const GURL& resolved_url, | |
244 const GURL& requestor_url, | |
245 InterfaceRequest<ServiceProvider> services, | |
246 ServiceProviderPtr exposed_services) { | |
247 instance->ConnectToClient(resolved_url, requestor_url, services.Pass(), | |
248 exposed_services.Pass()); | |
249 } | |
250 | |
251 void ApplicationManager::HandleFetchCallback( | 264 void ApplicationManager::HandleFetchCallback( |
| 265 ApplicationInstance* originator, |
252 const GURL& requested_url, | 266 const GURL& requested_url, |
253 const std::string& qualifier, | 267 const std::string& qualifier, |
254 const GURL& requestor_url, | 268 const GURL& requestor_url, |
255 InterfaceRequest<ServiceProvider> services, | 269 InterfaceRequest<ServiceProvider> services, |
256 ServiceProviderPtr exposed_services, | 270 ServiceProviderPtr exposed_services, |
| 271 CapabilityFilterPtr filter, |
257 const base::Closure& on_application_end, | 272 const base::Closure& on_application_end, |
258 NativeApplicationCleanup cleanup, | 273 NativeApplicationCleanup cleanup, |
259 scoped_ptr<Fetcher> fetcher) { | 274 scoped_ptr<Fetcher> fetcher) { |
260 if (!fetcher) { | 275 if (!fetcher) { |
261 // Network error. Drop |application_request| to tell requestor. | 276 // Network error. Drop |application_request| to tell requestor. |
262 return; | 277 return; |
263 } | 278 } |
264 | 279 |
265 GURL redirect_url = fetcher->GetRedirectURL(); | 280 GURL redirect_url = fetcher->GetRedirectURL(); |
266 if (!redirect_url.is_empty()) { | 281 if (!redirect_url.is_empty()) { |
267 // And around we go again... Whee! | 282 // And around we go again... Whee! |
268 // TODO(sky): this loses |requested_url|. | 283 // TODO(sky): this loses |requested_url|. |
269 mojo::URLRequestPtr request(mojo::URLRequest::New()); | 284 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
270 request->url = mojo::String::From(redirect_url.spec()); | 285 request->url = mojo::String::From(redirect_url.spec()); |
271 HttpHeaderPtr header = HttpHeader::New(); | 286 HttpHeaderPtr header = HttpHeader::New(); |
272 header->name = "Referer"; | 287 header->name = "Referer"; |
273 header->value = fetcher->GetRedirectReferer().spec(); | 288 header->value = fetcher->GetRedirectReferer().spec(); |
274 request->headers.push_back(header.Pass()); | 289 request->headers.push_back(header.Pass()); |
275 ConnectToApplication(request.Pass(), qualifier, requestor_url, | 290 ConnectToApplication(originator, request.Pass(), qualifier, requestor_url, |
276 services.Pass(), exposed_services.Pass(), | 291 services.Pass(), exposed_services.Pass(), nullptr, |
277 on_application_end); | 292 on_application_end); |
278 return; | 293 return; |
279 } | 294 } |
280 | 295 |
281 // We already checked if the application was running before we fetched it, but | 296 // We already checked if the application was running before we fetched it, but |
282 // it might have started while the fetch was outstanding. We don't want to | 297 // it might have started while the fetch was outstanding. We don't want to |
283 // have two copies of the app running, so check again. | 298 // have two copies of the app running, so check again. |
284 // | 299 // |
285 // Also, it's possible the original URL was redirected to an app that is | 300 // Also, it's possible the original URL was redirected to an app that is |
286 // already running. | 301 // already running. |
287 if (ConnectToRunningApplication(requested_url, qualifier, requestor_url, | 302 if (ConnectToRunningApplication(originator, requested_url, qualifier, |
288 &services, &exposed_services)) { | 303 requestor_url, &services, |
| 304 &exposed_services, &filter)) { |
289 return; | 305 return; |
290 } | 306 } |
291 | 307 |
292 const GURL app_url = | 308 const GURL app_url = |
293 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); | 309 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); |
294 | 310 |
295 InterfaceRequest<Application> request( | 311 InterfaceRequest<Application> request( |
296 RegisterInstance(app_url, qualifier, requestor_url, services.Pass(), | 312 RegisterInstance(originator, app_url, qualifier, requestor_url, |
297 exposed_services.Pass(), on_application_end)); | 313 services.Pass(), exposed_services.Pass(), filter.Pass(), |
| 314 on_application_end)); |
298 | 315 |
299 // For resources that are loaded with content handlers, we group app instances | 316 // For resources that are loaded with content handlers, we group app instances |
300 // by site. | 317 // by site. |
301 | 318 |
302 // If the response begins with a #!mojo <content-handler-url>, use it. | 319 // If the response begins with a #!mojo <content-handler-url>, use it. |
303 GURL content_handler_url; | 320 GURL content_handler_url; |
304 std::string shebang; | 321 std::string shebang; |
305 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( | 322 bool enable_multi_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
306 switches::kEnableMultiprocess); | 323 switches::kEnableMultiprocess); |
307 | 324 |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 void ApplicationManager::OnContentHandlerConnectionClosed( | 513 void ApplicationManager::OnContentHandlerConnectionClosed( |
497 ContentHandlerConnection* content_handler) { | 514 ContentHandlerConnection* content_handler) { |
498 // Remove the mapping to the content handler. | 515 // Remove the mapping to the content handler. |
499 auto it = url_to_content_handler_.find( | 516 auto it = url_to_content_handler_.find( |
500 std::make_pair(content_handler->content_handler_url(), | 517 std::make_pair(content_handler->content_handler_url(), |
501 content_handler->content_handler_qualifier())); | 518 content_handler->content_handler_qualifier())); |
502 DCHECK(it != url_to_content_handler_.end()); | 519 DCHECK(it != url_to_content_handler_.end()); |
503 url_to_content_handler_.erase(it); | 520 url_to_content_handler_.erase(it); |
504 } | 521 } |
505 | 522 |
| 523 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 524 native_runners_.erase( |
| 525 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
| 526 } |
| 527 |
506 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 528 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
507 const GURL& application_url, | 529 const GURL& application_url, |
508 const std::string& interface_name) { | 530 const std::string& interface_name) { |
509 ServiceProviderPtr services; | 531 ServiceProviderPtr services; |
510 mojo::URLRequestPtr request(mojo::URLRequest::New()); | 532 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
511 request->url = mojo::String::From(application_url.spec()); | 533 request->url = mojo::String::From(application_url.spec()); |
512 ConnectToApplication(request.Pass(), std::string(), GURL(), | 534 ConnectToApplication(nullptr, request.Pass(), std::string(), GURL(), |
513 GetProxy(&services), nullptr, base::Closure()); | 535 GetProxy(&services), nullptr, nullptr, base::Closure()); |
514 MessagePipe pipe; | 536 MessagePipe pipe; |
515 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 537 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
516 return pipe.handle0.Pass(); | 538 return pipe.handle0.Pass(); |
517 } | 539 } |
518 | 540 |
519 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | |
520 native_runners_.erase( | |
521 std::find(native_runners_.begin(), native_runners_.end(), runner)); | |
522 } | |
523 | |
524 } // namespace shell | 541 } // namespace shell |
525 } // namespace mojo | 542 } // namespace mojo |
OLD | NEW |