summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chrome_browser_main.cc12
-rw-r--r--chrome/test/base/mash_browser_tests_main.cc64
-rw-r--r--chrome/test/base/mojo_test_connector.cc21
-rw-r--r--chrome/test/base/mojo_test_connector.h3
-rw-r--r--content/common/mojo/mojo_shell_connection_impl.cc5
-rw-r--r--content/common/mojo/mojo_shell_connection_impl.h1
-rw-r--r--content/public/common/mojo_shell_connection.h3
-rw-r--r--content/public/test/test_launcher.cc6
-rw-r--r--content/public/test/test_launcher.h5
-rw-r--r--mojo/shell/standalone/context.cc10
-rw-r--r--mojo/shell/standalone/context.h1
11 files changed, 116 insertions, 15 deletions
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 0311f133..61723fab 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -257,6 +257,11 @@
#include "components/webusb/webusb_detector.h"
#endif
+#if defined(MOJO_SHELL_CLIENT)
+#include "chrome/browser/lifetime/application_lifetime.h"
+#include "content/public/common/mojo_shell_connection.h"
+#endif
+
using content::BrowserThread;
namespace {
@@ -1138,6 +1143,13 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() {
}
void ChromeBrowserMainParts::PreMainMessageLoopRun() {
+#if defined(MOJO_SHELL_CLIENT)
+ if (content::MojoShellConnection::Get() &&
+ content::MojoShellConnection::Get()->UsingExternalShell()) {
+ content::MojoShellConnection::Get()->SetConnectionLostClosure(
+ base::Bind(&chrome::SessionEnding));
+ }
+#endif
TRACE_EVENT0("startup", "ChromeBrowserMainParts::PreMainMessageLoopRun");
TRACK_SCOPED_REGION(
"Startup", "ChromeBrowserMainParts::PreMainMessageLoopRun");
diff --git a/chrome/test/base/mash_browser_tests_main.cc b/chrome/test/base/mash_browser_tests_main.cc
index a6f2f59..0db8651 100644
--- a/chrome/test/base/mash_browser_tests_main.cc
+++ b/chrome/test/base/mash_browser_tests_main.cc
@@ -27,21 +27,53 @@ void ConnectToDefaultApps(mojo::Connector* connector) {
connector->Connect("mojo:mash_session");
}
+class MashTestSuite : public ChromeTestSuite {
+ public:
+ MashTestSuite(int argc, char** argv) : ChromeTestSuite(argc, argv) {}
+
+ void SetMojoTestConnector(scoped_ptr<MojoTestConnector> connector) {
+ mojo_test_connector_ = std::move(connector);
+ }
+ MojoTestConnector* mojo_test_connector() {
+ return mojo_test_connector_.get();
+ }
+
+ private:
+ // ChromeTestSuite:
+ void Shutdown() override {
+ mojo_test_connector_.reset();
+ ChromeTestSuite::Shutdown();
+ }
+
+ scoped_ptr<MojoTestConnector> mojo_test_connector_;
+
+ DISALLOW_COPY_AND_ASSIGN(MashTestSuite);
+};
+
// Used to setup the command line for passing a mojo channel to tests.
class MashTestLauncherDelegate : public ChromeTestLauncherDelegate {
public:
- explicit MashTestLauncherDelegate(ChromeTestSuiteRunner* runner)
- : ChromeTestLauncherDelegate(runner) {}
+ MashTestLauncherDelegate() : ChromeTestLauncherDelegate(nullptr) {}
~MashTestLauncherDelegate() override {}
- MojoTestConnector* GetMojoTestConnector() {
- if (!mojo_test_connector_)
- mojo_test_connector_.reset(new MojoTestConnector);
- return mojo_test_connector_.get();
+ MojoTestConnector* GetMojoTestConnectorForSingleProcess() {
+ // This is only called for single process tests, in which case we need
+ // the TestSuite to own the MojoTestConnector.
+ DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ content::kSingleProcessTestsFlag));
+ DCHECK(test_suite_);
+ test_suite_->SetMojoTestConnector(make_scoped_ptr(new MojoTestConnector));
+ return test_suite_->mojo_test_connector();
}
private:
// ChromeTestLauncherDelegate:
+ int RunTestSuite(int argc, char** argv) override {
+ test_suite_.reset(new MashTestSuite(argc, argv));
+ const int result = test_suite_->Run();
+ test_suite_.reset();
+ return result;
+ }
scoped_ptr<content::TestState> PreRunTest(
base::CommandLine* command_line,
base::TestLauncher::LaunchOptions* test_launch_options) override {
@@ -52,10 +84,18 @@ class MashTestLauncherDelegate : public ChromeTestLauncherDelegate {
shell_client_.get(), mojo_test_connector_->Init()));
ConnectToDefaultApps(shell_connection_->connector());
}
- return GetMojoTestConnector()->PrepareForTest(command_line,
- test_launch_options);
+ return mojo_test_connector_->PrepareForTest(command_line,
+ test_launch_options);
+ }
+ void OnDoneRunningTests() override {
+ // We have to shutdown this state here, while an AtExitManager is still
+ // valid.
+ shell_connection_.reset();
+ shell_client_.reset();
+ mojo_test_connector_.reset();
}
+ scoped_ptr<MashTestSuite> test_suite_;
scoped_ptr<MojoTestConnector> mojo_test_connector_;
scoped_ptr<mojo::ShellClient> shell_client_;
scoped_ptr<mojo::ShellConnection> shell_connection_;
@@ -65,8 +105,9 @@ class MashTestLauncherDelegate : public ChromeTestLauncherDelegate {
void CreateMojoShellConnection(MashTestLauncherDelegate* delegate) {
const bool is_external_shell = true;
- content::MojoShellConnection::Create(delegate->GetMojoTestConnector()->Init(),
- is_external_shell);
+ content::MojoShellConnection::Create(
+ delegate->GetMojoTestConnectorForSingleProcess()->Init(),
+ is_external_shell);
ConnectToDefaultApps(content::MojoShellConnection::Get()->GetConnector());
}
@@ -92,8 +133,7 @@ bool RunMashBrowserTests(int argc, char** argv, int* exit_code) {
}
int default_jobs = std::max(1, base::SysInfo::NumberOfProcessors() / 2);
- ChromeTestSuiteRunner runner;
- MashTestLauncherDelegate delegate(&runner);
+ MashTestLauncherDelegate delegate;
// --single_process and no primoridal pipe token indicate we were run directly
// from the command line. In this case we have to start up MojoShellConnection
// as though we were embedded.
diff --git a/chrome/test/base/mojo_test_connector.cc b/chrome/test/base/mojo_test_connector.cc
index 404dd97..3092c9b 100644
--- a/chrome/test/base/mojo_test_connector.cc
+++ b/chrome/test/base/mojo_test_connector.cc
@@ -19,6 +19,7 @@
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/services/catalog/store.h"
#include "mojo/shell/background/tests/test_catalog_store.h"
+#include "mojo/shell/native_runner_delegate.h"
#include "mojo/shell/public/cpp/connector.h"
#include "mojo/shell/public/cpp/shell_client.h"
#include "mojo/shell/public/cpp/shell_connection.h"
@@ -216,18 +217,38 @@ class MojoTestState : public content::TestState {
} // namespace
+class MojoTestConnector::NativeRunnerDelegateImpl
+ : public mojo::shell::NativeRunnerDelegate {
+ public:
+ NativeRunnerDelegateImpl() {}
+ ~NativeRunnerDelegateImpl() override {}
+
+ private:
+ // mojo::shell::NativeRunnerDelegate:
+ void AdjustCommandLineArgumentsForTarget(
+ const mojo::Identity& target,
+ base::CommandLine* command_line) override {
+ if (target.name() == "exe:chrome")
+ command_line->AppendSwitch(switches::kWaitForMojoShell);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(NativeRunnerDelegateImpl);
+};
+
// static
const char MojoTestConnector::kTestSwitch[] = "is_test";
MojoTestConnector::MojoTestConnector() {}
mojo::shell::mojom::ShellClientRequest MojoTestConnector::Init() {
+ native_runner_delegate_.reset(new NativeRunnerDelegateImpl);
scoped_ptr<mojo::shell::BackgroundShell::InitParams> init_params(
new mojo::shell::BackgroundShell::InitParams);
init_params->catalog_store = BuildTestCatalogStore();
// When running in single_process mode chrome initializes the edk.
init_params->init_edk = !base::CommandLine::ForCurrentProcess()->HasSwitch(
content::kSingleProcessTestsFlag);
+ init_params->native_runner_delegate = native_runner_delegate_.get();
background_shell_.Init(std::move(init_params));
return background_shell_.CreateShellClientRequest(kTestRunnerName);
}
diff --git a/chrome/test/base/mojo_test_connector.h b/chrome/test/base/mojo_test_connector.h
index 909a490..7ad844d 100644
--- a/chrome/test/base/mojo_test_connector.h
+++ b/chrome/test/base/mojo_test_connector.h
@@ -45,6 +45,9 @@ class MojoTestConnector {
base::TestLauncher::LaunchOptions* test_launch_options);
private:
+ class NativeRunnerDelegateImpl;
+
+ scoped_ptr<NativeRunnerDelegateImpl> native_runner_delegate_;
mojo::shell::BackgroundShell background_shell_;
DISALLOW_COPY_AND_ASSIGN(MojoTestConnector);
diff --git a/content/common/mojo/mojo_shell_connection_impl.cc b/content/common/mojo/mojo_shell_connection_impl.cc
index 42cfada6..3f3a693 100644
--- a/content/common/mojo/mojo_shell_connection_impl.cc
+++ b/content/common/mojo/mojo_shell_connection_impl.cc
@@ -135,6 +135,11 @@ bool MojoShellConnectionImpl::UsingExternalShell() const {
return external_;
}
+void MojoShellConnectionImpl::SetConnectionLostClosure(
+ const base::Closure& closure) {
+ shell_connection_->set_connection_lost_closure(closure);
+}
+
void MojoShellConnectionImpl::AddListener(Listener* listener) {
DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) ==
listeners_.end());
diff --git a/content/common/mojo/mojo_shell_connection_impl.h b/content/common/mojo/mojo_shell_connection_impl.h
index 49bfefc..3f1a188 100644
--- a/content/common/mojo/mojo_shell_connection_impl.h
+++ b/content/common/mojo/mojo_shell_connection_impl.h
@@ -57,6 +57,7 @@ class MojoShellConnectionImpl : public MojoShellConnection,
// MojoShellConnection:
mojo::Connector* GetConnector() override;
bool UsingExternalShell() const override;
+ void SetConnectionLostClosure(const base::Closure& closure) override;
void AddListener(Listener* listener) override;
void RemoveListener(Listener* listener) override;
diff --git a/content/public/common/mojo_shell_connection.h b/content/public/common/mojo_shell_connection.h
index 7077dce..6ae92bbe 100644
--- a/content/public/common/mojo_shell_connection.h
+++ b/content/public/common/mojo_shell_connection.h
@@ -59,6 +59,9 @@ class CONTENT_EXPORT MojoShellConnection {
// a shell embedded in the browser process (false).
virtual bool UsingExternalShell() const = 0;
+ // Sets a closure that is called when the connection is lost.
+ virtual void SetConnectionLostClosure(const base::Closure& closure) = 0;
+
// [De]Register an impl of Listener that will be consulted when the wrapped
// ShellConnection exposes services to inbound connections.
// Registered listeners are owned by this MojoShellConnection.
diff --git a/content/public/test/test_launcher.cc b/content/public/test/test_launcher.cc
index 183d82a..4b578d8 100644
--- a/content/public/test/test_launcher.cc
+++ b/content/public/test/test_launcher.cc
@@ -472,6 +472,8 @@ scoped_ptr<TestState> TestLauncherDelegate::PreRunTest(
return nullptr;
}
+void TestLauncherDelegate::OnDoneRunningTests() {}
+
TestLauncherDelegate::~TestLauncherDelegate() {
}
@@ -541,7 +543,9 @@ int LaunchTests(TestLauncherDelegate* launcher_delegate,
WrapperTestLauncherDelegate delegate(launcher_delegate);
base::TestLauncher launcher(&delegate, default_jobs);
- return (launcher.Run() ? 0 : 1);
+ const int result = launcher.Run() ? 0 : 1;
+ launcher_delegate->OnDoneRunningTests();
+ return result;
}
TestLauncherDelegate* GetCurrentTestLauncherDelegate() {
diff --git a/content/public/test/test_launcher.h b/content/public/test/test_launcher.h
index 117c658..67b711b 100644
--- a/content/public/test/test_launcher.h
+++ b/content/public/test/test_launcher.h
@@ -64,6 +64,11 @@ class TestLauncherDelegate {
// when --test-launcher-jobs isn't specified on the command-line.
virtual void AdjustDefaultParallelJobs(int* default_jobs) {}
+ // Called prior to returning from LaunchTests(). Gives the delegate a chance
+ // to do cleanup before state created by TestLauncher has been destroyed (such
+ // as the AtExitManager).
+ virtual void OnDoneRunningTests();
+
protected:
virtual ~TestLauncherDelegate();
};
diff --git a/mojo/shell/standalone/context.cc b/mojo/shell/standalone/context.cc
index e64ed82..c036694 100644
--- a/mojo/shell/standalone/context.cc
+++ b/mojo/shell/standalone/context.cc
@@ -140,7 +140,8 @@ void Context::Init(scoped_ptr<InitParams> init_params) {
blocking_pool_ =
new base::SequencedWorkerPool(kMaxBlockingPoolThreads, "blocking_pool");
- if (!init_params || init_params->init_edk) {
+ init_edk_ = !init_params || init_params->init_edk;
+ if (init_edk_) {
edk::InitIPCSupport(this, io_thread_->task_runner().get());
#if defined(OS_MACOSX)
edk::SetMachPortProvider(MachBroker::GetInstance()->port_provider());
@@ -210,8 +211,13 @@ void Context::Shutdown() {
// loop shutdown.
shell_.reset();
- TRACE_EVENT0("mojo_shell", "Context::Shutdown");
DCHECK_EQ(base::MessageLoop::current()->task_runner(), shell_runner_);
+
+ // If we didn't initialize the edk we should not shut it down.
+ if (!init_edk_)
+ return;
+
+ TRACE_EVENT0("mojo_shell", "Context::Shutdown");
// Post a task in case OnShutdownComplete is called synchronously.
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(edk::ShutdownIPCSupport));
diff --git a/mojo/shell/standalone/context.h b/mojo/shell/standalone/context.h
index 3c25027..fee1e5a 100644
--- a/mojo/shell/standalone/context.h
+++ b/mojo/shell/standalone/context.h
@@ -75,6 +75,7 @@ class Context : public edk::ProcessDelegate {
scoped_ptr<catalog::Factory> catalog_;
scoped_ptr<Shell> shell_;
base::Time main_entry_time_;
+ bool init_edk_ = false;
DISALLOW_COPY_AND_ASSIGN(Context);
};