#include "mojo/shell/service_manager.h"
#include "base/logging.h"
-#include "mojo/public/bindings/lib/remote_ptr.h"
+#include "mojo/public/bindings/allocation_scope.h"
+#include "mojo/public/bindings/error_handler.h"
+#include "mojo/public/bindings/remote_ptr.h"
#include "mojom/shell.h"
namespace mojo {
namespace shell {
-class ServiceManager::Service : public Shell {
+class ServiceManager::ServiceFactory : public Shell, public ErrorHandler {
public:
- Service(ServiceManager* manager, const GURL& url)
+ ServiceFactory(ServiceManager* manager, const GURL& url)
: manager_(manager),
url_(url) {
- MessagePipe pipe;
- shell_client_.reset(pipe.handle0.Pass(), this);
- manager_->GetLoaderForURL(url)->Load(url, pipe.handle1.Pass());
+ InterfacePipe<Shell> pipe;
+ shell_client_.reset(pipe.handle_to_peer.Pass(), this, this);
+ manager_->GetLoaderForURL(url)->Load(url, pipe.handle_to_self.Pass());
}
- virtual ~Service() {}
+ virtual ~ServiceFactory() {}
void ConnectToClient(ScopedMessagePipeHandle handle) {
- if (handle.is_valid())
- shell_client_->AcceptConnection(handle.Pass());
+ if (handle.is_valid()) {
+ AllocationScope scope;
+ shell_client_->AcceptConnection(url_.spec(), handle.Pass());
+ }
}
virtual void Connect(const String& url,
manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass());
}
+ virtual void OnError() MOJO_OVERRIDE {
+ manager_->RemoveServiceFactory(this);
+ }
+
+ const GURL& url() const { return url_; }
+
private:
- ServiceManager* manager_;
- GURL url_;
+ ServiceManager* const manager_;
+ const GURL url_;
RemotePtr<ShellClient> shell_client_;
- DISALLOW_COPY_AND_ASSIGN(Service);
+ DISALLOW_COPY_AND_ASSIGN(ServiceFactory);
};
ServiceManager::Loader::Loader() {}
ServiceManager::Loader::~Loader() {}
+bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
+ return manager_->url_to_service_factory_.find(url) !=
+ manager_->url_to_service_factory_.end();
+}
+
ServiceManager::ServiceManager() : default_loader_(NULL) {
}
ServiceManager::~ServiceManager() {
- for (ServiceMap::iterator it = url_to_service_.begin();
- it != url_to_service_.end(); ++it) {
+ for (ServiceFactoryMap::iterator it = url_to_service_factory_.begin();
+ it != url_to_service_factory_.end(); ++it) {
delete it->second;
}
- url_to_service_.clear();
+ url_to_service_factory_.clear();
}
void ServiceManager::SetLoaderForURL(Loader* loader, const GURL& gurl) {
}
void ServiceManager::Connect(const GURL& url,
- ScopedMessagePipeHandle client_handle) {
- ServiceMap::const_iterator service_it = url_to_service_.find(url);
- Service* service;
- if (service_it != url_to_service_.end()) {
- service = service_it->second;
+ ScopedMessagePipeHandle client_handle) {
+ ServiceFactoryMap::const_iterator service_it =
+ url_to_service_factory_.find(url);
+ ServiceFactory* service_factory;
+ if (service_it != url_to_service_factory_.end()) {
+ service_factory = service_it->second;
} else {
- service = new Service(this, url);
- url_to_service_[url] = service;
+ service_factory = new ServiceFactory(this, url);
+ url_to_service_factory_[url] = service_factory;
}
- service->ConnectToClient(client_handle.Pass());
+ service_factory->ConnectToClient(client_handle.Pass());
+}
+
+void ServiceManager::RemoveServiceFactory(ServiceFactory* service_factory) {
+ ServiceFactoryMap::iterator it =
+ url_to_service_factory_.find(service_factory->url());
+ DCHECK(it != url_to_service_factory_.end());
+ delete it->second;
+ url_to_service_factory_.erase(it);
}
} // namespace shell