diff options
-rw-r--r-- | chrome/browser/chrome_browser_main.cc | 12 | ||||
-rw-r--r-- | chrome/test/base/mash_browser_tests_main.cc | 64 | ||||
-rw-r--r-- | chrome/test/base/mojo_test_connector.cc | 21 | ||||
-rw-r--r-- | chrome/test/base/mojo_test_connector.h | 3 | ||||
-rw-r--r-- | content/common/mojo/mojo_shell_connection_impl.cc | 5 | ||||
-rw-r--r-- | content/common/mojo/mojo_shell_connection_impl.h | 1 | ||||
-rw-r--r-- | content/public/common/mojo_shell_connection.h | 3 | ||||
-rw-r--r-- | content/public/test/test_launcher.cc | 6 | ||||
-rw-r--r-- | content/public/test/test_launcher.h | 5 | ||||
-rw-r--r-- | mojo/shell/standalone/context.cc | 10 | ||||
-rw-r--r-- | mojo/shell/standalone/context.h | 1 |
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); }; |