service_manager.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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. 4 5#include "mojo/service_manager/service_manager.h" 6 7#include "base/lazy_instance.h" 8#include "base/logging.h" 9#include "mojo/public/bindings/allocation_scope.h" 10#include "mojo/public/bindings/error_handler.h" 11#include "mojo/public/bindings/remote_ptr.h" 12#include "mojo/service_manager/service_loader.h" 13 14namespace mojo { 15 16class ServiceManager::ServiceFactory : public Shell, public ErrorHandler { 17 public: 18 ServiceFactory(ServiceManager* manager, const GURL& url) 19 : manager_(manager), 20 url_(url) { 21 InterfacePipe<Shell> pipe; 22 shell_client_.reset(pipe.handle_to_peer.Pass(), this, this); 23 manager_->GetLoaderForURL(url)->LoadService(manager_, 24 url, 25 pipe.handle_to_self.Pass()); 26 } 27 virtual ~ServiceFactory() {} 28 29 void ConnectToClient(ScopedMessagePipeHandle handle) { 30 if (handle.is_valid()) { 31 AllocationScope scope; 32 shell_client_->AcceptConnection(url_.spec(), handle.Pass()); 33 } 34 } 35 36 virtual void Connect(const String& url, 37 ScopedMessagePipeHandle client_pipe) MOJO_OVERRIDE { 38 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); 39 } 40 41 virtual void OnError() MOJO_OVERRIDE { 42 manager_->RemoveServiceFactory(this); 43 } 44 45 const GURL& url() const { return url_; } 46 47 private: 48 ServiceManager* const manager_; 49 const GURL url_; 50 RemotePtr<ShellClient> shell_client_; 51 DISALLOW_COPY_AND_ASSIGN(ServiceFactory); 52}; 53 54bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const { 55 return manager_->url_to_service_factory_.find(url) != 56 manager_->url_to_service_factory_.end(); 57} 58 59ServiceManager::ServiceManager() : default_loader_(NULL) { 60} 61 62ServiceManager::~ServiceManager() { 63 for (ServiceFactoryMap::iterator it = url_to_service_factory_.begin(); 64 it != url_to_service_factory_.end(); ++it) { 65 delete it->second; 66 } 67 url_to_service_factory_.clear(); 68} 69 70// static 71ServiceManager* GetInstance() { 72 static base::LazyInstance<ServiceManager> instance = 73 LAZY_INSTANCE_INITIALIZER; 74 return &instance.Get(); 75} 76 77void ServiceManager::SetLoaderForURL(ServiceLoader* loader, const GURL& gurl) { 78 DCHECK(url_to_loader_.find(gurl) == url_to_loader_.end()); 79 url_to_loader_[gurl] = loader; 80} 81 82ServiceLoader* ServiceManager::GetLoaderForURL(const GURL& gurl) { 83 LoaderMap::const_iterator it = url_to_loader_.find(gurl); 84 if (it != url_to_loader_.end()) 85 return it->second; 86 DCHECK(default_loader_); 87 return default_loader_; 88} 89 90void ServiceManager::Connect(const GURL& url, 91 ScopedMessagePipeHandle client_handle) { 92 ServiceFactoryMap::const_iterator service_it = 93 url_to_service_factory_.find(url); 94 ServiceFactory* service_factory; 95 if (service_it != url_to_service_factory_.end()) { 96 service_factory = service_it->second; 97 } else { 98 service_factory = new ServiceFactory(this, url); 99 url_to_service_factory_[url] = service_factory; 100 } 101 service_factory->ConnectToClient(client_handle.Pass()); 102} 103 104void ServiceManager::RemoveServiceFactory(ServiceFactory* service_factory) { 105 ServiceFactoryMap::iterator it = 106 url_to_service_factory_.find(service_factory->url()); 107 DCHECK(it != url_to_service_factory_.end()); 108 delete it->second; 109 url_to_service_factory_.erase(it); 110} 111 112} // namespace mojo 113