| 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/application_manager/application_manager.h" | 5 #include "mojo/application_manager/application_manager.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { | 44 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { |
| 45 LOG(ERROR) << "Communication error with application: " << url.spec(); | 45 LOG(ERROR) << "Communication error with application: " << url.spec(); |
| 46 } | 46 } |
| 47 | 47 |
| 48 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { | 48 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { |
| 49 return url; | 49 return url; |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 class ApplicationManager::LoadCallbacksImpl | |
| 54 : public ApplicationLoader::LoadCallbacks { | |
| 55 public: | |
| 56 LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager, | |
| 57 const GURL& requested_url, | |
| 58 const GURL& resolved_url, | |
| 59 const GURL& requestor_url, | |
| 60 ServiceProviderPtr service_provider) | |
| 61 : manager_(manager), | |
| 62 requested_url_(requested_url), | |
| 63 resolved_url_(resolved_url), | |
| 64 requestor_url_(requestor_url), | |
| 65 service_provider_(service_provider.Pass()) {} | |
| 66 | |
| 67 private: | |
| 68 ~LoadCallbacksImpl() override {} | |
| 69 | |
| 70 // LoadCallbacks implementation | |
| 71 ScopedMessagePipeHandle RegisterApplication() override { | |
| 72 ScopedMessagePipeHandle shell_handle; | |
| 73 if (manager_) { | |
| 74 manager_->RegisterLoadedApplication(requested_url_, | |
| 75 resolved_url_, | |
| 76 requestor_url_, | |
| 77 service_provider_.Pass(), | |
| 78 &shell_handle); | |
| 79 } | |
| 80 return shell_handle.Pass(); | |
| 81 } | |
| 82 | |
| 83 void LoadWithContentHandler(const GURL& content_handler_url, | |
| 84 URLResponsePtr url_response) override { | |
| 85 if (manager_) { | |
| 86 manager_->LoadWithContentHandler(requested_url_, | |
| 87 resolved_url_, | |
| 88 requestor_url_, | |
| 89 content_handler_url, | |
| 90 url_response.Pass(), | |
| 91 service_provider_.Pass()); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 base::WeakPtr<ApplicationManager> manager_; | |
| 96 GURL requested_url_; | |
| 97 GURL resolved_url_; | |
| 98 GURL requestor_url_; | |
| 99 ServiceProviderPtr service_provider_; | |
| 100 }; | |
| 101 | |
| 102 class ApplicationManager::ShellImpl : public Shell, public ErrorHandler { | 53 class ApplicationManager::ShellImpl : public Shell, public ErrorHandler { |
| 103 public: | 54 public: |
| 104 ShellImpl(ScopedMessagePipeHandle handle, | 55 ShellImpl(ScopedMessagePipeHandle handle, |
| 105 ApplicationManager* manager, | 56 ApplicationManager* manager, |
| 106 const GURL& requested_url, | 57 const GURL& requested_url, |
| 107 const GURL& url) | 58 const GURL& url) |
| 108 : ShellImpl(manager, requested_url, url) { | 59 : ShellImpl(manager, requested_url, url) { |
| 109 binding_.Bind(handle.Pass()); | 60 binding_.Bind(handle.Pass()); |
| 110 } | 61 } |
| 111 | 62 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 166 |
| 216 ApplicationManager::~ApplicationManager() { | 167 ApplicationManager::~ApplicationManager() { |
| 217 STLDeleteValues(&url_to_content_handler_); | 168 STLDeleteValues(&url_to_content_handler_); |
| 218 TerminateShellConnections(); | 169 TerminateShellConnections(); |
| 219 STLDeleteValues(&url_to_loader_); | 170 STLDeleteValues(&url_to_loader_); |
| 220 STLDeleteValues(&scheme_to_loader_); | 171 STLDeleteValues(&scheme_to_loader_); |
| 221 } | 172 } |
| 222 | 173 |
| 223 void ApplicationManager::TerminateShellConnections() { | 174 void ApplicationManager::TerminateShellConnections() { |
| 224 STLDeleteValues(&url_to_shell_impl_); | 175 STLDeleteValues(&url_to_shell_impl_); |
| 225 STLDeleteElements(&content_shell_impls_); | |
| 226 } | 176 } |
| 227 | 177 |
| 228 void ApplicationManager::ConnectToApplication( | 178 void ApplicationManager::ConnectToApplication( |
| 229 const GURL& requested_url, | 179 const GURL& requested_url, |
| 230 const GURL& requestor_url, | 180 const GURL& requestor_url, |
| 231 ServiceProviderPtr service_provider) { | 181 ServiceProviderPtr service_provider) { |
| 232 ApplicationLoader* loader = GetLoaderForURL(requested_url, | 182 ApplicationLoader* loader = GetLoaderForURL(requested_url, |
| 233 DONT_INCLUDE_DEFAULT_LOADER); | 183 DONT_INCLUDE_DEFAULT_LOADER); |
| 234 if (loader) { | 184 if (loader) { |
| 235 ConnectToApplicationImpl(requested_url, requested_url, requestor_url, | 185 ConnectToApplicationImpl(requested_url, requested_url, requestor_url, |
| 236 service_provider.Pass(), loader); | 186 service_provider.Pass(), loader); |
| 237 return; | 187 return; |
| 238 } | 188 } |
| 239 | 189 |
| 240 GURL resolved_url = delegate_->ResolveURL(requested_url); | 190 GURL resolved_url = delegate_->ResolveURL(requested_url); |
| 241 loader = GetLoaderForURL(resolved_url, INCLUDE_DEFAULT_LOADER); | 191 loader = GetLoaderForURL(resolved_url, INCLUDE_DEFAULT_LOADER); |
| 242 if (loader) { | 192 if (loader) { |
| 243 ConnectToApplicationImpl(requested_url, resolved_url, requestor_url, | 193 ConnectToApplicationImpl(requested_url, resolved_url, requestor_url, |
| 244 service_provider.Pass(), loader); | 194 service_provider.Pass(), loader); |
| 245 return; | 195 return; |
| 246 } | 196 } |
| 247 | 197 |
| 248 LOG(WARNING) << "Could not find loader to load application: " | 198 LOG(WARNING) << "Could not find loader to load application: " |
| 249 << requested_url.spec(); | 199 << requested_url.spec(); |
| 250 } | 200 } |
| 251 | 201 |
| 252 void ApplicationManager::ConnectToApplicationImpl( | 202 void ApplicationManager::ConnectToApplicationImpl( |
| 253 const GURL& requested_url, const GURL& resolved_url, | 203 const GURL& requested_url, |
| 254 const GURL& requestor_url, ServiceProviderPtr service_provider, | 204 const GURL& resolved_url, |
| 205 const GURL& requestor_url, |
| 206 ServiceProviderPtr service_provider, |
| 255 ApplicationLoader* loader) { | 207 ApplicationLoader* loader) { |
| 208 ShellImpl* shell = nullptr; |
| 256 URLToShellImplMap::const_iterator shell_it = | 209 URLToShellImplMap::const_iterator shell_it = |
| 257 url_to_shell_impl_.find(resolved_url); | 210 url_to_shell_impl_.find(resolved_url); |
| 258 if (shell_it != url_to_shell_impl_.end()) { | 211 if (shell_it != url_to_shell_impl_.end()) { |
| 259 ConnectToClient(shell_it->second, resolved_url, requestor_url, | 212 shell = shell_it->second; |
| 260 service_provider.Pass()); | 213 } else { |
| 261 return; | 214 MessagePipe pipe; |
| 215 shell = |
| 216 new ShellImpl(pipe.handle0.Pass(), this, requested_url, resolved_url); |
| 217 url_to_shell_impl_[resolved_url] = shell; |
| 218 shell->client()->Initialize(GetArgsForURL(requested_url)); |
| 219 |
| 220 loader->Load(this, resolved_url, pipe.handle1.Pass(), |
| 221 base::Bind(&ApplicationManager::LoadWithContentHandler, |
| 222 weak_ptr_factory_.GetWeakPtr())); |
| 262 } | 223 } |
| 263 | 224 ConnectToClient(shell, resolved_url, requestor_url, service_provider.Pass()); |
| 264 scoped_refptr<LoadCallbacksImpl> callbacks( | |
| 265 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), | |
| 266 requested_url, | |
| 267 resolved_url, | |
| 268 requestor_url, | |
| 269 service_provider.Pass())); | |
| 270 loader->Load(this, resolved_url, callbacks); | |
| 271 } | 225 } |
| 272 | 226 |
| 273 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, | 227 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, |
| 274 const GURL& url, | 228 const GURL& url, |
| 275 const GURL& requestor_url, | 229 const GURL& requestor_url, |
| 276 ServiceProviderPtr service_provider) { | 230 ServiceProviderPtr service_provider) { |
| 277 if (interceptor_) { | 231 if (interceptor_) { |
| 278 shell_impl->ConnectToClient( | 232 shell_impl->ConnectToClient( |
| 279 requestor_url, | 233 requestor_url, |
| 280 interceptor_->OnConnectToClient(url, service_provider.Pass())); | 234 interceptor_->OnConnectToClient(url, service_provider.Pass())); |
| 281 } else { | 235 } else { |
| 282 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); | 236 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); |
| 283 } | 237 } |
| 284 } | 238 } |
| 285 | 239 |
| 286 void ApplicationManager::RegisterExternalApplication( | 240 void ApplicationManager::RegisterExternalApplication( |
| 287 const GURL& url, | 241 const GURL& url, |
| 288 ScopedMessagePipeHandle shell_handle) { | 242 ScopedMessagePipeHandle shell_handle) { |
| 289 ShellImpl* shell_impl = new ShellImpl(shell_handle.Pass(), this, url, url); | 243 ShellImpl* shell_impl = new ShellImpl(shell_handle.Pass(), this, url, url); |
| 290 url_to_shell_impl_[url] = shell_impl; | 244 url_to_shell_impl_[url] = shell_impl; |
| 291 | 245 |
| 292 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | 246 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); |
| 293 Array<String> args; | 247 Array<String> args; |
| 294 if (args_it != url_to_args_.end()) | 248 if (args_it != url_to_args_.end()) |
| 295 args = Array<String>::From(args_it->second); | 249 args = Array<String>::From(args_it->second); |
| 296 shell_impl->client()->Initialize(args.Pass()); | 250 shell_impl->client()->Initialize(args.Pass()); |
| 297 } | 251 } |
| 298 | 252 |
| 299 void ApplicationManager::RegisterLoadedApplication( | |
| 300 const GURL& requested_url, | |
| 301 const GURL& resolved_url, | |
| 302 const GURL& requestor_url, | |
| 303 ServiceProviderPtr service_provider, | |
| 304 ScopedMessagePipeHandle* shell_handle) { | |
| 305 ShellImpl* shell_impl = NULL; | |
| 306 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(resolved_url); | |
| 307 if (iter != url_to_shell_impl_.end()) { | |
| 308 // This can happen because services are loaded asynchronously. So if we get | |
| 309 // two requests for the same service close to each other, we might get here | |
| 310 // and find that we already have it. | |
| 311 shell_impl = iter->second; | |
| 312 } else { | |
| 313 MessagePipe pipe; | |
| 314 shell_impl = | |
| 315 new ShellImpl(pipe.handle1.Pass(), this, requested_url, resolved_url); | |
| 316 url_to_shell_impl_[resolved_url] = shell_impl; | |
| 317 *shell_handle = pipe.handle0.Pass(); | |
| 318 shell_impl->client()->Initialize(GetArgsForURL(requested_url)); | |
| 319 } | |
| 320 | |
| 321 ConnectToClient(shell_impl, resolved_url, requestor_url, | |
| 322 service_provider.Pass()); | |
| 323 } | |
| 324 | |
| 325 void ApplicationManager::LoadWithContentHandler( | 253 void ApplicationManager::LoadWithContentHandler( |
| 326 const GURL& requested_url, | |
| 327 const GURL& resolved_url, | |
| 328 const GURL& requestor_url, | |
| 329 const GURL& content_handler_url, | 254 const GURL& content_handler_url, |
| 330 URLResponsePtr url_response, | 255 ScopedMessagePipeHandle shell_handle, |
| 331 ServiceProviderPtr service_provider) { | 256 URLResponsePtr url_response) { |
| 332 ContentHandlerConnection* connection = NULL; | 257 ContentHandlerConnection* connection = NULL; |
| 333 URLToContentHandlerMap::iterator iter = | 258 URLToContentHandlerMap::iterator iter = |
| 334 url_to_content_handler_.find(content_handler_url); | 259 url_to_content_handler_.find(content_handler_url); |
| 335 if (iter != url_to_content_handler_.end()) { | 260 if (iter != url_to_content_handler_.end()) { |
| 336 connection = iter->second; | 261 connection = iter->second; |
| 337 } else { | 262 } else { |
| 338 connection = new ContentHandlerConnection(this, content_handler_url); | 263 connection = new ContentHandlerConnection(this, content_handler_url); |
| 339 url_to_content_handler_[content_handler_url] = connection; | 264 url_to_content_handler_[content_handler_url] = connection; |
| 340 } | 265 } |
| 341 | 266 |
| 342 ShellPtr shell_proxy; | 267 connection->content_handler()->StartApplication( |
| 343 ShellImpl* shell_impl = | 268 MakeProxy<Shell>(shell_handle.Pass()), url_response.Pass()); |
| 344 new ShellImpl(&shell_proxy, this, requested_url, resolved_url); | |
| 345 content_shell_impls_.insert(shell_impl); | |
| 346 shell_impl->client()->Initialize(GetArgsForURL(requested_url)); | |
| 347 | |
| 348 connection->content_handler()->StartApplication(shell_proxy.Pass(), | |
| 349 url_response.Pass()); | |
| 350 ConnectToClient( | |
| 351 shell_impl, resolved_url, requestor_url, service_provider.Pass()); | |
| 352 } | 269 } |
| 353 | 270 |
| 354 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 271 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
| 355 const GURL& url) { | 272 const GURL& url) { |
| 356 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 273 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
| 357 if (it != url_to_loader_.end()) | 274 if (it != url_to_loader_.end()) |
| 358 delete it->second; | 275 delete it->second; |
| 359 url_to_loader_[url] = loader.release(); | 276 url_to_loader_[url] = loader.release(); |
| 360 } | 277 } |
| 361 | 278 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 385 auto scheme_it = scheme_to_loader_.find(url.scheme()); | 302 auto scheme_it = scheme_to_loader_.find(url.scheme()); |
| 386 if (scheme_it != scheme_to_loader_.end()) | 303 if (scheme_it != scheme_to_loader_.end()) |
| 387 return scheme_it->second; | 304 return scheme_it->second; |
| 388 if (include_default_loader == INCLUDE_DEFAULT_LOADER) | 305 if (include_default_loader == INCLUDE_DEFAULT_LOADER) |
| 389 return default_loader_.get(); | 306 return default_loader_.get(); |
| 390 return NULL; | 307 return NULL; |
| 391 } | 308 } |
| 392 | 309 |
| 393 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { | 310 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { |
| 394 // Called from ~ShellImpl, so we do not need to call Destroy here. | 311 // Called from ~ShellImpl, so we do not need to call Destroy here. |
| 395 auto content_shell_it = content_shell_impls_.find(shell_impl); | |
| 396 if (content_shell_it != content_shell_impls_.end()) { | |
| 397 delete (*content_shell_it); | |
| 398 content_shell_impls_.erase(content_shell_it); | |
| 399 return; | |
| 400 } | |
| 401 const GURL url = shell_impl->url(); | 312 const GURL url = shell_impl->url(); |
| 402 const GURL requested_url = shell_impl->requested_url(); | 313 const GURL requested_url = shell_impl->requested_url(); |
| 403 // Remove the shell. | 314 // Remove the shell. |
| 404 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); | 315 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); |
| 405 DCHECK(it != url_to_shell_impl_.end()); | 316 DCHECK(it != url_to_shell_impl_.end()); |
| 406 delete it->second; | 317 delete it->second; |
| 407 url_to_shell_impl_.erase(it); | 318 url_to_shell_impl_.erase(it); |
| 408 ApplicationLoader* loader = GetLoaderForURL(requested_url, | 319 ApplicationLoader* loader = GetLoaderForURL(requested_url, |
| 409 INCLUDE_DEFAULT_LOADER); | 320 INCLUDE_DEFAULT_LOADER); |
| 410 if (loader) | 321 if (loader) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 435 return pipe.handle0.Pass(); | 346 return pipe.handle0.Pass(); |
| 436 } | 347 } |
| 437 | 348 |
| 438 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { | 349 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { |
| 439 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | 350 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); |
| 440 if (args_it != url_to_args_.end()) | 351 if (args_it != url_to_args_.end()) |
| 441 return Array<String>::From(args_it->second); | 352 return Array<String>::From(args_it->second); |
| 442 return Array<String>(); | 353 return Array<String>(); |
| 443 } | 354 } |
| 444 } // namespace mojo | 355 } // namespace mojo |
| OLD | NEW |