Chromium Code Reviews| 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 17 matching lines...) Expand all Loading... | |
| 28 public: | 28 public: |
| 29 ServiceProvider* GetRemoteServiceProvider() { return client(); } | 29 ServiceProvider* GetRemoteServiceProvider() { return client(); } |
| 30 | 30 |
| 31 private: | 31 private: |
| 32 void ConnectToService(const String& service_name, | 32 void ConnectToService(const String& service_name, |
| 33 ScopedMessagePipeHandle client_handle) override {} | 33 ScopedMessagePipeHandle client_handle) override {} |
| 34 }; | 34 }; |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 ApplicationManager::Delegate::~Delegate() {} | 38 |
| 39 ApplicationManager::Delegate::~Delegate() { | |
| 40 } | |
| 41 | |
| 42 void ApplicationManager::Delegate::OnApplicationError(const GURL& url) { | |
| 43 LOG(ERROR) << "Communication error with application: " << url.spec(); | |
| 44 } | |
| 45 | |
| 46 GURL ApplicationManager::Delegate::ResolveURL(const GURL& url) { | |
| 47 return url; | |
| 48 } | |
| 49 | |
| 39 | 50 |
| 40 class ApplicationManager::LoadCallbacksImpl | 51 class ApplicationManager::LoadCallbacksImpl |
| 41 : public ApplicationLoader::LoadCallbacks { | 52 : public ApplicationLoader::LoadCallbacks { |
| 42 public: | 53 public: |
| 43 LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager, | 54 LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager, |
| 44 const GURL& requested_url, | 55 const GURL& requested_url, |
| 56 const GURL& resolved_url, | |
| 45 const GURL& requestor_url, | 57 const GURL& requestor_url, |
| 46 ServiceProviderPtr service_provider) | 58 ServiceProviderPtr service_provider) |
| 47 : manager_(manager), | 59 : manager_(manager), |
| 48 requested_url_(requested_url), | 60 requested_url_(requested_url), |
| 61 resolved_url_(resolved_url), | |
| 49 requestor_url_(requestor_url), | 62 requestor_url_(requestor_url), |
| 50 service_provider_(service_provider.Pass()) {} | 63 service_provider_(service_provider.Pass()) {} |
| 51 | 64 |
| 52 private: | 65 private: |
| 53 ~LoadCallbacksImpl() override {} | 66 ~LoadCallbacksImpl() override {} |
| 54 | 67 |
| 55 // LoadCallbacks implementation | 68 // LoadCallbacks implementation |
| 56 ScopedMessagePipeHandle RegisterApplication() override { | 69 ScopedMessagePipeHandle RegisterApplication() override { |
| 57 ScopedMessagePipeHandle shell_handle; | 70 ScopedMessagePipeHandle shell_handle; |
| 58 if (manager_) { | 71 if (manager_) { |
| 59 manager_->RegisterLoadedApplication(requested_url_, | 72 manager_->RegisterLoadedApplication(requested_url_, |
| 73 resolved_url_, | |
| 60 requestor_url_, | 74 requestor_url_, |
| 61 service_provider_.Pass(), | 75 service_provider_.Pass(), |
| 62 &shell_handle); | 76 &shell_handle); |
| 63 } | 77 } |
| 64 return shell_handle.Pass(); | 78 return shell_handle.Pass(); |
| 65 } | 79 } |
| 66 | 80 |
| 67 void LoadWithContentHandler(const GURL& content_handler_url, | 81 void LoadWithContentHandler(const GURL& content_handler_url, |
| 68 URLResponsePtr url_response) override { | 82 URLResponsePtr url_response) override { |
| 69 if (manager_) { | 83 if (manager_) { |
| 70 manager_->LoadWithContentHandler(requested_url_, | 84 manager_->LoadWithContentHandler(requested_url_, |
| 71 requestor_url_, | 85 requestor_url_, |
| 72 content_handler_url, | 86 content_handler_url, |
| 73 url_response.Pass(), | 87 url_response.Pass(), |
| 74 service_provider_.Pass()); | 88 service_provider_.Pass()); |
| 75 } | 89 } |
| 76 } | 90 } |
| 77 | 91 |
| 78 base::WeakPtr<ApplicationManager> manager_; | 92 base::WeakPtr<ApplicationManager> manager_; |
| 79 GURL requested_url_; | 93 GURL requested_url_; |
| 94 GURL resolved_url_; | |
| 80 GURL requestor_url_; | 95 GURL requestor_url_; |
| 81 ServiceProviderPtr service_provider_; | 96 ServiceProviderPtr service_provider_; |
| 82 }; | 97 }; |
| 83 | 98 |
| 84 class ApplicationManager::ShellImpl : public InterfaceImpl<Shell> { | 99 class ApplicationManager::ShellImpl : public InterfaceImpl<Shell> { |
| 85 public: | 100 public: |
| 86 ShellImpl(ApplicationManager* manager, const GURL& url) | 101 ShellImpl(ApplicationManager* manager, const GURL& requested_url, |
|
DaveMoore
2014/10/31 16:15:58
Nit: could you put these on their own lines?
Aaron Boodman
2014/10/31 18:14:02
Done.
| |
| 87 : manager_(manager), url_(url) {} | 102 const GURL& url) |
| 103 : manager_(manager), requested_url_(requested_url), url_(url) {} | |
| 88 | 104 |
| 89 ~ShellImpl() override {} | 105 ~ShellImpl() override {} |
| 90 | 106 |
| 91 void ConnectToClient(const GURL& requestor_url, | 107 void ConnectToClient(const GURL& requestor_url, |
| 92 ServiceProviderPtr service_provider) { | 108 ServiceProviderPtr service_provider) { |
| 93 client()->AcceptConnection(String::From(requestor_url), | 109 client()->AcceptConnection(String::From(requestor_url), |
| 94 service_provider.Pass()); | 110 service_provider.Pass()); |
| 95 } | 111 } |
| 96 | 112 |
| 97 // ServiceProvider implementation: | 113 // ServiceProvider implementation: |
| 98 void ConnectToApplication( | 114 void ConnectToApplication( |
| 99 const String& app_url, | 115 const String& app_url, |
| 100 InterfaceRequest<ServiceProvider> in_service_provider) override { | 116 InterfaceRequest<ServiceProvider> in_service_provider) override { |
| 101 ServiceProviderPtr out_service_provider; | 117 ServiceProviderPtr out_service_provider; |
| 102 out_service_provider.Bind(in_service_provider.PassMessagePipe()); | 118 out_service_provider.Bind(in_service_provider.PassMessagePipe()); |
| 103 manager_->ConnectToApplication( | 119 manager_->ConnectToApplication( |
| 104 app_url.To<GURL>(), url_, out_service_provider.Pass()); | 120 app_url.To<GURL>(), url_, out_service_provider.Pass()); |
| 105 } | 121 } |
| 106 | 122 |
| 107 const GURL& url() const { return url_; } | 123 const GURL& url() const { return url_; } |
| 124 const GURL& requested_url() const { return requested_url_; } | |
| 108 | 125 |
| 109 private: | 126 private: |
| 110 void OnConnectionError() override { manager_->OnShellImplError(this); } | 127 void OnConnectionError() override { manager_->OnShellImplError(this); } |
| 111 | 128 |
| 112 ApplicationManager* const manager_; | 129 ApplicationManager* const manager_; |
| 130 const GURL requested_url_; | |
| 113 const GURL url_; | 131 const GURL url_; |
| 114 | 132 |
| 115 DISALLOW_COPY_AND_ASSIGN(ShellImpl); | 133 DISALLOW_COPY_AND_ASSIGN(ShellImpl); |
| 116 }; | 134 }; |
| 117 | 135 |
| 118 struct ApplicationManager::ContentHandlerConnection { | 136 struct ApplicationManager::ContentHandlerConnection { |
| 119 ContentHandlerConnection(ApplicationManager* manager, | 137 ContentHandlerConnection(ApplicationManager* manager, |
| 120 const GURL& content_handler_url) { | 138 const GURL& content_handler_url) { |
| 121 ServiceProviderPtr service_provider; | 139 ServiceProviderPtr service_provider; |
| 122 BindToProxy(&service_provider_impl, &service_provider); | 140 BindToProxy(&service_provider_impl, &service_provider); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 139 | 157 |
| 140 bool ApplicationManager::TestAPI::HasCreatedInstance() { | 158 bool ApplicationManager::TestAPI::HasCreatedInstance() { |
| 141 return has_created_instance; | 159 return has_created_instance; |
| 142 } | 160 } |
| 143 | 161 |
| 144 bool ApplicationManager::TestAPI::HasFactoryForURL(const GURL& url) const { | 162 bool ApplicationManager::TestAPI::HasFactoryForURL(const GURL& url) const { |
| 145 return manager_->url_to_shell_impl_.find(url) != | 163 return manager_->url_to_shell_impl_.find(url) != |
| 146 manager_->url_to_shell_impl_.end(); | 164 manager_->url_to_shell_impl_.end(); |
| 147 } | 165 } |
| 148 | 166 |
| 149 ApplicationManager::ApplicationManager() | 167 ApplicationManager::ApplicationManager(Delegate* delegate) |
| 150 : delegate_(NULL), | 168 : delegate_(delegate), |
| 151 interceptor_(NULL), | 169 interceptor_(NULL), |
| 152 weak_ptr_factory_(this) { | 170 weak_ptr_factory_(this) { |
| 153 } | 171 } |
| 154 | 172 |
| 155 ApplicationManager::~ApplicationManager() { | 173 ApplicationManager::~ApplicationManager() { |
| 156 STLDeleteValues(&url_to_content_handler_); | 174 STLDeleteValues(&url_to_content_handler_); |
| 157 TerminateShellConnections(); | 175 TerminateShellConnections(); |
| 158 STLDeleteValues(&url_to_loader_); | 176 STLDeleteValues(&url_to_loader_); |
| 159 STLDeleteValues(&scheme_to_loader_); | 177 STLDeleteValues(&scheme_to_loader_); |
| 160 } | 178 } |
| 161 | 179 |
| 162 void ApplicationManager::TerminateShellConnections() { | 180 void ApplicationManager::TerminateShellConnections() { |
| 163 STLDeleteValues(&url_to_shell_impl_); | 181 STLDeleteValues(&url_to_shell_impl_); |
| 164 } | 182 } |
| 165 | 183 |
| 166 // static | |
| 167 ApplicationManager* ApplicationManager::GetInstance() { | |
| 168 static base::LazyInstance<ApplicationManager> instance = | |
| 169 LAZY_INSTANCE_INITIALIZER; | |
| 170 has_created_instance = true; | |
| 171 return &instance.Get(); | |
| 172 } | |
| 173 | |
| 174 void ApplicationManager::ConnectToApplication( | 184 void ApplicationManager::ConnectToApplication( |
| 175 const GURL& url, | 185 const GURL& requested_url, |
| 176 const GURL& requestor_url, | 186 const GURL& requestor_url, |
| 177 ServiceProviderPtr service_provider) { | 187 ServiceProviderPtr service_provider) { |
| 178 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); | 188 GURL resolved_url = delegate_->ResolveURL(requested_url); |
| 189 | |
| 190 URLToShellImplMap::const_iterator shell_it = | |
| 191 url_to_shell_impl_.find(resolved_url); | |
| 179 if (shell_it != url_to_shell_impl_.end()) { | 192 if (shell_it != url_to_shell_impl_.end()) { |
| 180 ConnectToClient( | 193 ConnectToClient(shell_it->second, resolved_url, requestor_url, |
| 181 shell_it->second, url, requestor_url, service_provider.Pass()); | 194 service_provider.Pass()); |
| 182 return; | 195 return; |
| 183 } | 196 } |
| 184 | 197 |
| 185 scoped_refptr<LoadCallbacksImpl> callbacks( | 198 scoped_refptr<LoadCallbacksImpl> callbacks( |
| 186 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), | 199 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(), |
| 187 url, | 200 requested_url, |
| 201 resolved_url, | |
| 188 requestor_url, | 202 requestor_url, |
| 189 service_provider.Pass())); | 203 service_provider.Pass())); |
| 190 GetLoaderForURL(url)->Load(this, url, callbacks); | 204 GetLoaderForURL(resolved_url)->Load(this, resolved_url, callbacks); |
| 191 } | 205 } |
| 192 | 206 |
| 193 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, | 207 void ApplicationManager::ConnectToClient(ShellImpl* shell_impl, |
| 194 const GURL& url, | 208 const GURL& url, |
| 195 const GURL& requestor_url, | 209 const GURL& requestor_url, |
| 196 ServiceProviderPtr service_provider) { | 210 ServiceProviderPtr service_provider) { |
| 197 if (interceptor_) { | 211 if (interceptor_) { |
| 198 shell_impl->ConnectToClient( | 212 shell_impl->ConnectToClient( |
| 199 requestor_url, | 213 requestor_url, |
| 200 interceptor_->OnConnectToClient(url, service_provider.Pass())); | 214 interceptor_->OnConnectToClient(url, service_provider.Pass())); |
| 201 } else { | 215 } else { |
| 202 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); | 216 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); |
| 203 } | 217 } |
| 204 } | 218 } |
| 205 | 219 |
| 206 void ApplicationManager::RegisterExternalApplication( | 220 void ApplicationManager::RegisterExternalApplication( |
| 207 const GURL& url, | 221 const GURL& url, |
| 208 ScopedMessagePipeHandle shell_handle) { | 222 ScopedMessagePipeHandle shell_handle) { |
| 209 url_to_shell_impl_[url] = | 223 url_to_shell_impl_[url] = |
| 210 WeakBindToPipe(new ShellImpl(this, url), shell_handle.Pass()); | 224 WeakBindToPipe(new ShellImpl(this, url, url), shell_handle.Pass()); |
| 211 } | 225 } |
| 212 | 226 |
| 213 void ApplicationManager::RegisterLoadedApplication( | 227 void ApplicationManager::RegisterLoadedApplication( |
| 214 const GURL& url, | 228 const GURL& requested_url, |
| 229 const GURL& resolved_url, | |
| 215 const GURL& requestor_url, | 230 const GURL& requestor_url, |
| 216 ServiceProviderPtr service_provider, | 231 ServiceProviderPtr service_provider, |
| 217 ScopedMessagePipeHandle* shell_handle) { | 232 ScopedMessagePipeHandle* shell_handle) { |
| 218 ShellImpl* shell_impl = NULL; | 233 ShellImpl* shell_impl = NULL; |
| 219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url); | 234 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(resolved_url); |
| 220 if (iter != url_to_shell_impl_.end()) { | 235 if (iter != url_to_shell_impl_.end()) { |
| 221 // This can happen because services are loaded asynchronously. So if we get | 236 // 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 | 237 // two requests for the same service close to each other, we might get here |
| 223 // and find that we already have it. | 238 // and find that we already have it. |
| 224 shell_impl = iter->second; | 239 shell_impl = iter->second; |
| 225 } else { | 240 } else { |
| 226 MessagePipe pipe; | 241 MessagePipe pipe; |
| 227 URLToArgsMap::const_iterator args_it = url_to_args_.find(url); | 242 URLToArgsMap::const_iterator args_it = url_to_args_.find(resolved_url); |
| 228 Array<String> args; | 243 Array<String> args; |
| 229 if (args_it != url_to_args_.end()) | 244 if (args_it != url_to_args_.end()) |
| 230 args = Array<String>::From(args_it->second); | 245 args = Array<String>::From(args_it->second); |
| 231 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass()); | 246 shell_impl = WeakBindToPipe( |
| 232 url_to_shell_impl_[url] = shell_impl; | 247 new ShellImpl(this, requested_url, resolved_url), pipe.handle1.Pass()); |
| 248 url_to_shell_impl_[resolved_url] = shell_impl; | |
| 233 *shell_handle = pipe.handle0.Pass(); | 249 *shell_handle = pipe.handle0.Pass(); |
| 234 shell_impl->client()->Initialize(args.Pass()); | 250 shell_impl->client()->Initialize(args.Pass()); |
| 235 } | 251 } |
| 236 | 252 |
| 237 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass()); | 253 ConnectToClient(shell_impl, resolved_url, requestor_url, |
| 254 service_provider.Pass()); | |
| 238 } | 255 } |
| 239 | 256 |
| 240 void ApplicationManager::LoadWithContentHandler( | 257 void ApplicationManager::LoadWithContentHandler( |
| 241 const GURL& content_url, | 258 const GURL& content_url, |
| 242 const GURL& requestor_url, | 259 const GURL& requestor_url, |
| 243 const GURL& content_handler_url, | 260 const GURL& content_handler_url, |
| 244 URLResponsePtr url_response, | 261 URLResponsePtr url_response, |
| 245 ServiceProviderPtr service_provider) { | 262 ServiceProviderPtr service_provider) { |
| 246 ContentHandlerConnection* connection = NULL; | 263 ContentHandlerConnection* connection = NULL; |
| 247 URLToContentHandlerMap::iterator iter = | 264 URLToContentHandlerMap::iterator iter = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 SchemeToLoaderMap::const_iterator scheme_it = | 309 SchemeToLoaderMap::const_iterator scheme_it = |
| 293 scheme_to_loader_.find(url.scheme()); | 310 scheme_to_loader_.find(url.scheme()); |
| 294 if (scheme_it != scheme_to_loader_.end()) | 311 if (scheme_it != scheme_to_loader_.end()) |
| 295 return scheme_it->second; | 312 return scheme_it->second; |
| 296 return default_loader_.get(); | 313 return default_loader_.get(); |
| 297 } | 314 } |
| 298 | 315 |
| 299 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { | 316 void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) { |
| 300 // Called from ~ShellImpl, so we do not need to call Destroy here. | 317 // Called from ~ShellImpl, so we do not need to call Destroy here. |
| 301 const GURL url = shell_impl->url(); | 318 const GURL url = shell_impl->url(); |
| 319 const GURL requested_url = shell_impl->requested_url(); | |
| 302 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); | 320 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url); |
| 303 DCHECK(it != url_to_shell_impl_.end()); | 321 DCHECK(it != url_to_shell_impl_.end()); |
| 304 delete it->second; | 322 delete it->second; |
| 305 url_to_shell_impl_.erase(it); | 323 url_to_shell_impl_.erase(it); |
| 306 ApplicationLoader* loader = GetLoaderForURL(url); | 324 ApplicationLoader* loader = GetLoaderForURL(requested_url); |
| 307 if (loader) | 325 if (loader) |
| 308 loader->OnApplicationError(this, url); | 326 loader->OnApplicationError(this, url); |
| 309 if (delegate_) | 327 delegate_->OnApplicationError(requested_url); |
| 310 delegate_->OnApplicationError(url); | |
| 311 } | 328 } |
| 312 | 329 |
| 313 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( | 330 ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName( |
| 314 const GURL& application_url, | 331 const GURL& application_url, |
| 315 const std::string& interface_name) { | 332 const std::string& interface_name) { |
| 316 StubServiceProvider* stub_sp = new StubServiceProvider; | 333 StubServiceProvider* stub_sp = new StubServiceProvider; |
| 317 ServiceProviderPtr spp; | 334 ServiceProviderPtr spp; |
| 318 BindToProxy(stub_sp, &spp); | 335 BindToProxy(stub_sp, &spp); |
| 319 ConnectToApplication(application_url, GURL(), spp.Pass()); | 336 ConnectToApplication(application_url, GURL(), spp.Pass()); |
| 320 MessagePipe pipe; | 337 MessagePipe pipe; |
| 321 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, | 338 stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name, |
| 322 pipe.handle1.Pass()); | 339 pipe.handle1.Pass()); |
| 323 return pipe.handle0.Pass(); | 340 return pipe.handle0.Pass(); |
| 324 } | 341 } |
| 325 } // namespace mojo | 342 } // namespace mojo |
| OLD | NEW |