Allow external applications to register for mojo: urls
BUG=
R=aa@chromium.org
Review URL: https://codereview.chromium.org/861293002
diff --git a/shell/application_manager/application_manager.cc b/shell/application_manager/application_manager.cc
index ff386e0..8032d0f 100644
--- a/shell/application_manager/application_manager.cc
+++ b/shell/application_manager/application_manager.cc
@@ -107,6 +107,24 @@
ServiceProviderPtr exposed_services) {
DCHECK(requested_url.is_valid());
GURL mapped_url = delegate_->ResolveMappings(requested_url);
+
+ // We check both the mapped and resolved urls for existing shell_impls because
+ // external applications can be registered for the unresolved mojo:foo urls.
+ ShellImpl* shell_impl = GetShellImpl(mapped_url);
+ if (shell_impl) {
+ ConnectToClient(shell_impl, mapped_url, requestor_url, services.Pass(),
+ exposed_services.Pass());
+ return;
+ }
+
+ GURL resolved_url = delegate_->ResolveURL(mapped_url);
+ shell_impl = GetShellImpl(resolved_url);
+ if (shell_impl) {
+ ConnectToClient(shell_impl, resolved_url, requestor_url, services.Pass(),
+ exposed_services.Pass());
+ return;
+ }
+
ApplicationLoader* loader =
GetLoaderForURL(mapped_url, DONT_INCLUDE_DEFAULT_LOADER);
if (loader) {
@@ -115,7 +133,6 @@
return;
}
- GURL resolved_url = delegate_->ResolveURL(mapped_url);
loader = GetLoaderForURL(resolved_url, INCLUDE_DEFAULT_LOADER);
if (loader) {
ConnectToApplicationImpl(requested_url, resolved_url, requestor_url,
@@ -134,26 +151,26 @@
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services,
ApplicationLoader* loader) {
- ShellImpl* shell = nullptr;
- URLToShellImplMap::const_iterator shell_it =
- url_to_shell_impl_.find(resolved_url);
- if (shell_it != url_to_shell_impl_.end()) {
- shell = shell_it->second;
- } else {
- ShellPtr shell_ptr;
- shell =
- new ShellImpl(GetProxy(&shell_ptr), this, requested_url, resolved_url);
- url_to_shell_impl_[resolved_url] = shell;
- shell->client()->Initialize(GetArgsForURL(requested_url));
+ ShellPtr shell_ptr;
+ ShellImpl* shell =
+ new ShellImpl(GetProxy(&shell_ptr), this, requested_url, resolved_url);
+ url_to_shell_impl_[resolved_url] = shell;
+ shell->client()->Initialize(GetArgsForURL(requested_url));
- loader->Load(this, resolved_url, shell_ptr.Pass(),
- base::Bind(&ApplicationManager::LoadWithContentHandler,
- weak_ptr_factory_.GetWeakPtr()));
- }
+ loader->Load(this, resolved_url, shell_ptr.Pass(),
+ base::Bind(&ApplicationManager::LoadWithContentHandler,
+ weak_ptr_factory_.GetWeakPtr()));
ConnectToClient(shell, resolved_url, requestor_url, services.Pass(),
exposed_services.Pass());
}
+ShellImpl* ApplicationManager::GetShellImpl(const GURL& url) {
+ const auto& shell_it = url_to_shell_impl_.find(url);
+ if (shell_it != url_to_shell_impl_.end())
+ return shell_it->second;
+ return nullptr;
+}
+
void ApplicationManager::ConnectToClient(
ShellImpl* shell_impl,
const GURL& url,
diff --git a/shell/application_manager/application_manager.h b/shell/application_manager/application_manager.h
index f5b63c5..02fc308 100644
--- a/shell/application_manager/application_manager.h
+++ b/shell/application_manager/application_manager.h
@@ -116,6 +116,8 @@
ServiceProviderPtr exposed_services,
ApplicationLoader* loader);
+ ShellImpl* GetShellImpl(const GURL& url);
+
void ConnectToClient(ShellImpl* shell_impl,
const GURL& url,
const GURL& requestor_url,
diff --git a/shell/application_manager/application_manager_unittest.cc b/shell/application_manager/application_manager_unittest.cc
index f3b0503..b8da53b 100644
--- a/shell/application_manager/application_manager_unittest.cc
+++ b/shell/application_manager/application_manager_unittest.cc
@@ -415,6 +415,34 @@
std::map<GURL, GURL> mappings_;
};
+class TestExternal : public ApplicationDelegate {
+ public:
+ TestExternal()
+ : initialize_called_(false),
+ configure_incoming_connection_called_(false) {}
+
+ virtual void Initialize(ApplicationImpl* app) override {
+ initialize_called_ = true;
+ base::MessageLoop::current()->Quit();
+ }
+
+ virtual bool ConfigureIncomingConnection(
+ ApplicationConnection* connection) override {
+ configure_incoming_connection_called_ = true;
+ base::MessageLoop::current()->Quit();
+ return true;
+ }
+
+ bool initialize_called() const { return initialize_called_; }
+ bool configure_incoming_connection_called() const {
+ return configure_incoming_connection_called_;
+ }
+
+ private:
+ bool initialize_called_;
+ bool configure_incoming_connection_called_;
+};
+
} // namespace
class ApplicationManagerTest : public testing::Test {
@@ -696,4 +724,18 @@
custom_loader->set_context(nullptr);
}
+TEST_F(ApplicationManagerTest, ExternalApp) {
+ MessagePipe shell_pipe;
+ TestExternal external;
+ ApplicationImpl app(&external, shell_pipe.handle0.Pass());
+ application_manager_->RegisterExternalApplication(
+ GURL("mojo:test"), shell_pipe.handle1.Pass());
+ loop_.Run();
+ EXPECT_TRUE(external.initialize_called());
+ application_manager_->ConnectToServiceByName(
+ GURL("mojo:test"), std::string());
+ loop_.Run();
+ EXPECT_TRUE(external.configure_incoming_connection_called());
+};
+
} // namespace mojo