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

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

Powered by Google App Engine
This is Rietveld 408576698