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

Unified 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: more gn 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/service_manager/service_manager.h ('k') | mojo/service_manager/service_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/service_manager/service_manager.cc
diff --git a/mojo/service_manager/service_manager.cc b/mojo/service_manager/service_manager.cc
index 51efd41feddd0c18205f30f0c4dd24e5a8fce0cf..b0ef1e87417f7736ad8890397c8fa67ffd7f179c 100644
--- a/mojo/service_manager/service_manager.cc
+++ b/mojo/service_manager/service_manager.cc
@@ -2,18 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <stdio.h>
-
#include "mojo/service_manager/service_manager.h"
+#include <stdio.h>
+
+#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "mojo/common/common_type_converters.h"
+#include "mojo/public/cpp/application/connect.h"
#include "mojo/public/interfaces/application/application.mojom.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/service_manager/service_loader.h"
+#include "mojo/services/public/interfaces/content_handler/content_handler.mojom.h"
namespace mojo {
@@ -33,7 +36,52 @@ class StubServiceProvider : public InterfaceImpl<ServiceProvider> {
ScopedMessagePipeHandle client_handle) MOJO_OVERRIDE {}
};
-}
+} // namespace
+
+class ServiceManager::LoadCallbacksImpl : public ServiceLoader::LoadCallbacks {
+ public:
+ LoadCallbacksImpl(base::WeakPtr<ServiceManager> manager,
+ const GURL& requested_url,
+ const GURL& requestor_url,
+ ServiceProviderPtr service_provider)
+ : manager_(manager),
+ requested_url_(requested_url),
+ requestor_url_(requestor_url),
+ service_provider_(service_provider.Pass()) {
+ }
+
+ private:
+ virtual ~LoadCallbacksImpl() {
+ }
+
+ // LoadCallbacks implementation
+ virtual ScopedMessagePipeHandle RegisterApplication() OVERRIDE {
+ ScopedMessagePipeHandle shell_handle;
+ if (manager_) {
+ manager_->RegisterLoadedApplication(requested_url_,
+ requestor_url_,
+ service_provider_.Pass(),
+ &shell_handle);
+ }
+ return shell_handle.Pass();
+ }
+
+ virtual void LoadWithContentHandler(const GURL& content_handler_url,
+ URLResponsePtr content) OVERRIDE {
+ if (manager_) {
+ manager_->LoadWithContentHandler(requested_url_,
+ requestor_url_,
+ content_handler_url,
+ content.Pass(),
+ service_provider_.Pass());
+ }
+ }
+
+ base::WeakPtr<ServiceManager> manager_;
+ GURL requested_url_;
+ GURL requestor_url_;
+ ServiceProviderPtr service_provider_;
+};
class ServiceManager::ShellImpl : public InterfaceImpl<Shell> {
public:
@@ -76,6 +124,21 @@ class ServiceManager::ShellImpl : public InterfaceImpl<Shell> {
DISALLOW_COPY_AND_ASSIGN(ShellImpl);
};
+struct ServiceManager::ContentHandlerConnection {
+ ContentHandlerConnection(ServiceManager* manager,
+ const GURL& content_handler_url) {
+ ServiceProviderPtr service_provider;
+ BindToProxy(&service_provider_impl, &service_provider);
+ manager->ConnectToApplication(content_handler_url,
+ GURL(),
+ service_provider.Pass());
+ mojo::ConnectToService(service_provider_impl.client(), &content_handler);
+ }
+
+ StubServiceProvider service_provider_impl;
+ ContentHandlerPtr content_handler;
+};
+
// static
ServiceManager::TestAPI::TestAPI(ServiceManager* manager) : manager_(manager) {
}
@@ -92,10 +155,13 @@ bool ServiceManager::TestAPI::HasFactoryForURL(const GURL& url) const {
manager_->url_to_shell_impl_.end();
}
-ServiceManager::ServiceManager() : interceptor_(NULL) {
+ServiceManager::ServiceManager()
+ : interceptor_(NULL),
+ weak_ptr_factory_(this) {
}
ServiceManager::~ServiceManager() {
+ STLDeleteValues(&url_to_content_handler_);
TerminateShellConnections();
STLDeleteValues(&url_to_loader_);
STLDeleteValues(&scheme_to_loader_);
@@ -117,15 +183,24 @@ void ServiceManager::ConnectToApplication(const GURL& url,
const GURL& requestor_url,
ServiceProviderPtr service_provider) {
URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url);
- ShellImpl* shell_impl;
if (shell_it != url_to_shell_impl_.end()) {
- shell_impl = shell_it->second;
- } else {
- MessagePipe pipe;
- GetLoaderForURL(url)->LoadService(this, url, pipe.handle0.Pass());
- shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
- url_to_shell_impl_[url] = shell_impl;
+ ConnectToClient(shell_it->second, url, requestor_url,
+ service_provider.Pass());
+ return;
}
+
+ scoped_refptr<LoadCallbacksImpl> callbacks(
+ new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(),
+ url,
+ requestor_url,
+ service_provider.Pass()));
+ GetLoaderForURL(url)->Load(this, url, callbacks);
+}
+
+void ServiceManager::ConnectToClient(ShellImpl* shell_impl,
+ const GURL& url,
+ const GURL& requestor_url,
+ ServiceProviderPtr service_provider) {
if (interceptor_) {
shell_impl->ConnectToClient(
requestor_url,
@@ -135,6 +210,48 @@ void ServiceManager::ConnectToApplication(const GURL& url,
}
}
+void ServiceManager::RegisterLoadedApplication(
+ const GURL& url,
+ const GURL& requestor_url,
+ ServiceProviderPtr service_provider,
+ ScopedMessagePipeHandle* shell_handle) {
+ ShellImpl* shell_impl = NULL;
+ URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url);
+ if (iter != url_to_shell_impl_.end()) {
+ // This can happen because services are loaded asynchronously. So if we get
+ // two requests for the same service close to each other, we might get here
+ // and find that we already have it.
+ shell_impl = iter->second;
+ } else {
+ MessagePipe pipe;
+ shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
+ url_to_shell_impl_[url] = shell_impl;
+ *shell_handle = pipe.handle0.Pass();
+ }
+
+ ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass());
+}
+
+void ServiceManager::LoadWithContentHandler(
+ const GURL& content_url,
+ const GURL& requestor_url,
+ const GURL& content_handler_url,
+ URLResponsePtr content,
+ ServiceProviderPtr service_provider) {
+ ContentHandlerConnection* connection = NULL;
+ URLToContentHandlerMap::iterator iter =
+ url_to_content_handler_.find(content_handler_url);
+ if (iter != url_to_content_handler_.end()) {
+ connection = iter->second;
+ } else {
+ connection = new ContentHandlerConnection(this, content_handler_url);
+ url_to_content_handler_[content_handler_url] = connection;
+ }
+ connection->content_handler->OnConnect(content_url.spec(),
+ content.Pass(),
+ service_provider.Pass());
+}
+
void ServiceManager::SetLoaderForURL(scoped_ptr<ServiceLoader> loader,
const GURL& url) {
URLToLoaderMap::iterator it = url_to_loader_.find(url);
« no previous file with comments | « mojo/service_manager/service_manager.h ('k') | mojo/service_manager/service_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698