OLD | NEW |
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 <stdio.h> | 5 #include <stdio.h> |
6 | 6 |
7 #include "mojo/service_manager/service_manager.h" | 7 #include "mojo/service_manager/service_manager.h" |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "mojo/public/cpp/bindings/allocation_scope.h" | 13 #include "mojo/public/cpp/bindings/allocation_scope.h" |
14 #include "mojo/public/cpp/bindings/error_handler.h" | |
15 #include "mojo/public/cpp/bindings/remote_ptr.h" | |
16 #include "mojo/service_manager/service_loader.h" | 14 #include "mojo/service_manager/service_loader.h" |
17 | 15 |
18 namespace mojo { | 16 namespace mojo { |
19 | 17 |
20 namespace { | 18 namespace { |
21 // Used by TestAPI. | 19 // Used by TestAPI. |
22 bool has_created_instance = false; | 20 bool has_created_instance = false; |
23 } | 21 } |
24 | 22 |
25 class ServiceManager::ServiceFactory : public Shell, public ErrorHandler { | 23 class ServiceManager::ServiceFactory : public InterfaceImpl<Shell> { |
26 public: | 24 public: |
27 ServiceFactory(ServiceManager* manager, const GURL& url) | 25 ServiceFactory(ServiceManager* manager, const GURL& url) |
28 : manager_(manager), | 26 : manager_(manager), |
29 url_(url) { | 27 url_(url), |
30 InterfacePipe<Shell> pipe; | 28 client_(NULL) { |
31 shell_client_.reset(pipe.handle_to_peer.Pass(), this, this); | |
32 manager_->GetLoaderForURL(url)->LoadService(manager_, | |
33 url, | |
34 pipe.handle_to_self.Pass()); | |
35 } | 29 } |
36 | 30 |
37 virtual ~ServiceFactory() {} | 31 virtual ~ServiceFactory() { |
| 32 } |
38 | 33 |
39 void ConnectToClient(ScopedMessagePipeHandle handle) { | 34 void ConnectToClient(ScopedMessagePipeHandle handle) { |
40 if (handle.is_valid()) { | 35 if (!handle.is_valid()) { |
41 AllocationScope scope; | 36 assert(false); |
42 shell_client_->AcceptConnection(url_.spec(), handle.Pass()); | 37 return; |
43 } | 38 } |
| 39 AllocationScope scope; |
| 40 client_->AcceptConnection(url_.spec(), handle.Pass()); |
44 } | 41 } |
45 | 42 |
| 43 // Shell implementation: |
| 44 virtual void SetClient(ShellClient* client) OVERRIDE { |
| 45 client_ = client; |
| 46 } |
46 virtual void Connect(const String& url, | 47 virtual void Connect(const String& url, |
47 ScopedMessagePipeHandle client_pipe) OVERRIDE { | 48 ScopedMessagePipeHandle client_pipe) OVERRIDE { |
48 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); | 49 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); |
49 } | 50 } |
50 | 51 |
51 virtual void OnError() OVERRIDE { | 52 const GURL& url() const { return url_; } |
| 53 |
| 54 private: |
| 55 virtual void OnConnectionError() OVERRIDE { |
52 manager_->OnServiceFactoryError(this); | 56 manager_->OnServiceFactoryError(this); |
53 } | 57 } |
54 | 58 |
55 const GURL& url() const { return url_; } | |
56 | |
57 private: | |
58 ServiceManager* const manager_; | 59 ServiceManager* const manager_; |
59 const GURL url_; | 60 const GURL url_; |
60 RemotePtr<ShellClient> shell_client_; | 61 ShellClient* client_; |
61 | 62 |
62 DISALLOW_COPY_AND_ASSIGN(ServiceFactory); | 63 DISALLOW_COPY_AND_ASSIGN(ServiceFactory); |
63 }; | 64 }; |
64 | 65 |
65 class ServiceManager::TestAPI::TestShellConnection | 66 class ServiceManager::TestAPI::TestShellConnection |
66 : public Shell, | 67 : public InterfaceImpl<Shell> { |
67 public ErrorHandler { | |
68 public: | 68 public: |
69 explicit TestShellConnection(ServiceManager* manager) : manager_(manager) { | 69 explicit TestShellConnection(ServiceManager* manager) |
70 InterfacePipe<Shell> pipe; | 70 : manager_(manager), |
71 shell_client_.reset(pipe.handle_to_peer.Pass(), this, this); | 71 client_(NULL) { |
72 shell_handle_ = pipe.handle_to_self.Pass(); | |
73 } | 72 } |
74 virtual ~TestShellConnection() {} | 73 virtual ~TestShellConnection() {} |
75 | 74 |
76 ScopedShellHandle GetShellHandle() { | 75 virtual void OnConnectionError() OVERRIDE { |
77 return shell_handle_.Pass(); | 76 // TODO(darin): How should we handle this error? |
78 } | 77 } |
79 | 78 |
80 // Shell: | 79 // Shell: |
| 80 virtual void SetClient(ShellClient* client) OVERRIDE { |
| 81 client_ = client; |
| 82 } |
81 virtual void Connect(const String& url, | 83 virtual void Connect(const String& url, |
82 ScopedMessagePipeHandle client_pipe) OVERRIDE { | 84 ScopedMessagePipeHandle client_pipe) OVERRIDE { |
83 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); | 85 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); |
84 } | 86 } |
85 | 87 |
86 virtual void OnError() OVERRIDE { | |
87 } | |
88 | |
89 private: | 88 private: |
90 ServiceManager* manager_; | 89 ServiceManager* manager_; |
91 RemotePtr<ShellClient> shell_client_; | 90 ShellClient* client_; |
92 ScopedShellHandle shell_handle_; | |
93 | 91 |
94 DISALLOW_COPY_AND_ASSIGN(TestShellConnection); | 92 DISALLOW_COPY_AND_ASSIGN(TestShellConnection); |
95 }; | 93 }; |
96 | 94 |
97 // static | 95 // static |
98 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { | 96 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) { |
99 } | 97 } |
100 | 98 |
101 ServiceManager::TestAPI::~TestAPI() { | 99 ServiceManager::TestAPI::~TestAPI() { |
102 } | 100 } |
103 | 101 |
104 bool ServiceManager::TestAPI::HasCreatedInstance() { | 102 bool ServiceManager::TestAPI::HasCreatedInstance() { |
105 return has_created_instance; | 103 return has_created_instance; |
106 } | 104 } |
107 | 105 |
108 ScopedShellHandle ServiceManager::TestAPI::GetShellHandle() { | 106 ScopedMessagePipeHandle ServiceManager::TestAPI::GetShellHandle() { |
109 if (!shell_connection_.get()) | 107 MessagePipe pipe; |
110 shell_connection_.reset(new TestShellConnection(manager_)); | 108 shell_.reset( |
111 return shell_connection_->GetShellHandle().Pass(); | 109 BindToPipe(new TestShellConnection(manager_), pipe.handle0.Pass())); |
| 110 return pipe.handle1.Pass(); |
112 } | 111 } |
113 | 112 |
114 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { | 113 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { |
115 return manager_->url_to_service_factory_.find(url) != | 114 return manager_->url_to_service_factory_.find(url) != |
116 manager_->url_to_service_factory_.end(); | 115 manager_->url_to_service_factory_.end(); |
117 } | 116 } |
118 | 117 |
119 ServiceManager::ServiceManager() | 118 ServiceManager::ServiceManager() |
120 : interceptor_(NULL) { | 119 : interceptor_(NULL) { |
121 } | 120 } |
122 | 121 |
123 ServiceManager::~ServiceManager() { | 122 ServiceManager::~ServiceManager() { |
124 STLDeleteValues(&url_to_service_factory_); | 123 STLDeleteValues(&url_to_service_factory_); |
125 STLDeleteValues(&url_to_loader_); | 124 STLDeleteValues(&url_to_loader_); |
126 STLDeleteValues(&scheme_to_loader_); | 125 STLDeleteValues(&scheme_to_loader_); |
127 } | 126 } |
128 | 127 |
129 // static | 128 // static |
130 ServiceManager* ServiceManager::GetInstance() { | 129 ServiceManager* ServiceManager::GetInstance() { |
131 static base::LazyInstance<ServiceManager> instance = | 130 static base::LazyInstance<ServiceManager> instance = |
132 LAZY_INSTANCE_INITIALIZER; | 131 LAZY_INSTANCE_INITIALIZER; |
133 has_created_instance = true; | 132 has_created_instance = true; |
134 return &instance.Get(); | 133 return &instance.Get(); |
135 } | 134 } |
136 | 135 |
137 void ServiceManager::Connect(const GURL& url, | 136 void ServiceManager::Connect(const GURL& url, |
138 ScopedMessagePipeHandle client_handle) { | 137 ScopedMessagePipeHandle client_handle) { |
139 URLToServiceFactoryMap::const_iterator service_it = | 138 URLToServiceFactoryMap::const_iterator service_it = |
140 url_to_service_factory_.find(url); | 139 url_to_service_factory_.find(url); |
141 ServiceFactory* service_factory; | 140 ServiceFactory* service_factory; |
142 if (service_it != url_to_service_factory_.end()) { | 141 if (service_it != url_to_service_factory_.end()) { |
143 service_factory = service_it->second; | 142 service_factory = service_it->second; |
144 } else { | 143 } else { |
145 service_factory = new ServiceFactory(this, url); | 144 MessagePipe pipe; |
| 145 GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass()); |
| 146 |
| 147 service_factory = |
| 148 BindToPipe(new ServiceFactory(this, url), pipe.handle1.Pass()); |
| 149 |
146 url_to_service_factory_[url] = service_factory; | 150 url_to_service_factory_[url] = service_factory; |
147 } | 151 } |
148 if (interceptor_) { | 152 if (interceptor_) { |
149 service_factory->ConnectToClient( | 153 service_factory->ConnectToClient( |
150 interceptor_->OnConnectToClient(url, client_handle.Pass())); | 154 interceptor_->OnConnectToClient(url, client_handle.Pass())); |
151 } else { | 155 } else { |
152 service_factory->ConnectToClient(client_handle.Pass()); | 156 service_factory->ConnectToClient(client_handle.Pass()); |
153 } | 157 } |
154 } | 158 } |
155 | 159 |
(...skipping 23 matching lines...) Expand all Loading... |
179 return url_it->second; | 183 return url_it->second; |
180 SchemeToLoaderMap::const_iterator scheme_it = | 184 SchemeToLoaderMap::const_iterator scheme_it = |
181 scheme_to_loader_.find(url.scheme()); | 185 scheme_to_loader_.find(url.scheme()); |
182 if (scheme_it != scheme_to_loader_.end()) | 186 if (scheme_it != scheme_to_loader_.end()) |
183 return scheme_it->second; | 187 return scheme_it->second; |
184 DCHECK(default_loader_); | 188 DCHECK(default_loader_); |
185 return default_loader_.get(); | 189 return default_loader_.get(); |
186 } | 190 } |
187 | 191 |
188 void ServiceManager::OnServiceFactoryError(ServiceFactory* service_factory) { | 192 void ServiceManager::OnServiceFactoryError(ServiceFactory* service_factory) { |
| 193 // Called from ~ServiceFactory, so we do not need to call Destroy here. |
189 const GURL url = service_factory->url(); | 194 const GURL url = service_factory->url(); |
190 URLToServiceFactoryMap::iterator it = url_to_service_factory_.find(url); | 195 URLToServiceFactoryMap::iterator it = url_to_service_factory_.find(url); |
191 DCHECK(it != url_to_service_factory_.end()); | 196 DCHECK(it != url_to_service_factory_.end()); |
192 delete it->second; | 197 delete it->second; |
193 url_to_service_factory_.erase(it); | 198 url_to_service_factory_.erase(it); |
194 GetLoaderForURL(url)->OnServiceError(this, url); | 199 GetLoaderForURL(url)->OnServiceError(this, url); |
195 } | 200 } |
196 | 201 |
197 } // namespace mojo | 202 } // namespace mojo |
OLD | NEW |