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

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: Use URLResponse with ContentHandler interface instead of data pipe 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"
14 #include "mojo/service_manager/service_loader.h" 15 #include "mojo/service_manager/service_loader.h"
16 #include "mojo/services/public/interfaces/content_handler/content_handler.mojom. h"
15 17
16 namespace mojo { 18 namespace mojo {
17 19
18 namespace { 20 namespace {
19 // Used by TestAPI. 21 // Used by TestAPI.
20 bool has_created_instance = false; 22 bool has_created_instance = false;
21 23
22 class StubServiceProvider : public InterfaceImpl<ServiceProvider> { 24 class StubServiceProvider : public InterfaceImpl<ServiceProvider> {
23 public: 25 public:
24 ServiceProvider* GetRemoteServiceProvider() { 26 ServiceProvider* GetRemoteServiceProvider() {
25 return client(); 27 return client();
26 } 28 }
27 29
28 private: 30 private:
29 virtual void ConnectToService( 31 virtual void ConnectToService(
30 const String& service_name, 32 const String& service_name,
31 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {} 33 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {}
32 }; 34 };
33 35
34 } 36 } // namespace
37
38 class ServiceManager::LoadServiceCallbacksImpl
39 : public ServiceLoader::LoadServiceCallbacks {
40 public:
41 LoadServiceCallbacksImpl(base::WeakPtr<ServiceManager> manager,
42 const GURL& requested_url,
43 const GURL& requestor_url,
44 ServiceProviderPtr service_provider)
45 : manager_(manager),
46 requested_url_(requested_url),
47 requestor_url_(requestor_url),
48 service_provider_(service_provider.Pass()) {
49 }
50
51 private:
52 virtual ~LoadServiceCallbacksImpl() {
53 }
54
55 // LoadServiceCallbacks implementation
56 virtual ScopedMessagePipeHandle RegisterApplication() OVERRIDE {
57 ScopedMessagePipeHandle shell_handle;
58 if (manager_) {
59 manager_->RegisterLoadedApplication(requested_url_,
60 requestor_url_,
61 service_provider_.Pass(),
62 &shell_handle);
63 }
64 return shell_handle.Pass();
65 }
66
67 virtual void LoadWithContentHandler(
68 const GURL& content_handler_url,
69 URLResponsePtr content) OVERRIDE {
70 if (manager_) {
71 manager_->LoadWithContentHandler(requested_url_,
72 requestor_url_,
73 content_handler_url,
74 content.Pass(),
75 service_provider_.Pass());
76 }
77 }
78
79 base::WeakPtr<ServiceManager> manager_;
80 GURL requested_url_;
81 GURL requestor_url_;
82 ServiceProviderPtr service_provider_;
83 };
35 84
36 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> { 85 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> {
37 public: 86 public:
38 ShellImpl(ServiceManager* manager, const GURL& url) 87 ShellImpl(ServiceManager* manager, const GURL& url)
39 : manager_(manager), 88 : manager_(manager),
40 url_(url) { 89 url_(url) {
41 } 90 }
42 91
43 virtual ~ShellImpl() { 92 virtual ~ShellImpl() {
44 } 93 }
(...skipping 22 matching lines...) Expand all
67 virtual void OnConnectionError() OVERRIDE { 116 virtual void OnConnectionError() OVERRIDE {
68 manager_->OnShellImplError(this); 117 manager_->OnShellImplError(this);
69 } 118 }
70 119
71 ServiceManager* const manager_; 120 ServiceManager* const manager_;
72 const GURL url_; 121 const GURL url_;
73 122
74 DISALLOW_COPY_AND_ASSIGN(ShellImpl); 123 DISALLOW_COPY_AND_ASSIGN(ShellImpl);
75 }; 124 };
76 125
126 struct ServiceManager::ContentHandlerConnection {
127 ContentHandlerConnection(ServiceManager* manager,
128 const GURL& content_handler_url) {
129 ServiceProviderPtr service_provider;
130 BindToProxy(&service_provider_impl, &service_provider);
131 manager->ConnectToApplication(content_handler_url,
132 GURL(),
133 service_provider.Pass());
134 MessagePipe pipe;
135 content_handler.Bind(pipe.handle0.Pass());
136 service_provider_impl.client()->ConnectToService(ContentHandler::Name_,
137 pipe.handle1.Pass());
138 }
139
140 StubServiceProvider service_provider_impl;
141 ContentHandlerPtr content_handler;
142 };
143
77 // static 144 // static
78 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { 145 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) {
79 } 146 }
80 147
81 ServiceManager::TestAPI::~TestAPI() { 148 ServiceManager::TestAPI::~TestAPI() {
82 } 149 }
83 150
84 bool ServiceManager::TestAPI::HasCreatedInstance() { 151 bool ServiceManager::TestAPI::HasCreatedInstance() {
85 return has_created_instance; 152 return has_created_instance;
86 } 153 }
87 154
88 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { 155 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
89 return manager_->url_to_shell_impl_.find(url) != 156 return manager_->url_to_shell_impl_.find(url) !=
90 manager_->url_to_shell_impl_.end(); 157 manager_->url_to_shell_impl_.end();
91 } 158 }
92 159
93 ServiceManager::ServiceManager() : interceptor_(NULL) { 160 ServiceManager::ServiceManager()
161 : interceptor_(NULL),
162 weak_ptr_factory_(this) {
94 } 163 }
95 164
96 ServiceManager::~ServiceManager() { 165 ServiceManager::~ServiceManager() {
166 STLDeleteValues(&content_handlers_);
97 TerminateShellConnections(); 167 TerminateShellConnections();
98 STLDeleteValues(&url_to_loader_); 168 STLDeleteValues(&url_to_loader_);
99 STLDeleteValues(&scheme_to_loader_); 169 STLDeleteValues(&scheme_to_loader_);
100 } 170 }
101 171
102 void ServiceManager::TerminateShellConnections() { 172 void ServiceManager::TerminateShellConnections() {
103 STLDeleteValues(&url_to_shell_impl_); 173 STLDeleteValues(&url_to_shell_impl_);
104 } 174 }
105 175
106 // static 176 // static
107 ServiceManager* ServiceManager::GetInstance() { 177 ServiceManager* ServiceManager::GetInstance() {
108 static base::LazyInstance<ServiceManager> instance = 178 static base::LazyInstance<ServiceManager> instance =
109 LAZY_INSTANCE_INITIALIZER; 179 LAZY_INSTANCE_INITIALIZER;
110 has_created_instance = true; 180 has_created_instance = true;
111 return &instance.Get(); 181 return &instance.Get();
112 } 182 }
113 183
114 void ServiceManager::ConnectToApplication(const GURL& url, 184 void ServiceManager::ConnectToApplication(const GURL& url,
115 const GURL& requestor_url, 185 const GURL& requestor_url,
116 ServiceProviderPtr service_provider) { 186 ServiceProviderPtr service_provider) {
117 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url); 187 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url);
118 ShellImpl* shell_impl;
119 if (shell_it != url_to_shell_impl_.end()) { 188 if (shell_it != url_to_shell_impl_.end()) {
120 shell_impl = shell_it->second; 189 ConnectToClient(shell_it->second, url, requestor_url,
121 } else { 190 service_provider.Pass());
122 MessagePipe pipe; 191 return;
123 GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass());
124 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
125 url_to_shell_impl_[url] = shell_impl;
126 } 192 }
193
194 scoped_refptr<LoadServiceCallbacksImpl> callbacks(
195 new LoadServiceCallbacksImpl(weak_ptr_factory_.GetWeakPtr(),
196 url,
197 requestor_url,
198 service_provider.Pass()));
199 GetLoaderForURL(url)->LoadService(this, url, callbacks);
200 }
201
202 void ServiceManager::ConnectToClient(ShellImpl* shell_impl,
203 const GURL& url,
204 const GURL& requestor_url,
205 ServiceProviderPtr service_provider) {
127 if (interceptor_) { 206 if (interceptor_) {
128 shell_impl->ConnectToClient( 207 shell_impl->ConnectToClient(
129 requestor_url, 208 requestor_url,
130 interceptor_->OnConnectToClient(url, service_provider.Pass())); 209 interceptor_->OnConnectToClient(url, service_provider.Pass()));
131 } else { 210 } else {
132 shell_impl->ConnectToClient(requestor_url, service_provider.Pass()); 211 shell_impl->ConnectToClient(requestor_url, service_provider.Pass());
133 } 212 }
134 } 213 }
135 214
215 void ServiceManager::RegisterLoadedApplication(
216 const GURL& url,
217 const GURL& requestor_url,
218 ServiceProviderPtr service_provider,
219 ScopedMessagePipeHandle* shell_handle) {
220 ShellImpl* shell_impl = NULL;
221 URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url);
222 if (iter != url_to_shell_impl_.end()) {
223 // This can happen because services are loaded asynchronously. So if we get
224 // two requests for the same service close to each other, we might get here
225 // and find that we already have it.
226 shell_impl = iter->second;
227 } else {
228 MessagePipe pipe;
229 shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
230 url_to_shell_impl_[url] = shell_impl;
231 *shell_handle = pipe.handle0.Pass();
232 }
233
234 ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass());
235 }
236
237 void ServiceManager::LoadWithContentHandler(
238 const GURL& content_url,
239 const GURL& requestor_url,
240 const GURL& content_handler_url,
241 URLResponsePtr content,
242 ServiceProviderPtr service_provider) {
243 ContentHandlerConnection* connection = NULL;
244 ContentHandlerMap::iterator iter =
245 content_handlers_.find(content_handler_url);
246 if (iter != content_handlers_.end()) {
247 connection = iter->second;
248 } else {
249 connection = new ContentHandlerConnection(this, content_handler_url);
250 content_handlers_[content_handler_url] = connection;
251 }
252 connection->content_handler->OnConnect(content_url.spec(),
253 content.Pass(),
254 service_provider.Pass());
255 }
256
136 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader, 257 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
137 const GURL& url) { 258 const GURL& url) {
138 URLToLoaderMap::iterator it = url_to_loader_.find(url); 259 URLToLoaderMap::iterator it = url_to_loader_.find(url);
139 if (it != url_to_loader_.end()) 260 if (it != url_to_loader_.end())
140 delete it->second; 261 delete it->second;
141 url_to_loader_[url] = loader.release(); 262 url_to_loader_[url] = loader.release();
142 } 263 }
143 264
144 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader, 265 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader,
145 const std::string& scheme) { 266 const std::string& scheme) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 StubServiceProvider* stub_sp = new StubServiceProvider; 303 StubServiceProvider* stub_sp = new StubServiceProvider;
183 ServiceProviderPtr spp; 304 ServiceProviderPtr spp;
184 BindToProxy(stub_sp, &spp); 305 BindToProxy(stub_sp, &spp);
185 ConnectToApplication(application_url, GURL(), spp.Pass()); 306 ConnectToApplication(application_url, GURL(), spp.Pass());
186 MessagePipe pipe; 307 MessagePipe pipe;
187 stub_sp->GetRemoteServiceProvider()->ConnectToService( 308 stub_sp->GetRemoteServiceProvider()->ConnectToService(
188 interface_name, pipe.handle1.Pass()); 309 interface_name, pipe.handle1.Pass());
189 return pipe.handle0.Pass(); 310 return pipe.handle0.Pass();
190 } 311 }
191 } // namespace mojo 312 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698