| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "mojo/application_manager/application_loader.h" | 14 #include "mojo/application_manager/application_loader.h" |
| 15 #include "mojo/common/common_type_converters.h" | 15 #include "mojo/common/common_type_converters.h" |
| 16 #include "mojo/public/cpp/application/connect.h" | 16 #include "mojo/public/cpp/application/connect.h" |
| 17 #include "mojo/public/cpp/bindings/error_handler.h" |
| 17 #include "mojo/public/interfaces/application/application.mojom.h" | 18 #include "mojo/public/interfaces/application/application.mojom.h" |
| 18 #include "mojo/public/interfaces/application/shell.mojom.h" | 19 #include "mojo/public/interfaces/application/shell.mojom.h" |
| 19 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom.
h" | 20 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom.
h" |
| 20 | 21 |
| 21 namespace mojo { | 22 namespace mojo { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 // Used by TestAPI. | 25 // Used by TestAPI. |
| 25 bool has_created_instance = false; | 26 bool has_created_instance = false; |
| 26 | 27 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 109 |
| 109 private: | 110 private: |
| 110 void OnConnectionError() override { manager_->OnShellImplError(this); } | 111 void OnConnectionError() override { manager_->OnShellImplError(this); } |
| 111 | 112 |
| 112 ApplicationManager* const manager_; | 113 ApplicationManager* const manager_; |
| 113 const GURL url_; | 114 const GURL url_; |
| 114 | 115 |
| 115 DISALLOW_COPY_AND_ASSIGN(ShellImpl); | 116 DISALLOW_COPY_AND_ASSIGN(ShellImpl); |
| 116 }; | 117 }; |
| 117 | 118 |
| 118 struct ApplicationManager::ContentHandlerConnection { | 119 class ApplicationManager::ContentHandlerConnection : public ErrorHandler { |
| 120 public: |
| 119 ContentHandlerConnection(ApplicationManager* manager, | 121 ContentHandlerConnection(ApplicationManager* manager, |
| 120 const GURL& content_handler_url) { | 122 const GURL& content_handler_url) |
| 123 : manager_(manager), content_handler_url_(content_handler_url) { |
| 121 ServiceProviderPtr service_provider; | 124 ServiceProviderPtr service_provider; |
| 122 BindToProxy(&service_provider_impl, &service_provider); | 125 WeakBindToProxy(&service_provider_impl_, &service_provider); |
| 123 manager->ConnectToApplication( | 126 manager->ConnectToApplication( |
| 124 content_handler_url, GURL(), service_provider.Pass()); | 127 content_handler_url, GURL(), service_provider.Pass()); |
| 125 mojo::ConnectToService(service_provider_impl.client(), &content_handler); | 128 mojo::ConnectToService(service_provider_impl_.client(), &content_handler_); |
| 129 content_handler_.set_error_handler(this); |
| 126 } | 130 } |
| 127 | 131 |
| 128 StubServiceProvider service_provider_impl; | 132 ContentHandler* content_handler() { return content_handler_.get(); } |
| 129 ContentHandlerPtr content_handler; | 133 |
| 134 GURL content_handler_url() { return content_handler_url_; } |
| 135 |
| 136 private: |
| 137 // ErrorHandler implementation: |
| 138 void OnConnectionError() override { manager_->OnContentHandlerError(this); } |
| 139 |
| 140 ApplicationManager* manager_; |
| 141 GURL content_handler_url_; |
| 142 StubServiceProvider service_provider_impl_; |
| 143 ContentHandlerPtr content_handler_; |
| 144 |
| 145 DISALLOW_COPY_AND_ASSIGN(ContentHandlerConnection); |
| 130 }; | 146 }; |
| 131 | 147 |
| 132 // static | 148 // static |
| 133 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) | 149 ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager) |
| 134 : manager_(manager) { | 150 : manager_(manager) { |
| 135 } | 151 } |
| 136 | 152 |
| 137 ApplicationManager::TestAPI::~TestAPI() { | 153 ApplicationManager::TestAPI::~TestAPI() { |
| 138 } | 154 } |
| 139 | 155 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 154 | 170 |
| 155 ApplicationManager::~ApplicationManager() { | 171 ApplicationManager::~ApplicationManager() { |
| 156 STLDeleteValues(&url_to_content_handler_); | 172 STLDeleteValues(&url_to_content_handler_); |
| 157 TerminateShellConnections(); | 173 TerminateShellConnections(); |
| 158 STLDeleteValues(&url_to_loader_); | 174 STLDeleteValues(&url_to_loader_); |
| 159 STLDeleteValues(&scheme_to_loader_); | 175 STLDeleteValues(&scheme_to_loader_); |
| 160 } | 176 } |
| 161 | 177 |
| 162 void ApplicationManager::TerminateShellConnections() { | 178 void ApplicationManager::TerminateShellConnections() { |
| 163 STLDeleteValues(&url_to_shell_impl_); | 179 STLDeleteValues(&url_to_shell_impl_); |
| 180 STLDeleteElements(&content_shell_impls_); |
| 164 } | 181 } |
| 165 | 182 |
| 166 // static | 183 // static |
| 167 ApplicationManager* ApplicationManager::GetInstance() { | 184 ApplicationManager* ApplicationManager::GetInstance() { |
| 168 static base::LazyInstance<ApplicationManager> instance = | 185 static base::LazyInstance<ApplicationManager> instance = |
| 169 LAZY_INSTANCE_INITIALIZER; | 186 LAZY_INSTANCE_INITIALIZER; |
| 170 has_created_instance = true; | 187 has_created_instance = true; |
| 171 return &instance.Get(); | 188 return &instance.Get(); |
| 172 } | 189 } |
| 173 | 190 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 ScopedMessagePipeHandle* shell_handle) { | 234 ScopedMessagePipeHandle* shell_handle) { |
| 218 ShellImpl* shell_impl = NULL; | 235 ShellImpl* shell_impl = NULL; |
| 219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); | 236 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); |
| 220 if (iter != url_to_shell_impl_.end()) { | 237 if (iter != url_to_shell_impl_.end()) { |
| 221 // This can happen because services are loaded asynchronously. So if we get | 238 // This can happen because services are loaded asynchronously. So if we get |
| 222 // two requests for the same service close to each other, we might get here | 239 // two requests for the same service close to each other, we might get here |
| 223 // and find that we already have it. | 240 // and find that we already have it. |
| 224 shell_impl = iter->second; | 241 shell_impl = iter->second; |
| 225 } else { | 242 } else { |
| 226 MessagePipe pipe; | 243 MessagePipe pipe; |
| 227 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | |
| 228 Array<String> args; | |
| 229 if (args_it != url_to_args_.end()) | |
| 230 args = Array<String>::From(args_it->second); | |
| 231 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); | 244 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); |
| 232 url_to_shell_impl_[url] = shell_impl; | 245 url_to_shell_impl_[url] = shell_impl; |
| 233 *shell_handle = pipe.handle0.Pass(); | 246 *shell_handle = pipe.handle0.Pass(); |
| 234 shell_impl->client()->Initialize(args.Pass()); | 247 shell_impl->client()->Initialize(GetArgsForURL(url)); |
| 235 } | 248 } |
| 236 | 249 |
| 237 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); | 250 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); |
| 238 } | 251 } |
| 239 | 252 |
| 240 void ApplicationManager::LoadWithContentHandler( | 253 void ApplicationManager::LoadWithContentHandler( |
| 241 const GURL& content_url, | 254 const GURL& content_url, |
| 242 const GURL& requestor_url, | 255 const GURL& requestor_url, |
| 243 const GURL& content_handler_url, | 256 const GURL& content_handler_url, |
| 244 URLResponsePtr url_response, | 257 URLResponsePtr url_response, |
| 245 ServiceProviderPtr service_provider) { | 258 ServiceProviderPtr service_provider) { |
| 246 ContentHandlerConnection* connection = NULL; | 259 ContentHandlerConnection* connection = NULL; |
| 247 URLToContentHandlerMap::iterator iter = | 260 URLToContentHandlerMap::iterator iter = |
| 248 url_to_content_handler_.find(content_handler_url); | 261 url_to_content_handler_.find(content_handler_url); |
| 249 if (iter != url_to_content_handler_.end()) { | 262 if (iter != url_to_content_handler_.end()) { |
| 250 connection = iter->second; | 263 connection = iter->second; |
| 251 } else { | 264 } else { |
| 252 connection = new ContentHandlerConnection(this, content_handler_url); | 265 connection = new ContentHandlerConnection(this, content_handler_url); |
| 253 url_to_content_handler_[content_handler_url] = connection; | 266 url_to_content_handler_[content_handler_url] = connection; |
| 254 } | 267 } |
| 255 | 268 |
| 256 InterfaceRequest<ServiceProvider> spir; | 269 ShellPtr shell_proxy; |
| 257 spir.Bind(service_provider.PassMessagePipe()); | 270 ShellImpl* shell_impl = |
| 258 connection->content_handler->OnConnect( | 271 WeakBindToProxy(new ShellImpl(this, content_url), &shell_proxy); |
| 259 requestor_url.spec(), url_response.Pass(), spir.Pass()); | 272 content_shell_impls_.insert(shell_impl); |
| 273 shell_impl->client()->Initialize(GetArgsForURL(content_url)); |
| 274 |
| 275 connection->content_handler()->StartApplication(shell_proxy.Pass(), |
| 276 url_response.Pass()); |
| 277 ConnectToClient( |
| 278 shell_impl, content_url, requestor_url, service_provider.Pass()); |
| 260 } | 279 } |
| 261 | 280 |
| 262 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, | 281 void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, |
| 263 const GURL& url) { | 282 const GURL& url) { |
| 264 URLToLoaderMap::iterator it = url_to_loader_.find(url); | 283 URLToLoaderMap::iterator it = url_to_loader_.find(url); |
| 265 if (it != url_to_loader_.end()) | 284 if (it != url_to_loader_.end()) |
| 266 delete it->second; | 285 delete it->second; |
| 267 url_to_loader_[url] = loader.release(); | 286 url_to_loader_[url] = loader.release(); |
| 268 } | 287 } |
| 269 | 288 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 291 return url_it->second; | 310 return url_it->second; |
| 292 SchemeToLoaderMap::const_iterator scheme_it = | 311 SchemeToLoaderMap::const_iterator scheme_it = |
| 293 scheme_to_loader_.find(url.scheme()); | 312 scheme_to_loader_.find(url.scheme()); |
| 294 if (scheme_it != scheme_to_loader_.end()) | 313 if (scheme_it != scheme_to_loader_.end()) |
| 295 return scheme_it->second; | 314 return scheme_it->second; |
| 296 return default_loader_.get(); | 315 return default_loader_.get(); |
| 297 } | 316 } |
| 298 | 317 |
| 299 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { | 318 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { |
| 300 // Called from ~ShellImpl, so we do not need to call Destroy here. | 319 // Called from ~ShellImpl, so we do not need to call Destroy here. |
| 320 auto content_shell_it = content_shell_impls_.find(shell_impl); |
| 321 if (content_shell_it != content_shell_impls_.end()) { |
| 322 delete (*content_shell_it); |
| 323 content_shell_impls_.erase(content_shell_it); |
| 324 return; |
| 325 } |
| 301 const GURL url = shell_impl->url(); | 326 const GURL url = shell_impl->url(); |
| 327 // Remove the shell. |
| 302 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); | 328 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); |
| 303 DCHECK(it != url_to_shell_impl_.end()); | 329 DCHECK(it != url_to_shell_impl_.end()); |
| 304 delete it->second; | 330 delete it->second; |
| 305 url_to_shell_impl_.erase(it); | 331 url_to_shell_impl_.erase(it); |
| 306 ApplicationLoader* loader = GetLoaderForURL(url); | 332 ApplicationLoader* loader = GetLoaderForURL(url); |
| 307 if (loader) | 333 if (loader) |
| 308 loader->OnApplicationError(this, url); | 334 loader->OnApplicationError(this, url); |
| 309 if (delegate_) | 335 if (delegate_) |
| 310 delegate_->OnApplicationError(url); | 336 delegate_->OnApplicationError(url); |
| 311 } | 337 } |
| 312 | 338 |
| 339 void ApplicationManager::OnContentHandlerError( |
| 340 ContentHandlerConnection* content_handler) { |
| 341 // Remove the mapping to the content handler. |
| 342 auto it = |
| 343 url_to_content_handler_.find(content_handler->content_handler_url()); |
| 344 DCHECK(it != url_to_content_handler_.end()); |
| 345 delete it->second; |
| 346 url_to_content_handler_.erase(it); |
| 347 } |
| 348 |
| 313 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 349 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 314 const GURL& application_url, | 350 const GURL& application_url, |
| 315 const std::string& interface_name) { | 351 const std::string& interface_name) { |
| 316 StubServiceProvider* stub_sp = new StubServiceProvider; | 352 StubServiceProvider* stub_sp = new StubServiceProvider; |
| 317 ServiceProviderPtr spp; | 353 ServiceProviderPtr spp; |
| 318 BindToProxy(stub_sp, &spp); | 354 BindToProxy(stub_sp, &spp); |
| 319 ConnectToApplication(application_url, GURL(), spp.Pass()); | 355 ConnectToApplication(application_url, GURL(), spp.Pass()); |
| 320 MessagePipe pipe; | 356 MessagePipe pipe; |
| 321 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, | 357 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, |
| 322 pipe.handle1.Pass()); | 358 pipe.handle1.Pass()); |
| 323 return pipe.handle0.Pass(); | 359 return pipe.handle0.Pass(); |
| 324 } | 360 } |
| 361 |
| 362 Array<String> ApplicationManager::GetArgsForURL(const GURL& url) { |
| 363 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); |
| 364 if (args_it != url_to_args_.end()) |
| 365 return Array<String>::From(args_it->second); |
| 366 return Array<String>(); |
| 367 } |
| 325 } // namespace mojo | 368 } // namespace mojo |
| OLD | NEW |