application_manager.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/application_manager.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <stdio.h>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/lazy_instance.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/macros.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/stl_util.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/application_loader.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/common/common_type_converters.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/application/connect.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/interfaces/application/application.mojom.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/interfaces/application/shell.mojom.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/services/public/interfaces/content_handler/content_handler.mojom.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace {
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Used by TestAPI.
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool has_created_instance = false;
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass StubServiceProvider : public InterfaceImpl<ServiceProvider> {
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ServiceProvider* GetRemoteServiceProvider() { return client(); }
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void ConnectToService(const String& service_name,
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                ScopedMessagePipeHandle client_handle)
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MOJO_OVERRIDE {}
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ApplicationManager::LoadCallbacksImpl
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : public ApplicationLoader::LoadCallbacks {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  LoadCallbacksImpl(base::WeakPtr<ApplicationManager> manager,
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const GURL& requested_url,
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const GURL& requestor_url,
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    ServiceProviderPtr service_provider)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : manager_(manager),
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        requested_url_(requested_url),
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        requestor_url_(requestor_url),
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        service_provider_(service_provider.Pass()) {}
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~LoadCallbacksImpl() {}
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // LoadCallbacks implementation
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ScopedMessagePipeHandle RegisterApplication() OVERRIDE {
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ScopedMessagePipeHandle shell_handle;
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (manager_) {
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      manager_->RegisterLoadedApplication(requested_url_,
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          requestor_url_,
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          service_provider_.Pass(),
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          &shell_handle);
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return shell_handle.Pass();
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void LoadWithContentHandler(const GURL& content_handler_url,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      URLResponsePtr content) OVERRIDE {
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (manager_) {
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      manager_->LoadWithContentHandler(requested_url_,
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       requestor_url_,
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       content_handler_url,
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       content.Pass(),
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       service_provider_.Pass());
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::WeakPtr<ApplicationManager> manager_;
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GURL requested_url_;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GURL requestor_url_;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceProviderPtr service_provider_;
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ApplicationManager::ShellImpl : public InterfaceImpl<Shell> {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ShellImpl(ApplicationManager* manager, const GURL& url)
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : manager_(manager), url_(url) {}
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~ShellImpl() {}
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ConnectToClient(const GURL& requestor_url,
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       ServiceProviderPtr service_provider) {
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    client()->AcceptConnection(String::From(requestor_url),
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               service_provider.Pass());
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ServiceProvider implementation:
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void ConnectToApplication(
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const String& app_url,
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      InterfaceRequest<ServiceProvider> in_service_provider) OVERRIDE {
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceProviderPtr out_service_provider;
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    out_service_provider.Bind(in_service_provider.PassMessagePipe());
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    manager_->ConnectToApplication(
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        app_url.To<GURL>(), url_, out_service_provider.Pass());
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL& url() const { return url_; }
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1090de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  virtual void OnConnectionError() OVERRIDE {
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    manager_->OnShellImplError(this);
1110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
1120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ApplicationManager* const manager_;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url_;
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ShellImpl);
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)struct ApplicationManager::ContentHandlerConnection {
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ContentHandlerConnection(ApplicationManager* manager,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           const GURL& content_handler_url) {
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ServiceProviderPtr service_provider;
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BindToProxy(&service_provider_impl, &service_provider);
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    manager->ConnectToApplication(
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        content_handler_url, GURL(), service_provider.Pass());
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mojo::ConnectToService(service_provider_impl.client(), &content_handler);
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  StubServiceProvider service_provider_impl;
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ContentHandlerPtr content_handler;
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationManager::TestAPI::TestAPI(ApplicationManager* manager)
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : manager_(manager) {
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationManager::TestAPI::~TestAPI() {
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ApplicationManager::TestAPI::HasCreatedInstance() {
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return has_created_instance;
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ApplicationManager::TestAPI::HasFactoryForURL(const GURL& url) const {
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return manager_->url_to_shell_impl_.find(url) !=
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         manager_->url_to_shell_impl_.end();
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationManager::ApplicationManager()
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : interceptor_(NULL), weak_ptr_factory_(this) {
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationManager::~ApplicationManager() {
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  STLDeleteValues(&url_to_content_handler_);
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TerminateShellConnections();
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  STLDeleteValues(&url_to_loader_);
1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  STLDeleteValues(&scheme_to_loader_);
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::TerminateShellConnections() {
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  STLDeleteValues(&url_to_shell_impl_);
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationManager* ApplicationManager::GetInstance() {
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static base::LazyInstance<ApplicationManager> instance =
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      LAZY_INSTANCE_INITIALIZER;
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  has_created_instance = true;
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return &instance.Get();
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::ConnectToApplication(
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const GURL& url,
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const GURL& requestor_url,
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ServiceProviderPtr service_provider) {
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  URLToShellImplMap::const_iterator shell_it = url_to_shell_impl_.find(url);
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (shell_it != url_to_shell_impl_.end()) {
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ConnectToClient(
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        shell_it->second, url, requestor_url, service_provider.Pass());
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<LoadCallbacksImpl> callbacks(
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new LoadCallbacksImpl(weak_ptr_factory_.GetWeakPtr(),
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            url,
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            requestor_url,
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            service_provider.Pass()));
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetLoaderForURL(url)->Load(this, url, callbacks);
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::ConnectToClient(ShellImpl* shell_impl,
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         const GURL& url,
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         const GURL& requestor_url,
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         ServiceProviderPtr service_provider) {
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (interceptor_) {
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    shell_impl->ConnectToClient(
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        requestor_url,
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        interceptor_->OnConnectToClient(url, service_provider.Pass()));
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } else {
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    shell_impl->ConnectToClient(requestor_url, service_provider.Pass());
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::RegisterLoadedApplication(
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& url,
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& requestor_url,
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ServiceProviderPtr service_provider,
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ScopedMessagePipeHandle* shell_handle) {
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ShellImpl* shell_impl = NULL;
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  URLToShellImplMap::iterator iter = url_to_shell_impl_.find(url);
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (iter != url_to_shell_impl_.end()) {
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This can happen because services are loaded asynchronously. So if we get
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // two requests for the same service close to each other, we might get here
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // and find that we already have it.
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    shell_impl = iter->second;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MessagePipe pipe;
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    shell_impl = WeakBindToPipe(new ShellImpl(this, url), pipe.handle1.Pass());
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    url_to_shell_impl_[url] = shell_impl;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *shell_handle = pipe.handle0.Pass();
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ConnectToClient(shell_impl, url, requestor_url, service_provider.Pass());
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::LoadWithContentHandler(
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& content_url,
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& requestor_url,
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const GURL& content_handler_url,
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    URLResponsePtr content,
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ServiceProviderPtr service_provider) {
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ContentHandlerConnection* connection = NULL;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  URLToContentHandlerMap::iterator iter =
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      url_to_content_handler_.find(content_handler_url);
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (iter != url_to_content_handler_.end()) {
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection = iter->second;
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection = new ContentHandlerConnection(this, content_handler_url);
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    url_to_content_handler_[content_handler_url] = connection;
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  connection->content_handler->OnConnect(
2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      content_url.spec(), content.Pass(), service_provider.Pass());
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::SetLoaderForURL(scoped_ptr<ApplicationLoader> loader,
2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                         const GURL& url) {
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  URLToLoaderMap::iterator it = url_to_loader_.find(url);
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (it != url_to_loader_.end())
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    delete it->second;
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  url_to_loader_[url] = loader.release();
252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::SetLoaderForScheme(
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<ApplicationLoader> loader,
2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& scheme) {
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SchemeToLoaderMap::iterator it = scheme_to_loader_.find(scheme);
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (it != scheme_to_loader_.end())
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    delete it->second;
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheme_to_loader_[scheme] = loader.release();
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::SetInterceptor(Interceptor* interceptor) {
264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  interceptor_ = interceptor;
265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ApplicationLoader* ApplicationManager::GetLoaderForURL(const GURL& url) {
268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  URLToLoaderMap::const_iterator url_it = url_to_loader_.find(url);
269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (url_it != url_to_loader_.end())
270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return url_it->second;
271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SchemeToLoaderMap::const_iterator scheme_it =
272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      scheme_to_loader_.find(url.scheme());
273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (scheme_it != scheme_to_loader_.end())
274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return scheme_it->second;
2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return default_loader_.get();
276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ApplicationManager::OnShellImplError(ShellImpl* shell_impl) {
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Called from ~ShellImpl, so we do not need to call Destroy here.
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const GURL url = shell_impl->url();
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  URLToShellImplMap::iterator it = url_to_shell_impl_.find(url);
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(it != url_to_shell_impl_.end());
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete it->second;
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_to_shell_impl_.erase(it);
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ApplicationLoader* loader = GetLoaderForURL(url);
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (loader)
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    loader->OnServiceError(this, url);
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ScopedMessagePipeHandle ApplicationManager::ConnectToServiceByName(
2916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const GURL& application_url,
2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string& interface_name) {
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StubServiceProvider* stub_sp = new StubServiceProvider;
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceProviderPtr spp;
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BindToProxy(stub_sp, &spp);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ConnectToApplication(application_url, GURL(), spp.Pass());
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MessagePipe pipe;
2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  stub_sp->GetRemoteServiceProvider()->ConnectToService(interface_name,
2996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                        pipe.handle1.Pass());
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return pipe.handle0.Pass();
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace mojo
303