Index: mojo/shell/shell_test_helper.cc |
diff --git a/mojo/shell/shell_test_helper.cc b/mojo/shell/shell_test_helper.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..75db6e4771bcb1f486115cb37a4af9fa47cdb72f |
--- /dev/null |
+++ b/mojo/shell/shell_test_helper.cc |
@@ -0,0 +1,115 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/shell/shell_test_helper.h" |
+ |
+#include "base/command_line.h" |
+#include "base/logging.h" |
+#include "base/message_loop/message_loop.h" |
+#include "mojo/shell/context.h" |
+#include "mojo/shell/init.h" |
+ |
+namespace mojo { |
+namespace shell { |
+ |
+// State used on the background thread. Be careful, this is created on the main |
+// thread than passed to the shell thread. Destruction happens on the shell |
+// thread. |
+struct ShellTestHelper::State { |
+ scoped_ptr<Context> context; |
+ ScopedShellHandle shell_handle; |
+}; |
+ |
+namespace { |
+ |
+class TestServiceLoader : public ServiceLoader { |
+ public: |
+ explicit TestServiceLoader(ScopedShellHandle* handle) : handle_(handle) {} |
+ virtual ~TestServiceLoader() {} |
+ |
+ // ServiceLoader: |
+ virtual void LoadService(ServiceManager* manager, |
+ const GURL& url, |
+ ScopedShellHandle service_handle) OVERRIDE { |
+ // Bounce the handle back to the main thread. |
+ *handle_ = service_handle.Pass(); |
+ } |
+ |
+ virtual void OnServiceError(ServiceManager* manager, |
+ const GURL& url) OVERRIDE { |
+ CHECK(false); |
+ } |
+ |
+ private: |
+ ScopedShellHandle* handle_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TestServiceLoader); |
+}; |
+ |
+void StartShellOnShellThread(ShellTestHelper::State* state) { |
+ state->context.reset(new Context); |
+ MessagePipe pipe; |
+ state->context->service_manager()->set_default_loader( |
+ scoped_ptr<ServiceLoader>(new TestServiceLoader(&state->shell_handle))); |
+ state->context->service_manager()->Connect(GURL("test:test"), |
+ pipe.handle0.Pass()); |
+ // Destroy TestServiceLoader as it's no longer needed. |
+ state->context->service_manager()->set_default_loader( |
+ scoped_ptr<ServiceLoader>()); |
+} |
+ |
+} // namespace |
+ |
+class ShellTestHelper::TestShellClient : public ShellClient { |
+ public: |
+ TestShellClient() {} |
+ virtual ~TestShellClient() {} |
+ |
+ // ShellClient: |
+ virtual void AcceptConnection( |
+ const mojo::String& url, |
+ ScopedMessagePipeHandle client_handle) OVERRIDE { |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(TestShellClient); |
+}; |
+ |
+ShellTestHelper::ShellTestHelper() |
+ : shell_thread_("Test Shell Thread"), |
+ state_(NULL) { |
+ CommandLine::Init(0, NULL); |
+ mojo::shell::InitializeLogging(); |
+} |
+ |
+ShellTestHelper::~ShellTestHelper() { |
+ if (state_) { |
+ // |state_| contains data created on the background thread. Destroy it |
+ // there so that there aren't any race conditions. |
+ shell_thread_.message_loop()->DeleteSoon(FROM_HERE, state_); |
+ state_ = NULL; |
+ } |
+} |
+ |
+void ShellTestHelper::Init() { |
+ DCHECK(!state_); |
+ state_ = new State; |
+ shell_thread_.Start(); |
+ shell_thread_.message_loop()->message_loop_proxy()->PostTaskAndReply( |
+ FROM_HERE, |
+ base::Bind(&StartShellOnShellThread, state_), |
+ base::Bind(&ShellTestHelper::OnShellStarted, base::Unretained(this))); |
+ run_loop_.reset(new base::RunLoop); |
+ run_loop_->Run(); |
+} |
+ |
+void ShellTestHelper::OnShellStarted() { |
+ DCHECK(state_); |
+ shell_client_.reset(new TestShellClient); |
+ shell_.reset(state_->shell_handle.Pass(), shell_client_.get()); |
+ run_loop_->Quit(); |
+} |
+ |
+} // namespace shell |
+} // namespace mojo |