Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: mojo/service_manager/service_manager.cc

Issue 423963004: First cut at "content handling" support in Mojo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more gn Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/service_manager/service_manager.h"
6
5 #include <stdio.h> 7 #include <stdio.h>
6 8
7 #include "mojo/service_manager/service_manager.h" 9 #include "base/bind.h"
8
9 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/macros.h" 12 #include "base/macros.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "mojo/common/common_type_converters.h" 14 #include "mojo/common/common_type_converters.h"
15 #include "mojo/public/cpp/application/connect.h"
14 #include "mojo/public/interfaces/application/application.mojom.h" 16 #include "mojo/public/interfaces/application/application.mojom.h"
15 #include "mojo/public/interfaces/application/shell.mojom.h" 17 #include "mojo/public/interfaces/application/shell.mojom.h"
16 #include "mojo/service_manager/service_loader.h" 18 #include "mojo/service_manager/service_loader.h"
19 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h"
17 20
18 namespace mojo { 21 namespace mojo {
19 22
20 namespace { 23 namespace {
21 // Used by TestAPI. 24 // Used by TestAPI.
22 bool has_created_instance = false; 25 bool has_created_instance = false;
23 26
24 class StubServiceProvider : public InterfaceImpl<ServiceProvider> { 27 class StubServiceProvider : public InterfaceImpl<ServiceProvider> {
25 public: 28 public:
26 ServiceProvider* GetRemoteServiceProvider() { 29 ServiceProvider* GetRemoteServiceProvider() {
27 return client(); 30 return client();
28 } 31 }
29 32
30 private: 33 private:
31 virtual void ConnectToService( 34 virtual void ConnectToService(
32 const String& service_name, 35 const String& service_name,
33 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {} 36 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {}
34 }; 37 };
35 38
36 } 39 } // namespace
40
41 class ServiceManager::LoadCallbacksImpl : public ServiceLoader::LoadCallbacks {
42 public:
43 LoadCallbacksImpl(base::WeakPtr<ServiceManager> manager,
44 const GURL& requested_url,
45 const GURL& requestor_url,
46 ServiceProviderPtr service_provider)
47 : manager_(manager),
48 requested_url_(requested_url),
49 requestor_url_(requestor_url),
50 service_provider_(service_provider.Pass()) {
51 }
52
53 private:
54 virtual ~LoadCallbacksImpl() {
55 }
56
57 // LoadCallbacks implementation
58 virtual ScopedMessagePipeHandle RegisterApplication() OVERRIDE {
59 ScopedMessagePipeHandle shell_handle;
60 if (manager_) {
61 manager_->RegisterLoadedApplication(requested_url_,
62 requestor_url_,
63 service_provider_.Pass(),
64 &shell_handle);
65 }
66 return shell_handle.Pass();
67 }
68
69 virtual void LoadWithContentHandler(const GURL& content_handler_url,
70 URLResponsePtr content) OVERRIDE {
71 if (manager_) {
72 manager_->LoadWithContentHandler(requested_url_,
73 requestor_url_,
74 content_handler_url,
75 content.Pass(),
76 service_provider_.Pass());
77 }
78 }
79
80 base::WeakPtr<ServiceManager> manager_;
81 GURL requested_url_;
82 GURL requestor_url_;
83 ServiceProviderPtr service_provider_;
84 };
37 85
38 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> { 86 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> {
39 public: 87 public:
40 ShellImpl(ServiceManager* manager, const GURL& url) 88 ShellImpl(ServiceManager* manager, const GURL& url)
41 : manager_(manager), 89 : manager_(manager),
42 url_(url) { 90 url_(url) {
43 } 91 }
44 92
45 virtual ~ShellImpl() { 93 virtual ~ShellImpl() {
46 } 94 }
(...skipping 22 matching lines...) Expand all
69 virtual void OnConnectionError() OVERRIDE { 117 virtual void OnConnectionError() OVERRIDE {
70 manager_->OnShellImplError(this); 118 manager_->OnShellImplError(this);
71 } 119 }
72 120
73 ServiceManager* const manager_; 121 ServiceManager* const manager_;
74 const GURL url_; 122 const GURL url_;
75 123
76 DISALLOW_COPY_AND_ASSIGN(ShellImpl); 124 DISALLOW_COPY_AND_ASSIGN(ShellImpl);
77 }; 125 };
78 126
127 struct ServiceManager::ContentHandlerConnection {
128 ContentHandlerConnection(ServiceManager* manager,
129 const GURL& content_handler_url) {
130 ServiceProviderPtr service_provider;
131 BindToProxy(&service_provider_impl, &service_provider);
132 manager->ConnectToApplication(content_handler_url,
133 GURL(),
134 service_provider.Pass());
135 mojo::ConnectToService(service_provider_impl.client(), &content_handler);
136 }
137
138 StubServiceProvider service_provider_impl;
139 ContentHandlerPtr content_handler;
140 };
141
79 // static 142 // static
80 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { 143 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) {
81 } 144 }
82 145
83 ServiceManager::TestAPI::~TestAPI() { 146 ServiceManager::TestAPI::~TestAPI() {
84 } 147 }
85 148
86 bool ServiceManager::TestAPI::HasCreatedInstance() { 149 bool ServiceManager::TestAPI::HasCreatedInstance() {
87 return has_created_instance; 150 return has_created_instance;
88 } 151 }
89 152
90 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { 153 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
91 return manager_->url_to_shell_impl_.find(url) != 154 return manager_->url_to_shell_impl_.find(url) !=
92 manager_->url_to_shell_impl_.end(); 155 manager_->url_to_shell_impl_.end();
93 } 156 }
94 157
95 ServiceManager::ServiceManager() : interceptor_(NULL) { 158 ServiceManager::ServiceManager()
159 : interceptor_(NULL),
160 weak_ptr_factory_(this) {
96 } 161 }
97 162
98 ServiceManager::~ServiceManager() { 163 ServiceManager::~ServiceManager() {
164 STLDeleteValues(&url_to_content_handler_);
99 TerminateShellConnections(); 165 TerminateShellConnections();
100 STLDeleteValues(&url_to_loader_); 166 STLDeleteValues(&url_to_loader_);
101 STLDeleteValues(&scheme_to_loader_); 167 STLDeleteValues(&scheme_to_loader_);
102 } 168 }
103 169
104 void ServiceManager::TerminateShellConnections() { 170 void ServiceManager::TerminateShellConnections() {
105 STLDeleteValues(&url_to_shell_impl_); 171 STLDeleteValues(&url_to_shell_impl_);
106 } 172 }
107 173
108 // static 174 // static
109 ServiceManager* ServiceManager::GetInstance() { 175 ServiceManager* ServiceManager::GetInstance() {
110 static base::LazyInstance<ServiceManager> instance = 176 static base::LazyInstance<ServiceManager> instance =
111 LAZY_INSTANCE_INITIALIZER; 177 LAZY_INSTANCE_INITIALIZER;
112 has_created_instance = true; 178 has_created_instance = true;
113 return &instance.Get(); 179 return &instance.Get();
114 } 180 }
115 181
116 void ServiceManager::ConnectToApplication(const GURL& url, 182 void ServiceManager::ConnectToApplication(const GURL& url,
117 const GURL& requestor_url, 183 const GURL& requestor_url,
118 ServiceProviderPtr service_provider) { 184 ServiceProviderPtr service_provider) {
119 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); 185 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url);
120 ShellImpl* shell_impl;
121 if (shell_it != url_to_shell_impl_.end()) { 186 if (shell_it != url_to_shell_impl_.end()) {
122 shell_impl = shell_it->second; 187 ConnectToClient(shell_it->second, url, requestor_url,
123 } else { 188 service_provider.Pass());
124 MessagePipe pipe; 189 return;
125 GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass());
126 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
127 url_to_shell_impl_[url] = shell_impl;
128 } 190 }
191
192 scoped_refptr<LoadCallbacksImpl> callbacks(
193 new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(),
194 url,
195 requestor_url,
196 service_provider.Pass()));
197 GetLoaderForURL(url)->Load(this, url, callbacks);
198 }
199
200 void ServiceManager::ConnectToClient(ShellImpl* shell_impl,
201 const GURL& url,
202 const GURL& requestor_url,
203 ServiceProviderPtr service_provider) {
129 if (interceptor_) { 204 if (interceptor_) {
130 shell_impl->ConnectToClient( 205 shell_impl->ConnectToClient(
131 requestor_url, 206 requestor_url,
132 interceptor_->OnConnectToClient(url, service_provider.Pass())); 207 interceptor_->OnConnectToClient(url, service_provider.Pass()));
133 } else { 208 } else {
134 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); 209 shell_impl->ConnectToClient(requestor_url, service_provider.Pass());
135 } 210 }
136 } 211 }
137 212
213 void ServiceManager::RegisterLoadedApplication(
214 const GURL& url,
215 const GURL& requestor_url,
216 ServiceProviderPtr service_provider,
217 ScopedMessagePipeHandle* shell_handle) {
218 ShellImpl* shell_impl = NULL;
219 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url);
220 if (iter != url_to_shell_impl_.end()) {
221 // 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
223 // and find that we already have it.
224 shell_impl = iter->second;
225 } else {
226 MessagePipe pipe;
227 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
228 url_to_shell_impl_[url] = shell_impl;
229 *shell_handle = pipe.handle0.Pass();
230 }
231
232 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass());
233 }
234
235 void ServiceManager::LoadWithContentHandler(
236 const GURL& content_url,
237 const GURL& requestor_url,
238 const GURL& content_handler_url,
239 URLResponsePtr content,
240 ServiceProviderPtr service_provider) {
241 ContentHandlerConnection* connection = NULL;
242 URLToContentHandlerMap::iterator iter =
243 url_to_content_handler_.find(content_handler_url);
244 if (iter != url_to_content_handler_.end()) {
245 connection = iter->second;
246 } else {
247 connection = new ContentHandlerConnection(this, content_handler_url);
248 url_to_content_handler_[content_handler_url] = connection;
249 }
250 connection->content_handler->OnConnect(content_url.spec(),
251 content.Pass(),
252 service_provider.Pass());
253 }
254
138 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader, 255 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
139 const GURL& url) { 256 const GURL& url) {
140 URLToLoaderMap::iterator it = url_to_loader_.find(url); 257 URLToLoaderMap::iterator it = url_to_loader_.find(url);
141 if (it != url_to_loader_.end()) 258 if (it != url_to_loader_.end())
142 delete it->second; 259 delete it->second;
143 url_to_loader_[url] = loader.release(); 260 url_to_loader_[url] = loader.release();
144 } 261 }
145 262
146 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader, 263 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader,
147 const std::string& scheme) { 264 const std::string& scheme) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 StubServiceProvider* stub_sp = new StubServiceProvider; 301 StubServiceProvider* stub_sp = new StubServiceProvider;
185 ServiceProviderPtr spp; 302 ServiceProviderPtr spp;
186 BindToProxy(stub_sp, &spp); 303 BindToProxy(stub_sp, &spp);
187 ConnectToApplication(application_url, GURL(), spp.Pass()); 304 ConnectToApplication(application_url, GURL(), spp.Pass());
188 MessagePipe pipe; 305 MessagePipe pipe;
189 stub_sp->GetRemoteServiceProvider()->ConnectToService( 306 stub_sp->GetRemoteServiceProvider()->ConnectToService(
190 interface_name, pipe.handle1.Pass()); 307 interface_name, pipe.handle1.Pass());
191 return pipe.handle0.Pass(); 308 return pipe.handle0.Pass();
192 } 309 }
193 } // namespace mojo 310 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/service_manager/service_manager.h ('k') | mojo/service_manager/service_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698