15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/at_exit.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h"
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/message_loop/message_loop.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/application_loader.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/application_manager.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/background_shell_application_loader.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/test.mojom.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_connection.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_delegate.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_impl.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/application/interface_factory.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/interfaces/application/service_provider.mojom.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestURLString[] = "test:testService";
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kTestAURLString[] = "test:TestA";
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kTestBURLString[] = "test:TestB";
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct TestContext {
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestContext() : num_impls(0), num_loader_deletes(0) {}
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string last_test_string;
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int num_impls;
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int num_loader_deletes;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class QuitMessageLoopErrorHandler : public ErrorHandler {
346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public:
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  QuitMessageLoopErrorHandler() {}
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual ~QuitMessageLoopErrorHandler() {}
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // |ErrorHandler| implementation:
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual void OnConnectionError() OVERRIDE {
406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::MessageLoop::current()->QuitWhenIdle();
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private:
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuitMessageLoopErrorHandler);
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class TestServiceImpl : public InterfaceImpl<TestService> {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit TestServiceImpl(TestContext* context) : context_(context) {
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++context_->num_impls;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~TestServiceImpl() { --context_->num_impls; }
540de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnConnectionError() OVERRIDE {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!base::MessageLoop::current()->is_running())
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::MessageLoop::current()->Quit();
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // TestService implementation:
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void Test(const String& test_string) OVERRIDE {
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    context_->last_test_string = test_string;
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client()->AckTest();
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) private:
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestContext* context_;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestClientImpl : public TestClient {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
730de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  explicit TestClientImpl(TestServicePtr service)
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : service_(service.Pass()), quit_after_ack_(false) {
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    service_.set_client(this);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~TestClientImpl() { service_.reset(); }
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AckTest() OVERRIDE {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (quit_after_ack_)
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::MessageLoop::current()->Quit();
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Test(std::string test_string) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    quit_after_ack_ = true;
870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    service_->Test(test_string);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  TestServicePtr service_;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool quit_after_ack_;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestClientImpl);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class TestApplicationLoader : public ApplicationLoader,
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              public ApplicationDelegate,
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              public InterfaceFactory<TestService> {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestApplicationLoader() : context_(NULL), num_loads_(0) {}
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~TestApplicationLoader() {
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (context_)
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ++context_->num_loader_deletes;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    test_app_.reset(NULL);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void set_context(TestContext* context) { context_ = context; }
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int num_loads() const { return num_loads_; }
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<std::string> GetArgs() {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return test_app_->args().To<std::vector<std::string> >();
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ApplicationLoader implementation.
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void Load(ApplicationManager* manager,
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const GURL& url,
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ++num_loads_;
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_app_.reset(
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new ApplicationImpl(this, callbacks->RegisterApplication().Pass()));
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnApplicationError(ApplicationManager* manager,
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const GURL& url) OVERRIDE {}
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // ApplicationDelegate implementation.
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ConfigureIncomingConnection(
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ApplicationConnection* connection) OVERRIDE {
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection->AddService(this);
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // InterfaceFactory implementation.
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Create(ApplicationConnection* connection,
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      InterfaceRequest<TestService> request) OVERRIDE {
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BindToRequest(new TestServiceImpl(context_), &request);
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ApplicationImpl> test_app_;
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestContext* context_;
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int num_loads_;
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch};
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TesterContext {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit TesterContext(base::MessageLoop* loop)
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : num_b_calls_(0),
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        num_c_calls_(0),
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        num_a_deletes_(0),
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        num_b_deletes_(0),
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        num_c_deletes_(0),
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tester_called_quit_(false),
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        a_called_quit_(false),
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        loop_(loop) {}
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void IncrementNumBCalls() {
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    num_b_calls_++;
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void IncrementNumCCalls() {
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    num_c_calls_++;
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void IncrementNumADeletes() {
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    num_a_deletes_++;
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void IncrementNumBDeletes() {
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    num_b_deletes_++;
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void IncrementNumCDeletes() {
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    num_c_deletes_++;
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void set_tester_called_quit() {
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    tester_called_quit_ = true;
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void set_a_called_quit() {
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    a_called_quit_ = true;
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_b_calls() {
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return num_b_calls_;
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_c_calls() {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return num_c_calls_;
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_a_deletes() {
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return num_a_deletes_;
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_b_deletes() {
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return num_b_deletes_;
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_c_deletes() {
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return num_c_deletes_;
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool tester_called_quit() {
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return tester_called_quit_;
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool a_called_quit() {
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::AutoLock lock(lock_);
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return a_called_quit_;
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void QuitSoon() {
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    loop_->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // lock_ protects all members except for loop_ which must be unchanged for the
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // lifetime of this class.
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::Lock lock_;
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_b_calls_;
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_c_calls_;
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_a_deletes_;
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_b_deletes_;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int num_c_deletes_;
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool tester_called_quit_;
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool a_called_quit_;
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::MessageLoop* loop_;
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Used to test that the requestor url will be correctly passed.
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class TestAImpl : public InterfaceImpl<TestA> {
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestAImpl(ApplicationConnection* connection, TesterContext* test_context)
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : test_context_(test_context) {
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    connection->ConnectToApplication(kTestBURLString)->ConnectToService(&b_);
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~TestAImpl() {
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->IncrementNumADeletes();
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (base::MessageLoop::current()->is_running())
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Quit();
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void CallB() OVERRIDE {
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    b_->B(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void CallCFromB() OVERRIDE {
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    b_->CallC(base::Bind(&TestAImpl::Quit, base::Unretained(this)));
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Quit() {
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::MessageLoop::current()->Quit();
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->set_a_called_quit();
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->QuitSoon();
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TesterContext* test_context_;
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestBPtr b_;
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class TestBImpl : public InterfaceImpl<TestB> {
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestBImpl(ApplicationConnection* connection, TesterContext* test_context)
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : test_context_(test_context) {
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    connection->ConnectToService(&c_);
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~TestBImpl() {
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->IncrementNumBDeletes();
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (base::MessageLoop::current()->is_running())
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::MessageLoop::current()->Quit();
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->QuitSoon();
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void B(const mojo::Callback<void()>& callback) OVERRIDE {
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->IncrementNumBCalls();
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run();
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void CallC(const mojo::Callback<void()>& callback) OVERRIDE {
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->IncrementNumBCalls();
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    c_->C(callback);
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TesterContext* test_context_;
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestCPtr c_;
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass TestCImpl : public InterfaceImpl<TestC> {
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestCImpl(ApplicationConnection* connection, TesterContext* test_context)
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : test_context_(test_context) {}
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~TestCImpl() { test_context_->IncrementNumCDeletes(); }
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void C(const mojo::Callback<void()>& callback) OVERRIDE {
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    test_context_->IncrementNumCCalls();
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    callback.Run();
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TesterContext* test_context_;
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class Tester : public ApplicationDelegate,
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)               public ApplicationLoader,
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               public InterfaceFactory<TestA>,
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               public InterfaceFactory<TestB>,
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               public InterfaceFactory<TestC> {
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Tester(TesterContext* context, const std::string& requestor_url)
3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : context_(context), requestor_url_(requestor_url) {}
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~Tester() {}
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void Load(ApplicationManager* manager,
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const GURL& url,
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    app_.reset(
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new ApplicationImpl(this, callbacks->RegisterApplication().Pass()));
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnApplicationError(ApplicationManager* manager,
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const GURL& url) OVERRIDE {}
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ConfigureIncomingConnection(
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ApplicationConnection* connection) OVERRIDE {
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!requestor_url_.empty() &&
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        requestor_url_ != connection->GetRemoteApplicationURL()) {
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      context_->set_tester_called_quit();
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      context_->QuitSoon();
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::MessageLoop::current()->Quit();
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return false;
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If we're coming from A, then add B, otherwise A.
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (connection->GetRemoteApplicationURL() == kTestAURLString)
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      connection->AddService<TestB>(this);
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    else
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      connection->AddService<TestA>(this);
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ConfigureOutgoingConnection(
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ApplicationConnection* connection) OVERRIDE {
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If we're connecting to B, then add C.
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (connection->GetRemoteApplicationURL() == kTestBURLString)
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      connection->AddService<TestC>(this);
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Create(ApplicationConnection* connection,
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      InterfaceRequest<TestA> request) OVERRIDE {
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BindToRequest(new TestAImpl(connection, context_), &request);
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Create(ApplicationConnection* connection,
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      InterfaceRequest<TestB> request) OVERRIDE {
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BindToRequest(new TestBImpl(connection, context_), &request);
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Create(ApplicationConnection* connection,
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      InterfaceRequest<TestC> request) OVERRIDE {
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BindToRequest(new TestCImpl(connection, context_), &request);
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TesterContext* context_;
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ApplicationImpl> app_;
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string requestor_url_;
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class TestServiceInterceptor : public ApplicationManager::Interceptor {
384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TestServiceInterceptor() : call_count_(0) {}
386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ServiceProviderPtr OnConnectToClient(
3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const GURL& url,
3896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ServiceProviderPtr service_provider) OVERRIDE {
390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ++call_count_;
391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    url_ = url;
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return service_provider.Pass();
393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url_spec() const {
396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!url_.is_valid())
397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return "invalid url";
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return url_.spec();
399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  int call_count() const { return call_count_; }
402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
403a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int call_count_;
405a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GURL url_;
406a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(TestServiceInterceptor);
407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
4090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace
4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ApplicationManagerTest : public testing::Test {
4120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
4136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ApplicationManagerTest() : tester_context_(&loop_) {}
4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~ApplicationManagerTest() {}
4160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void SetUp() OVERRIDE {
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    application_manager_.reset(new ApplicationManager);
4196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* default_loader = new TestApplicationLoader;
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    default_loader->set_context(&context_);
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    application_manager_->set_default_loader(
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        scoped_ptr<ApplicationLoader>(default_loader));
4230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TestServicePtr service_proxy;
4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    application_manager_->ConnectToService(GURL(kTestURLString),
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                           &service_proxy);
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    test_client_.reset(new TestClientImpl(service_proxy.Pass()));
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void TearDown() OVERRIDE {
4310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    test_client_.reset(NULL);
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    application_manager_.reset(NULL);
4330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<BackgroundShellApplicationLoader> MakeLoader(
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::string& requestor_url) {
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<ApplicationLoader> real_loader(
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new Tester(&tester_context_, requestor_url));
4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<BackgroundShellApplicationLoader> loader(
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new BackgroundShellApplicationLoader(real_loader.Pass(),
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                             std::string(),
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                             base::MessageLoop::TYPE_DEFAULT));
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return loader.Pass();
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void AddLoaderForURL(const GURL& url, const std::string& requestor_url) {
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    application_manager_->SetLoaderForURL(
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        MakeLoader(requestor_url).PassAs<ApplicationLoader>(), url);
4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool HasFactoryForTestURL() {
4526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ApplicationManager::TestAPI manager_test_api(application_manager_.get());
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return manager_test_api.HasFactoryForURL(GURL(kTestURLString));
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch protected:
457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ShadowingAtExitManager at_exit_;
4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TesterContext tester_context_;
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestContext context_;
4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::MessageLoop loop_;
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<TestClientImpl> test_client_;
4626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ApplicationManager> application_manager_;
4636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ApplicationManagerTest);
4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
4650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, Basic) {
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_client_->Test("test");
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  loop_.Run();
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(std::string("test"), context_.last_test_string);
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Confirm that no arguments are sent to an application by default.
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ApplicationManagerTest, NoArgs) {
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ApplicationManager am;
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url("test:test");
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestContext context;
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestApplicationLoader* loader = new TestApplicationLoader;
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loader->set_context(&context);
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url);
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestServicePtr test_service;
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  am.ConnectToService(test_url, &test_service);
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestClientImpl test_client(test_service.Pass());
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test_client.Test("test");
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loop_.Run();
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<std::string> app_args = loader->GetArgs();
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0U, app_args.size());
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Confirm that arguments are sent to an application.
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ApplicationManagerTest, Args) {
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ApplicationManager am;
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL test_url("test:test");
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<std::string> args;
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args.push_back("test_arg1");
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  args.push_back("test_arg2");
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  am.SetArgsForURL(args, test_url);
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestContext context;
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestApplicationLoader* loader = new TestApplicationLoader;
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loader->set_context(&context);
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(loader), test_url);
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestServicePtr test_service;
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  am.ConnectToService(test_url, &test_service);
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestClientImpl test_client(test_service.Pass());
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  test_client.Test("test");
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  loop_.Run();
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<std::string> app_args = loader->GetArgs();
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(args.size(), app_args.size());
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(args[0], app_args[0]);
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(args[1], app_args[1]);
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, ClientError) {
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_client_->Test("test");
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(HasFactoryForTestURL());
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  loop_.Run();
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, context_.num_impls);
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_client_.reset(NULL);
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  loop_.Run();
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, context_.num_impls);
520f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(HasFactoryForTestURL());
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, Deletes) {
5240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  {
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ApplicationManager am;
5266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* default_loader = new TestApplicationLoader;
5270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    default_loader->set_context(&context_);
5286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* url_loader1 = new TestApplicationLoader;
5296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* url_loader2 = new TestApplicationLoader;
5300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    url_loader1->set_context(&context_);
5310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    url_loader2->set_context(&context_);
5326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* scheme_loader1 = new TestApplicationLoader;
5336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TestApplicationLoader* scheme_loader2 = new TestApplicationLoader;
5340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scheme_loader1->set_context(&context_);
5350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scheme_loader2->set_context(&context_);
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    am.set_default_loader(scoped_ptr<ApplicationLoader>(default_loader));
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader1),
5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       GURL("test:test1"));
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    am.SetLoaderForURL(scoped_ptr<ApplicationLoader>(url_loader2),
5400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       GURL("test:test1"));
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader1),
5426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          "test");
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    am.SetLoaderForScheme(scoped_ptr<ApplicationLoader>(scheme_loader2),
5446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          "test");
5450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(5, context_.num_loader_deletes);
5470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
549effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Confirm that both urls and schemes can have their loaders explicitly set.
5506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, SetLoaders) {
5516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestApplicationLoader* default_loader = new TestApplicationLoader;
5526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestApplicationLoader* url_loader = new TestApplicationLoader;
5536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestApplicationLoader* scheme_loader = new TestApplicationLoader;
5546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->set_default_loader(
5556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      scoped_ptr<ApplicationLoader>(default_loader));
5566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->SetLoaderForURL(
5576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      scoped_ptr<ApplicationLoader>(url_loader), GURL("test:test1"));
5586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->SetLoaderForScheme(
5596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      scoped_ptr<ApplicationLoader>(scheme_loader), "test");
560effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
561effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // test::test1 should go to url_loader.
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestServicePtr test_service;
5636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL("test:test1"), &test_service);
5640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, url_loader->num_loads());
5650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(0, scheme_loader->num_loads());
5660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(0, default_loader->num_loads());
567effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
568effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // test::test2 should go to scheme loader.
5696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL("test:test2"), &test_service);
5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, url_loader->num_loads());
5710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, scheme_loader->num_loads());
5720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(0, default_loader->num_loads());
573effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
574effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // http::test1 should go to default loader.
5756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL("http:test1"), &test_service);
5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, url_loader->num_loads());
5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, scheme_loader->num_loads());
5780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, default_loader->num_loads());
579effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
580effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Confirm that the url of a service is correctly passed to another service that
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// it loads.
5836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, ACallB) {
58446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Any url can load a.
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestAURLString), std::string());
58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Only a can load b.
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
58946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestAPtr a;
5916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(kTestAURLString), &a);
592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  a->CallB();
59346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  loop_.Run();
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(1, tester_context_.num_b_calls());
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(tester_context_.a_called_quit());
596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
598116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// A calls B which calls C.
5996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, BCallC) {
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Any url can load a.
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestAURLString), std::string());
602116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Only a can load b.
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestBURLString), kTestAURLString);
605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
606116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestAPtr a;
6076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(kTestAURLString), &a);
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  a->CallCFromB();
609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  loop_.Run();
610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(1, tester_context_.num_b_calls());
6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(1, tester_context_.num_c_calls());
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(tester_context_.a_called_quit());
614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Confirm that a service impl will be deleted if the app that connected to
617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// it goes away.
6186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, BDeleted) {
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestAURLString), std::string());
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestBURLString), std::string());
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestAPtr a;
6236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(kTestAURLString), &a);
624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  a->CallB();
626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  loop_.Run();
627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Kills the a app.
6296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->SetLoaderForURL(scoped_ptr<ApplicationLoader>(),
6306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                        GURL(kTestAURLString));
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  loop_.Run();
6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(1, tester_context_.num_b_deletes());
63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Confirm that the url of a service is correctly passed to another service that
63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// it loads, and that it can be rejected.
6386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, ANoLoadB) {
63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Any url can load a.
6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestAURLString), std::string());
64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Only c can load b, so this will fail.
6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestBURLString), "test:TestC");
64446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestAPtr a;
6466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(kTestAURLString), &a);
647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  a->CallB();
64846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  loop_.Run();
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(0, tester_context_.num_b_calls());
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(tester_context_.a_called_quit());
6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(tester_context_.tester_called_quit());
65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
65446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, NoServiceNoLoad) {
6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddLoaderForURL(GURL(kTestAURLString), std::string());
6576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // There is no TestC service implementation registered with
6596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ApplicationManager, so this cannot succeed (but also shouldn't crash).
660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  TestCPtr c;
6616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(kTestAURLString), &c);
6626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  QuitMessageLoopErrorHandler quitter;
663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  c.set_error_handler(&quitter);
6646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  loop_.Run();
666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(c.encountered_error());
6676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
6686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
6696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ApplicationManagerTest, Interceptor) {
670a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TestServiceInterceptor interceptor;
6716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestApplicationLoader* default_loader = new TestApplicationLoader;
6726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->set_default_loader(
6736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      scoped_ptr<ApplicationLoader>(default_loader));
6746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->SetInterceptor(&interceptor);
675a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
676a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string url("test:test3");
67746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestServicePtr test_service;
6786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  application_manager_->ConnectToService(GURL(url), &test_service);
679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
680a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(1, interceptor.call_count());
681a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_EQ(url, interceptor.url_spec());
6820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, default_loader->num_loads());
683a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
684a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace mojo
686