[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / mojo / service_manager / service_manager.cc
blob7b5be43d175bb8ef280efbaee6658b673109b9fa
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
3 // found in the LICENSE file.
5 #include <stdio.h>
7 #include "mojo/service_manager/service_manager.h"
9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/stl_util.h"
13 #include "mojo/common/common_type_converters.h"
14 #include "mojo/service_manager/service_loader.h"
16 namespace mojo {
18 namespace {
19 // Used by TestAPI.
20 bool has_created_instance = false;
22 class StubServiceProvider : public InterfaceImpl<ServiceProvider> {
23 public:
24 ServiceProvider* GetRemoteServiceProvider() {
25 return client();
28 private:
29 virtual void ConnectToService(
30 const String& service_name,
31 ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {}
36 class ServiceManager::ShellImpl : public InterfaceImpl<Shell> {
37 public:
38 ShellImpl(ServiceManager* manager, const GURL& url)
39 : manager_(manager),
40 url_(url) {
43 virtual ~ShellImpl() {
46 void ConnectToClient(const GURL& requestor_url,
47 ServiceProviderPtr service_provider) {
48 client()->AcceptConnection(String::From(requestor_url),
49 service_provider.Pass());
52 // ServiceProvider implementation:
53 virtual void ConnectToApplication(
54 const String& app_url,
55 InterfaceRequest<ServiceProvider> in_service_provider) OVERRIDE {
56 ServiceProviderPtr out_service_provider;
57 out_service_provider.Bind(in_service_provider.PassMessagePipe());
58 manager_->ConnectToApplication(
59 app_url.To<GURL>(),
60 url_,
61 out_service_provider.Pass());
64 const GURL& url() const { return url_; }
66 private:
67 virtual void OnConnectionError() OVERRIDE {
68 manager_->OnShellImplError(this);
71 ServiceManager* const manager_;
72 const GURL url_;
74 DISALLOW_COPY_AND_ASSIGN(ShellImpl);
77 // static
78 ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) {
81 ServiceManager::TestAPI::~TestAPI() {
84 bool ServiceManager::TestAPI::HasCreatedInstance() {
85 return has_created_instance;
88 bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
89 return manager_->url_to_shell_impl_.find(url) !=
90 manager_->url_to_shell_impl_.end();
93 ServiceManager::ServiceManager() : interceptor_(NULL) {
96 ServiceManager::~ServiceManager() {
97 STLDeleteValues(&url_to_shell_impl_);
98 STLDeleteValues(&url_to_loader_);
99 STLDeleteValues(&scheme_to_loader_);
102 // static
103 ServiceManager* ServiceManager::GetInstance() {
104 static base::LazyInstance<ServiceManager> instance =
105 LAZY_INSTANCE_INITIALIZER;
106 has_created_instance = true;
107 return &instance.Get();
110 void ServiceManager::ConnectToApplication(const GURL& url,
111 const GURL& requestor_url,
112 ServiceProviderPtr service_provider) {
113 URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url);
114 ShellImpl* shell_impl;
115 if (shell_it != url_to_shell_impl_.end()) {
116 shell_impl = shell_it->second;
117 } else {
118 MessagePipe pipe;
119 GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass());
120 shell_impl = BindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
121 url_to_shell_impl_[url] = shell_impl;
123 if (interceptor_) {
124 shell_impl->ConnectToClient(
125 requestor_url,
126 interceptor_->OnConnectToClient(url, service_provider.Pass()));
127 } else {
128 shell_impl->ConnectToClient(requestor_url, service_provider.Pass());
132 void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
133 const GURL& url) {
134 URLToLoaderMap::iterator it = url_to_loader_.find(url);
135 if (it != url_to_loader_.end())
136 delete it->second;
137 url_to_loader_[url] = loader.release();
140 void ServiceManager::SetLoaderForScheme(scoped_ptr<ServiceLoader> loader,
141 const std::string& scheme) {
142 SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme);
143 if (it != scheme_to_loader_.end())
144 delete it->second;
145 scheme_to_loader_[scheme] = loader.release();
148 void ServiceManager::SetInterceptor(Interceptor* interceptor) {
149 interceptor_ = interceptor;
152 ServiceLoader* ServiceManager::GetLoaderForURL(const GURL& url) {
153 URLToLoaderMap::const_iterator url_it = url_to_loader_.find(url);
154 if (url_it != url_to_loader_.end())
155 return url_it->second;
156 SchemeToLoaderMap::const_iterator scheme_it =
157 scheme_to_loader_.find(url.scheme());
158 if (scheme_it != scheme_to_loader_.end())
159 return scheme_it->second;
160 DCHECK(default_loader_);
161 return default_loader_.get();
164 void ServiceManager::OnShellImplError(ShellImpl* shell_impl) {
165 // Called from ~ShellImpl, so we do not need to call Destroy here.
166 const GURL url = shell_impl->url();
167 URLToShellImplMap::iterator it = url_to_shell_impl_.find(url);
168 DCHECK(it != url_to_shell_impl_.end());
169 delete it->second;
170 url_to_shell_impl_.erase(it);
171 ServiceLoader* loader = GetLoaderForURL(url);
172 if (loader)
173 loader->OnServiceError(this, url);
176 ScopedMessagePipeHandle ServiceManager::ConnectToServiceByName(
177 const GURL& application_url,
178 const std::string& interface_name) {
179 StubServiceProvider* stub_sp = new StubServiceProvider;
180 ServiceProviderPtr spp;
181 BindToProxy(stub_sp, &spp);
182 ConnectToApplication(application_url, GURL(), spp.Pass());
183 MessagePipe pipe;
184 stub_sp->GetRemoteServiceProvider()->ConnectToService(
185 interface_name, pipe.handle1.Pass());
186 return pipe.handle0.Pass();
188 } // namespace mojo