| 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 16 matching lines...) Expand all Loading... |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 // Used by TestAPI. | 29 // Used by TestAPI. |
| 30 bool has_created_instance = false; | 30 bool has_created_instance = false; |
| 31 | 31 |
| 32 } // namespace | 32 } // namespace |
| 33 | 33 |
| 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 : manager_(manager), content_handler_url_(content_handler_url) { | 38 const std::string& qualifier) |
| 39 : manager_(manager), |
| 40 content_handler_url_(content_handler_url), |
| 41 content_handler_qualifier_(qualifier) { |
| 39 ServiceProviderPtr services; | 42 ServiceProviderPtr services; |
| 40 manager->ConnectToApplication(content_handler_url, GURL(), | 43 manager->ConnectToApplicationWithParameters( |
| 41 GetProxy(&services), nullptr, | 44 content_handler_url, qualifier, GURL(), GetProxy(&services), nullptr, |
| 42 base::Closure()); | 45 base::Closure(), std::vector<std::string>()); |
| 43 MessagePipe pipe; | 46 MessagePipe pipe; |
| 44 content_handler_.Bind(pipe.handle0.Pass()); | 47 content_handler_.Bind(pipe.handle0.Pass()); |
| 45 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); | 48 services->ConnectToService(ContentHandler::Name_, pipe.handle1.Pass()); |
| 46 content_handler_.set_error_handler(this); | 49 content_handler_.set_error_handler(this); |
| 47 } | 50 } |
| 48 | 51 |
| 49 ContentHandler* content_handler() { return content_handler_.get(); } | 52 ContentHandler* content_handler() { return content_handler_.get(); } |
| 50 | 53 |
| 51 GURL content_handler_url() { return content_handler_url_; } | 54 GURL content_handler_url() { return content_handler_url_; } |
| 55 std::string content_handler_qualifier() { return content_handler_qualifier_; } |
| 52 | 56 |
| 53 private: | 57 private: |
| 54 // ErrorHandler implementation: | 58 // ErrorHandler implementation: |
| 55 void OnConnectionError() override { manager_->OnContentHandlerError(this); } | 59 void OnConnectionError() override { manager_->OnContentHandlerError(this); } |
| 56 | 60 |
| 57 ApplicationManager* manager_; | 61 ApplicationManager* manager_; |
| 58 GURL content_handler_url_; | 62 GURL content_handler_url_; |
| 63 std::string content_handler_qualifier_; |
| 59 ContentHandlerPtr content_handler_; | 64 ContentHandlerPtr content_handler_; |
| 60 | 65 |
| 61 DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection); | 66 DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection); |
| 62 }; | 67 }; |
| 63 | 68 |
| 64 // static | 69 // static |
| 65 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 70 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) |
| 66 : manager_(manager) { | 71 : manager_(manager) { |
| 67 } | 72 } |
| 68 | 73 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 93 STLDeleteValues(&identity_to_shell_impl_); | 98 STLDeleteValues(&identity_to_shell_impl_); |
| 94 } | 99 } |
| 95 | 100 |
| 96 void ApplicationManager::ConnectToApplication( | 101 void ApplicationManager::ConnectToApplication( |
| 97 const GURL& requested_url, | 102 const GURL& requested_url, |
| 98 const GURL& requestor_url, | 103 const GURL& requestor_url, |
| 99 InterfaceRequest<ServiceProvider> services, | 104 InterfaceRequest<ServiceProvider> services, |
| 100 ServiceProviderPtr exposed_services, | 105 ServiceProviderPtr exposed_services, |
| 101 const base::Closure& on_application_end) { | 106 const base::Closure& on_application_end) { |
| 102 ConnectToApplicationWithParameters( | 107 ConnectToApplicationWithParameters( |
| 103 requested_url, requestor_url, services.Pass(), exposed_services.Pass(), | 108 requested_url, std::string(), requestor_url, services.Pass(), |
| 104 on_application_end, std::vector<std::string>()); | 109 exposed_services.Pass(), on_application_end, std::vector<std::string>()); |
| 105 } | 110 } |
| 106 | 111 |
| 107 void ApplicationManager::ConnectToApplicationWithParameters( | 112 void ApplicationManager::ConnectToApplicationWithParameters( |
| 108 const GURL& requested_url, | 113 const GURL& requested_url, |
| 114 const std::string& qualifier, |
| 109 const GURL& requestor_url, | 115 const GURL& requestor_url, |
| 110 InterfaceRequest<ServiceProvider> services, | 116 InterfaceRequest<ServiceProvider> services, |
| 111 ServiceProviderPtr exposed_services, | 117 ServiceProviderPtr exposed_services, |
| 112 const base::Closure& on_application_end, | 118 const base::Closure& on_application_end, |
| 113 const std::vector<std::string>& pre_redirect_parameters) { | 119 const std::vector<std::string>& pre_redirect_parameters) { |
| 114 TRACE_EVENT_INSTANT1( | 120 TRACE_EVENT_INSTANT1( |
| 115 "mojo_shell", "ApplicationManager::ConnectToApplicationWithParameters", | 121 "mojo_shell", "ApplicationManager::ConnectToApplicationWithParameters", |
| 116 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_url.spec()); | 122 TRACE_EVENT_SCOPE_THREAD, "requested_url", requested_url.spec()); |
| 117 DCHECK(requested_url.is_valid()); | 123 DCHECK(requested_url.is_valid()); |
| 118 | 124 |
| 119 // We check both the mapped and resolved urls for existing shell_impls because | 125 // We check both the mapped and resolved urls for existing shell_impls because |
| 120 // external applications can be registered for the unresolved mojo:foo urls. | 126 // external applications can be registered for the unresolved mojo:foo urls. |
| 121 | 127 |
| 122 GURL mapped_url = delegate_->ResolveMappings(requested_url); | 128 GURL mapped_url = delegate_->ResolveMappings(requested_url); |
| 123 if (ConnectToRunningApplication(mapped_url, requestor_url, &services, | 129 if (ConnectToRunningApplication(mapped_url, qualifier, requestor_url, |
| 124 &exposed_services)) { | 130 &services, &exposed_services)) { |
| 125 return; | 131 return; |
| 126 } | 132 } |
| 127 | 133 |
| 128 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); | 134 GURL resolved_url = delegate_->ResolveMojoURL(mapped_url); |
| 129 if (ConnectToRunningApplication(resolved_url, requestor_url, &services, | 135 if (ConnectToRunningApplication(resolved_url, qualifier, requestor_url, |
| 130 &exposed_services)) { | 136 &services, &exposed_services)) { |
| 131 return; | 137 return; |
| 132 } | 138 } |
| 133 | 139 |
| 134 // The application is not running, let's compute the parameters. | 140 // The application is not running, let's compute the parameters. |
| 135 if (ConnectToApplicationWithLoader( | 141 if (ConnectToApplicationWithLoader( |
| 136 requested_url, mapped_url, requestor_url, &services, | 142 requested_url, qualifier, mapped_url, requestor_url, &services, |
| 137 &exposed_services, on_application_end, pre_redirect_parameters, | 143 &exposed_services, on_application_end, pre_redirect_parameters, |
| 138 GetLoaderForURL(mapped_url))) { | 144 GetLoaderForURL(mapped_url))) { |
| 139 return; | 145 return; |
| 140 } | 146 } |
| 141 | 147 |
| 142 if (ConnectToApplicationWithLoader( | 148 if (ConnectToApplicationWithLoader( |
| 143 requested_url, resolved_url, requestor_url, &services, | 149 requested_url, qualifier, resolved_url, requestor_url, &services, |
| 144 &exposed_services, on_application_end, pre_redirect_parameters, | 150 &exposed_services, on_application_end, pre_redirect_parameters, |
| 145 GetLoaderForURL(resolved_url))) { | 151 GetLoaderForURL(resolved_url))) { |
| 146 return; | 152 return; |
| 147 } | 153 } |
| 148 | 154 |
| 149 if (ConnectToApplicationWithLoader( | 155 if (ConnectToApplicationWithLoader( |
| 150 requested_url, resolved_url, requestor_url, &services, | 156 requested_url, qualifier, resolved_url, requestor_url, &services, |
| 151 &exposed_services, on_application_end, pre_redirect_parameters, | 157 &exposed_services, on_application_end, pre_redirect_parameters, |
| 152 default_loader_.get())) { | 158 default_loader_.get())) { |
| 153 return; | 159 return; |
| 154 } | 160 } |
| 155 | 161 |
| 156 auto callback = base::Bind(&ApplicationManager::HandleFetchCallback, | 162 auto callback = base::Bind( |
| 157 weak_ptr_factory_.GetWeakPtr(), requested_url, | 163 &ApplicationManager::HandleFetchCallback, weak_ptr_factory_.GetWeakPtr(), |
| 158 requestor_url, base::Passed(services.Pass()), | 164 requested_url, qualifier, requestor_url, base::Passed(services.Pass()), |
| 159 base::Passed(exposed_services.Pass()), | 165 base::Passed(exposed_services.Pass()), on_application_end, |
| 160 on_application_end, pre_redirect_parameters); | 166 pre_redirect_parameters); |
| 161 | 167 |
| 162 if (resolved_url.SchemeIsFile()) { | 168 if (resolved_url.SchemeIsFile()) { |
| 163 new LocalFetcher( | 169 new LocalFetcher( |
| 164 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), | 170 resolved_url, GetBaseURLAndQuery(resolved_url, nullptr), |
| 165 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE)); | 171 base::Bind(callback, NativeApplicationCleanup::DONT_DELETE)); |
| 166 return; | 172 return; |
| 167 } | 173 } |
| 168 | 174 |
| 169 if (!network_service_) | 175 if (!network_service_) |
| 170 ConnectToService(GURL("mojo:network_service"), &network_service_); | 176 ConnectToService(GURL("mojo:network_service"), &network_service_); |
| 171 | 177 |
| 172 const NativeApplicationCleanup cleanup = | 178 const NativeApplicationCleanup cleanup = |
| 173 base::CommandLine::ForCurrentProcess()->HasSwitch( | 179 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 174 switches::kDontDeleteOnDownload) | 180 switches::kDontDeleteOnDownload) |
| 175 ? NativeApplicationCleanup::DONT_DELETE | 181 ? NativeApplicationCleanup::DONT_DELETE |
| 176 : NativeApplicationCleanup::DELETE; | 182 : NativeApplicationCleanup::DELETE; |
| 177 | 183 |
| 178 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(), | 184 new NetworkFetcher(disable_cache_, resolved_url, network_service_.get(), |
| 179 base::Bind(callback, cleanup)); | 185 base::Bind(callback, cleanup)); |
| 180 } | 186 } |
| 181 | 187 |
| 182 bool ApplicationManager::ConnectToRunningApplication( | 188 bool ApplicationManager::ConnectToRunningApplication( |
| 183 const GURL& resolved_url, | 189 const GURL& resolved_url, |
| 190 const std::string& qualifier, |
| 184 const GURL& requestor_url, | 191 const GURL& requestor_url, |
| 185 InterfaceRequest<ServiceProvider>* services, | 192 InterfaceRequest<ServiceProvider>* services, |
| 186 ServiceProviderPtr* exposed_services) { | 193 ServiceProviderPtr* exposed_services) { |
| 187 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); | 194 GURL application_url = GetBaseURLAndQuery(resolved_url, nullptr); |
| 188 ShellImpl* shell_impl = GetShellImpl(application_url); | 195 ShellImpl* shell_impl = GetShellImpl(application_url, qualifier); |
| 189 if (!shell_impl) | 196 if (!shell_impl) |
| 190 return false; | 197 return false; |
| 191 | 198 |
| 192 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(), | 199 ConnectToClient(shell_impl, resolved_url, requestor_url, services->Pass(), |
| 193 exposed_services->Pass()); | 200 exposed_services->Pass()); |
| 194 return true; | 201 return true; |
| 195 } | 202 } |
| 196 | 203 |
| 197 bool ApplicationManager::ConnectToApplicationWithLoader( | 204 bool ApplicationManager::ConnectToApplicationWithLoader( |
| 198 const GURL& requested_url, | 205 const GURL& requested_url, |
| 206 const std::string& qualifier, |
| 199 const GURL& resolved_url, | 207 const GURL& resolved_url, |
| 200 const GURL& requestor_url, | 208 const GURL& requestor_url, |
| 201 InterfaceRequest<ServiceProvider>* services, | 209 InterfaceRequest<ServiceProvider>* services, |
| 202 ServiceProviderPtr* exposed_services, | 210 ServiceProviderPtr* exposed_services, |
| 203 const base::Closure& on_application_end, | 211 const base::Closure& on_application_end, |
| 204 const std::vector<std::string>& parameters, | 212 const std::vector<std::string>& parameters, |
| 205 ApplicationLoader* loader) { | 213 ApplicationLoader* loader) { |
| 206 if (!loader) | 214 if (!loader) |
| 207 return false; | 215 return false; |
| 208 | 216 |
| 209 const GURL app_url = | 217 const GURL app_url = |
| 210 requested_url.scheme() == "mojo" ? requested_url : resolved_url; | 218 requested_url.scheme() == "mojo" ? requested_url : resolved_url; |
| 211 | 219 |
| 212 loader->Load( | 220 loader->Load( |
| 213 resolved_url, | 221 resolved_url, |
| 214 RegisterShell(app_url, requestor_url, services->Pass(), | 222 RegisterShell(app_url, qualifier, requestor_url, services->Pass(), |
| 215 exposed_services->Pass(), on_application_end, parameters)); | 223 exposed_services->Pass(), on_application_end, parameters)); |
| 216 return true; | 224 return true; |
| 217 } | 225 } |
| 218 | 226 |
| 219 InterfaceRequest<Application> ApplicationManager::RegisterShell( | 227 InterfaceRequest<Application> ApplicationManager::RegisterShell( |
| 220 const GURL& app_url, | 228 const GURL& app_url, |
| 229 const std::string& qualifier, |
| 221 const GURL& requestor_url, | 230 const GURL& requestor_url, |
| 222 InterfaceRequest<ServiceProvider> services, | 231 InterfaceRequest<ServiceProvider> services, |
| 223 ServiceProviderPtr exposed_services, | 232 ServiceProviderPtr exposed_services, |
| 224 const base::Closure& on_application_end, | 233 const base::Closure& on_application_end, |
| 225 const std::vector<std::string>& parameters) { | 234 const std::vector<std::string>& parameters) { |
| 226 Identity app_identity(app_url); | 235 Identity app_identity(app_url, qualifier); |
| 227 | 236 |
| 228 ApplicationPtr application; | 237 ApplicationPtr application; |
| 229 InterfaceRequest<Application> application_request = GetProxy(&application); | 238 InterfaceRequest<Application> application_request = GetProxy(&application); |
| 230 ShellImpl* shell = | 239 ShellImpl* shell = |
| 231 new ShellImpl(application.Pass(), this, app_identity, on_application_end); | 240 new ShellImpl(application.Pass(), this, app_identity, on_application_end); |
| 232 identity_to_shell_impl_[app_identity] = shell; | 241 identity_to_shell_impl_[app_identity] = shell; |
| 233 shell->InitializeApplication(Array<String>::From(parameters)); | 242 shell->InitializeApplication(Array<String>::From(parameters)); |
| 234 ConnectToClient(shell, app_url, requestor_url, services.Pass(), | 243 ConnectToClient(shell, app_url, requestor_url, services.Pass(), |
| 235 exposed_services.Pass()); | 244 exposed_services.Pass()); |
| 236 return application_request.Pass(); | 245 return application_request.Pass(); |
| 237 } | 246 } |
| 238 | 247 |
| 239 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) { | 248 ShellImpl* ApplicationManager::GetShellImpl(const GURL& url, |
| 240 const auto& shell_it = identity_to_shell_impl_.find(Identity(url)); | 249 const std::string& qualifier) { |
| 250 const auto& shell_it = identity_to_shell_impl_.find(Identity(url, qualifier)); |
| 241 if (shell_it != identity_to_shell_impl_.end()) | 251 if (shell_it != identity_to_shell_impl_.end()) |
| 242 return shell_it->second; | 252 return shell_it->second; |
| 243 return nullptr; | 253 return nullptr; |
| 244 } | 254 } |
| 245 | 255 |
| 246 void ApplicationManager::ConnectToClient( | 256 void ApplicationManager::ConnectToClient( |
| 247 ShellImpl* shell_impl, | 257 ShellImpl* shell_impl, |
| 248 const GURL& resolved_url, | 258 const GURL& resolved_url, |
| 249 const GURL& requestor_url, | 259 const GURL& requestor_url, |
| 250 InterfaceRequest<ServiceProvider> services, | 260 InterfaceRequest<ServiceProvider> services, |
| 251 ServiceProviderPtr exposed_services) { | 261 ServiceProviderPtr exposed_services) { |
| 252 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), | 262 shell_impl->ConnectToClient(resolved_url, requestor_url, services.Pass(), |
| 253 exposed_services.Pass()); | 263 exposed_services.Pass()); |
| 254 } | 264 } |
| 255 | 265 |
| 256 void ApplicationManager::HandleFetchCallback( | 266 void ApplicationManager::HandleFetchCallback( |
| 257 const GURL& requested_url, | 267 const GURL& requested_url, |
| 268 const std::string& qualifier, |
| 258 const GURL& requestor_url, | 269 const GURL& requestor_url, |
| 259 InterfaceRequest<ServiceProvider> services, | 270 InterfaceRequest<ServiceProvider> services, |
| 260 ServiceProviderPtr exposed_services, | 271 ServiceProviderPtr exposed_services, |
| 261 const base::Closure& on_application_end, | 272 const base::Closure& on_application_end, |
| 262 const std::vector<std::string>& parameters, | 273 const std::vector<std::string>& parameters, |
| 263 NativeApplicationCleanup cleanup, | 274 NativeApplicationCleanup cleanup, |
| 264 scoped_ptr<Fetcher> fetcher) { | 275 scoped_ptr<Fetcher> fetcher) { |
| 265 if (!fetcher) { | 276 if (!fetcher) { |
| 266 // Network error. Drop |application_request| to tell requestor. | 277 // Network error. Drop |application_request| to tell requestor. |
| 267 return; | 278 return; |
| 268 } | 279 } |
| 269 | 280 |
| 270 GURL redirect_url = fetcher->GetRedirectURL(); | 281 GURL redirect_url = fetcher->GetRedirectURL(); |
| 271 if (!redirect_url.is_empty()) { | 282 if (!redirect_url.is_empty()) { |
| 272 // And around we go again... Whee! | 283 // And around we go again... Whee! |
| 273 // TODO(sky): this loses |requested_url|. | 284 // TODO(sky): this loses |requested_url|. |
| 274 ConnectToApplicationWithParameters(redirect_url, requestor_url, | 285 ConnectToApplicationWithParameters(redirect_url, qualifier, requestor_url, |
| 275 services.Pass(), exposed_services.Pass(), | 286 services.Pass(), exposed_services.Pass(), |
| 276 on_application_end, parameters); | 287 on_application_end, parameters); |
| 277 return; | 288 return; |
| 278 } | 289 } |
| 279 | 290 |
| 280 // 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 |
| 281 // 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 |
| 282 // have two copies of the app running, so check again. | 293 // have two copies of the app running, so check again. |
| 283 // | 294 // |
| 284 // 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 |
| 285 // already running. | 296 // already running. |
| 286 if (ConnectToRunningApplication(requested_url, requestor_url, &services, | 297 if (ConnectToRunningApplication(requested_url, qualifier, requestor_url, |
| 287 &exposed_services)) { | 298 &services, &exposed_services)) { |
| 288 return; | 299 return; |
| 289 } | 300 } |
| 290 | 301 |
| 291 const GURL app_url = | 302 const GURL app_url = |
| 292 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); | 303 requested_url.scheme() == "mojo" ? requested_url : fetcher->GetURL(); |
| 293 | 304 |
| 294 InterfaceRequest<Application> request( | 305 InterfaceRequest<Application> request( |
| 295 RegisterShell(app_url, requestor_url, services.Pass(), | 306 RegisterShell(app_url, qualifier, requestor_url, services.Pass(), |
| 296 exposed_services.Pass(), on_application_end, parameters)); | 307 exposed_services.Pass(), on_application_end, parameters)); |
| 297 | 308 |
| 298 // If the response begins with a #!mojo <content-handler-url>, use it. | 309 // If the response begins with a #!mojo <content-handler-url>, use it. |
| 299 GURL content_handler_url; | 310 GURL content_handler_url; |
| 300 std::string shebang; | 311 std::string shebang; |
| 301 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { | 312 if (fetcher->PeekContentHandler(&shebang, &content_handler_url)) { |
| 302 LoadWithContentHandler( | 313 LoadWithContentHandler( |
| 303 content_handler_url, request.Pass(), | 314 content_handler_url, qualifier, request.Pass(), |
| 304 fetcher->AsURLResponse(blocking_pool_, | 315 fetcher->AsURLResponse(blocking_pool_, |
| 305 static_cast<int>(shebang.size()))); | 316 static_cast<int>(shebang.size()))); |
| 306 return; | 317 return; |
| 307 } | 318 } |
| 308 | 319 |
| 309 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); | 320 MimeTypeToURLMap::iterator iter = mime_type_to_url_.find(fetcher->MimeType()); |
| 310 if (iter != mime_type_to_url_.end()) { | 321 if (iter != mime_type_to_url_.end()) { |
| 311 LoadWithContentHandler(iter->second, request.Pass(), | 322 LoadWithContentHandler(iter->second, qualifier, request.Pass(), |
| 312 fetcher->AsURLResponse(blocking_pool_, 0)); | 323 fetcher->AsURLResponse(blocking_pool_, 0)); |
| 313 return; | 324 return; |
| 314 } | 325 } |
| 315 | 326 |
| 316 auto alias_iter = application_package_alias_.find(app_url); | 327 auto alias_iter = application_package_alias_.find(app_url); |
| 317 if (alias_iter != application_package_alias_.end()) { | 328 if (alias_iter != application_package_alias_.end()) { |
| 329 // We replace the qualifier with the one our package alias requested. |
| 318 URLResponsePtr response(URLResponse::New()); | 330 URLResponsePtr response(URLResponse::New()); |
| 319 response->url = String::From(app_url.spec()); | 331 response->url = String::From(app_url.spec()); |
| 320 LoadWithContentHandler(alias_iter->second, | 332 |
| 321 request.Pass(), | 333 std::string qualifier; |
| 334 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 335 switches::kEnableMultiprocess)) { |
| 336 // Why can't we use this in single process mode? Because of |
| 337 // base::AtExitManager. If you link in ApplicationRunnerChromium into |
| 338 // your code, and then we make initialize multiple copies of the |
| 339 // application, we end up with multiple AtExitManagers and will check on |
| 340 // the second one being created. |
| 341 // |
| 342 // Why doesn't that happen when running different apps? Because |
| 343 // your_thing.mojo!base::AtExitManager and |
| 344 // my_thing.mojo!base::AtExitManager are different symbols. |
| 345 qualifier = alias_iter->second.second; |
| 346 } |
| 347 |
| 348 LoadWithContentHandler(alias_iter->second.first, qualifier, request.Pass(), |
| 322 response.Pass()); | 349 response.Pass()); |
| 323 return; | 350 return; |
| 324 } | 351 } |
| 325 | 352 |
| 326 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo | 353 // TODO(aa): Sanity check that the thing we got looks vaguely like a mojo |
| 327 // application. That could either mean looking for the platform-specific dll | 354 // application. That could either mean looking for the platform-specific dll |
| 328 // header, or looking for some specific mojo signature prepended to the | 355 // header, or looking for some specific mojo signature prepended to the |
| 329 // library. | 356 // library. |
| 330 // TODO(vtl): (Maybe this should be done by the factory/runner?) | 357 // TODO(vtl): (Maybe this should be done by the factory/runner?) |
| 331 | 358 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 } | 400 } |
| 374 | 401 |
| 375 void ApplicationManager::RegisterContentHandler( | 402 void ApplicationManager::RegisterContentHandler( |
| 376 const std::string& mime_type, | 403 const std::string& mime_type, |
| 377 const GURL& content_handler_url) { | 404 const GURL& content_handler_url) { |
| 378 DCHECK(content_handler_url.is_valid()) | 405 DCHECK(content_handler_url.is_valid()) |
| 379 << "Content handler URL is invalid for mime type " << mime_type; | 406 << "Content handler URL is invalid for mime type " << mime_type; |
| 380 mime_type_to_url_[mime_type] = content_handler_url; | 407 mime_type_to_url_[mime_type] = content_handler_url; |
| 381 } | 408 } |
| 382 | 409 |
| 383 | |
| 384 void ApplicationManager::RegisterApplicationPackageAlias( | 410 void ApplicationManager::RegisterApplicationPackageAlias( |
| 385 const GURL& alias, | 411 const GURL& alias, |
| 386 const GURL& content_handler_package) { | 412 const GURL& content_handler_package, |
| 387 application_package_alias_[alias] = content_handler_package; | 413 const std::string& qualifier) { |
| 414 application_package_alias_[alias] = |
| 415 std::make_pair(content_handler_package, qualifier); |
| 388 } | 416 } |
| 389 | 417 |
| 390 void ApplicationManager::LoadWithContentHandler( | 418 void ApplicationManager::LoadWithContentHandler( |
| 391 const GURL& content_handler_url, | 419 const GURL& content_handler_url, |
| 420 const std::string& qualifier, |
| 392 InterfaceRequest<Application> application_request, | 421 InterfaceRequest<Application> application_request, |
| 393 URLResponsePtr url_response) { | 422 URLResponsePtr url_response) { |
| 394 ContentHandlerConnection* connection = nullptr; | 423 ContentHandlerConnection* connection = nullptr; |
| 395 URLToContentHandlerMap::iterator iter = | 424 std::pair<GURL, std::string> key(content_handler_url, qualifier); |
| 396 url_to_content_handler_.find(content_handler_url); | 425 URLToContentHandlerMap::iterator iter = url_to_content_handler_.find(key); |
| 397 if (iter != url_to_content_handler_.end()) { | 426 if (iter != url_to_content_handler_.end()) { |
| 398 connection = iter->second; | 427 connection = iter->second; |
| 399 } else { | 428 } else { |
| 400 connection = new ContentHandlerConnection(this, content_handler_url); | 429 connection = |
| 401 url_to_content_handler_[content_handler_url] = connection; | 430 new ContentHandlerConnection(this, content_handler_url, qualifier); |
| 431 url_to_content_handler_[key] = connection; |
| 402 } | 432 } |
| 403 | 433 |
| 404 connection->content_handler()->StartApplication(application_request.Pass(), | 434 connection->content_handler()->StartApplication(application_request.Pass(), |
| 405 url_response.Pass()); | 435 url_response.Pass()); |
| 406 } | 436 } |
| 407 | 437 |
| 408 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 438 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
| 409 const GURL& url) { | 439 const GURL& url) { |
| 410 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 440 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
| 411 if (it != url_to_loader_.end()) | 441 if (it != url_to_loader_.end()) |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 DCHECK(it != identity_to_shell_impl_.end()); | 486 DCHECK(it != identity_to_shell_impl_.end()); |
| 457 delete it->second; | 487 delete it->second; |
| 458 identity_to_shell_impl_.erase(it); | 488 identity_to_shell_impl_.erase(it); |
| 459 if (!on_application_end.is_null()) | 489 if (!on_application_end.is_null()) |
| 460 on_application_end.Run(); | 490 on_application_end.Run(); |
| 461 } | 491 } |
| 462 | 492 |
| 463 void ApplicationManager::OnContentHandlerError( | 493 void ApplicationManager::OnContentHandlerError( |
| 464 ContentHandlerConnection* content_handler) { | 494 ContentHandlerConnection* content_handler) { |
| 465 // Remove the mapping to the content handler. | 495 // Remove the mapping to the content handler. |
| 466 auto it = | 496 auto it = url_to_content_handler_.find( |
| 467 url_to_content_handler_.find(content_handler->content_handler_url()); | 497 std::make_pair(content_handler->content_handler_url(), |
| 498 content_handler->content_handler_qualifier())); |
| 468 DCHECK(it != url_to_content_handler_.end()); | 499 DCHECK(it != url_to_content_handler_.end()); |
| 469 delete it->second; | 500 delete it->second; |
| 470 url_to_content_handler_.erase(it); | 501 url_to_content_handler_.erase(it); |
| 471 } | 502 } |
| 472 | 503 |
| 473 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 504 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 474 const GURL& application_url, | 505 const GURL& application_url, |
| 475 const std::string& interface_name) { | 506 const std::string& interface_name) { |
| 476 ServiceProviderPtr services; | 507 ServiceProviderPtr services; |
| 477 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr, | 508 ConnectToApplication(application_url, GURL(), GetProxy(&services), nullptr, |
| 478 base::Closure()); | 509 base::Closure()); |
| 479 MessagePipe pipe; | 510 MessagePipe pipe; |
| 480 services->ConnectToService(interface_name, pipe.handle1.Pass()); | 511 services->ConnectToService(interface_name, pipe.handle1.Pass()); |
| 481 return pipe.handle0.Pass(); | 512 return pipe.handle0.Pass(); |
| 482 } | 513 } |
| 483 | 514 |
| 484 void ApplicationManager::CleanupRunner(NativeRunner* runner) { | 515 void ApplicationManager::CleanupRunner(NativeRunner* runner) { |
| 485 native_runners_.erase( | 516 native_runners_.erase( |
| 486 std::find(native_runners_.begin(), native_runners_.end(), runner)); | 517 std::find(native_runners_.begin(), native_runners_.end(), runner)); |
| 487 } | 518 } |
| 488 | 519 |
| 489 } // namespace shell | 520 } // namespace shell |
| 490 } // namespace mojo | 521 } // namespace mojo |
| OLD | NEW |