15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/page_cycler/page_cycler.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/chrome_process_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/perf/perf_test.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::Referrer; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PageCycler::PageCycler(Browser* browser, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& urls_file) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : content::WebContentsObserver( 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents()), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_file_(urls_file), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_index_(0), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aborted_(false) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserList::AddObserver(this); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); // Balanced in Finish()/Abort() (only one should be called). 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PageCycler::~PageCycler() { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PageCycler::IsLoadCallbackValid(const GURL& validated_url, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |url_index_| is equal to zero, that means that this was called before 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LoadNextURL() - this can happen at startup, loading the new tab page; or 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the user specified a bad url as the final url in the list. In these 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cases, do not report success or failure, and load the next page. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_index_) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextURL(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (is_main_frame && 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) validated_url.spec() != content::kUnreachableWebDataURL); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::DidFinishLoad(int64 frame_id, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& validated_url, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderViewHost* render_view_host) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsLoadCallbackValid(validated_url, is_main_frame)) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadSucceeded(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::DidFailProvisionalLoad( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 frame_id, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& validated_url, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& error_description, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderViewHost* render_view_host) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsLoadCallbackValid(validated_url, is_main_frame)) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadFailed(validated_url, error_description); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::Run() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::ReadURLsOnBackgroundThread, this)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::ReadURLsOnBackgroundThread() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_contents; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> url_strings; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CHECK(base::PathExists(urls_file_)) << urls_file_.value(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReadFileToString(urls_file_, &file_contents); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SplitStringAlongWhitespace(file_contents, &url_strings); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url_strings.size()) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16("Page Cycler: No URLs in given file: " + 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_file_.value())); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16("Page Cycler: No URLs in given file: ")) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .append(urls_file_.value()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<std::string>::const_iterator iter = url_strings.begin(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != url_strings.end(); ++iter) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL gurl(*iter); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!gurl.is_valid()) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16("Omitting invalid URL: " + *iter + ".\n")); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we don't count kUnreachableWebData as a valid load, we don't want 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the user to specify this as one of the pages to visit. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (*iter == content::kUnreachableWebDataURL) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Chrome error pages are not allowed as urls. Omitting url: " + 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *iter + ".\n")); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_.push_back(gurl); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::UI, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::BeginCycle, this)); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::BeginCycle() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(browser_); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upon launch, Chrome will automatically load the newtab page. This can 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result in the browser being in a state of loading when PageCycler is ready 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to start. Instead of interrupting the load, we wait for it to finish, and 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will call LoadNextURL() from DidFinishLoad() or DidFailProvisionalLoad(). 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser_->tab_strip_model()->GetActiveWebContents()->IsLoading()) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextURL(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::LoadNextURL() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(browser_); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_index_ >= urls_.size()) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::PrepareResultsOnBackgroundThread, this)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_index_) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timings_string_.append(", "); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_string_.append(", "); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_string_.append(urls_[url_index_].spec()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_time_ = base::TimeTicks::HighResNow(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenURLParams params(urls_[url_index_], 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Referrer(), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURRENT_TAB, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_TYPED, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++url_index_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->OpenURL(params); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::LoadSucceeded() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_elapsed = 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (base::TimeTicks::HighResNow() - initial_time_) / 1000.0; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timings_string_.append(base::Int64ToString(time_elapsed.ToInternalValue())); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextURL(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::LoadFailed(const GURL& url, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& error_description) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16("Failed to load the page at: " + 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.spec() + ": ")).append(error_description). 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append(ASCIIToUTF16("\n")); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_elapsed = 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (base::TimeTicks::HighResNow() - initial_time_) / 1000.0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timings_string_.append(base::Int64ToString(time_elapsed.ToInternalValue()) + 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (" (failed)")); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextURL(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::PrepareResultsOnBackgroundThread() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string output; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!stats_file_.empty()) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessId pid = base::GetParentProcessId(base::GetCurrentProcId()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessId pid = base::GetCurrentProcId(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChromeProcessList chrome_processes(GetRunningChromeProcesses(pid)); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output += perf_test::MemoryUsageInfoToString( 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), chrome_processes, pid); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output += 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) perf_test::IOPerfInfoToString(std::string(), chrome_processes, pid); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output += perf_test::SystemCommitChargeToString( 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), base::GetSystemCommitCharge(), false); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("Pages: [" + urls_string_ + "]\n"); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.append("*RESULT times: t_ref= [" + timings_string_ + "] ms\n"); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteResultsOnBackgroundThread(output); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::WriteResultsOnBackgroundThread(const std::string& output) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!output.empty()) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!stats_file_.empty()); 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::PathExists(stats_file_)) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "PageCycler: Previous stats file found; appending."; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::AppendToFile(stats_file_, output.c_str(), output.size()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::WriteFile(stats_file_, output.c_str(), output.size()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!errors_file_.empty()) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!error_.empty()) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::WriteFile(errors_file_, UTF16ToUTF8(error_).c_str(), 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.size()); 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (base::PathExists(errors_file_)) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is an old error file, delete it to avoid confusion. 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(errors_file_, false); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (aborted_) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::UI, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::Abort, this)); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::UI, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::Finish, this)); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::Finish() { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserList::RemoveObserver(this); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->OnWindowClosing(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ExecuteCommand(browser_, IDC_EXIT); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in PageCycler constructor; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (only one of Finish/Abort should be called). 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::Abort() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_ = NULL; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserList::RemoveObserver(this); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); // Balanced in PageCycler constructor; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (only one of Finish/Abort should be called). 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::OnBrowserAdded(Browser* browser) {} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageCycler::OnBrowserRemoved(Browser* browser) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser == browser_) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aborted_ = true; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_.append(ASCIIToUTF16( 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Browser was closed before the run was completed.")); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Page Cycler: browser was closed before the run was completed."; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostBlockingPoolTask( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PageCycler::PrepareResultsOnBackgroundThread, this)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 268