// Copyright 2015 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 "components/web_view/test_runner/test_runner_application_delegate.h" #include #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/location.h" #include "base/path_service.h" #include "base/thread_task_runner_handle.h" #include "base/threading/thread_restrictions.h" #include "components/mus/public/cpp/scoped_view_ptr.h" #include "components/mus/public/cpp/view.h" #include "components/mus/public/cpp/view_tree_connection.h" #include "components/mus/public/cpp/view_tree_host_factory.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/converters/geometry/geometry_type_converters.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" #if defined(OS_WIN) #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #endif namespace web_view { TestRunnerApplicationDelegate::TestRunnerApplicationDelegate() : app_(nullptr), root_(nullptr), content_(nullptr) {} TestRunnerApplicationDelegate::~TestRunnerApplicationDelegate() { if (root_) mus::ScopedViewPtr::DeleteViewOrViewManager(root_); } void TestRunnerApplicationDelegate::LaunchURL(const GURL& test_url) { if (!web_view_) { web_view_.reset(new WebView(this)); web_view_->Init(app_, content_); } mojo::URLRequestPtr request(mojo::URLRequest::New()); request->url = test_url.spec(); web_view_->web_view()->LoadRequest(request.Pass()); } void TestRunnerApplicationDelegate::Terminate() { if (root_) mus::ScopedViewPtr::DeleteViewOrViewManager(root_); } //////////////////////////////////////////////////////////////////////////////// // mojo::ApplicationDelegate implementation: void TestRunnerApplicationDelegate::Initialize(mojo::ApplicationImpl* app) { app_ = app; mus::CreateSingleViewTreeHost(app_, this, &host_); } bool TestRunnerApplicationDelegate::ConfigureIncomingConnection( mojo::ApplicationConnection* connection) { connection->AddService(this); return true; } //////////////////////////////////////////////////////////////////////////////// // mus::ViewTreeDelegate implementation: void TestRunnerApplicationDelegate::OnEmbed(mus::View* root) { root_ = root; // If this is a sys-check, then terminate in the next cycle. const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps"; if (base::CommandLine::ForCurrentProcess()->HasSwitch( kCheckLayoutTestSysDeps)) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&TestRunnerApplicationDelegate::Terminate, base::Unretained(this))); return; } const gfx::Size kViewportSize(800, 600); host_->SetSize(mojo::Size::From(kViewportSize)); content_ = root_->connection()->CreateView(); root_->AddChild(content_); content_->SetBounds(*mojo::Rect::From(gfx::Rect(kViewportSize))); content_->SetVisible(true); std::cout << "#READY\n"; std::cout.flush(); auto cmdline_args = base::CommandLine::ForCurrentProcess()->GetArgs(); test_extractor_.reset(new test_runner::TestInfoExtractor(cmdline_args)); scoped_ptr test_info = test_extractor_->GetNextTest(); if (test_info) LaunchURL(test_info->url); } void TestRunnerApplicationDelegate::OnConnectionLost( mus::ViewTreeConnection* connection) { root_ = nullptr; app_->Quit(); } //////////////////////////////////////////////////////////////////////////////// // mojom::WebViewClient implementation: void TestRunnerApplicationDelegate::TopLevelNavigate( mojo::URLRequestPtr request) { web_view_->web_view()->LoadRequest(request.Pass()); } void TestRunnerApplicationDelegate::LoadingStateChanged(bool is_loading) {} void TestRunnerApplicationDelegate::ProgressChanged(double progress) {} void TestRunnerApplicationDelegate::BackForwardChanged( mojom::ButtonState back_button, mojom::ButtonState forward_button) {} void TestRunnerApplicationDelegate::TitleChanged(const mojo::String& title) {} //////////////////////////////////////////////////////////////////////////////// // LayoutTestRunner implementation: void TestRunnerApplicationDelegate::TestFinished() { std::cout << "#EOF\n"; std::cout.flush(); std::cerr << "#EOF\n"; std::cerr.flush(); scoped_ptr test_info = test_extractor_->GetNextTest(); if (test_info) LaunchURL(test_info->url); else Terminate(); } //////////////////////////////////////////////////////////////////////////////// // mojo::InterfaceFactory implementation: void TestRunnerApplicationDelegate::Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest request) { layout_test_runner_.AddBinding(this, request.Pass()); } } // namespace web_view