Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(492)

Side by Side Diff: chrome/browser/page_cycler/page_cycler.cc

Issue 23498004: Remove page cyclers from chrome binary. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/page_cycler/page_cycler.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_commands.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/test/base/chrome_process_util.h"
21 #include "chrome/test/perf/perf_test.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/common/url_constants.h"
27
28 using content::NavigationController;
29 using content::OpenURLParams;
30 using content::Referrer;
31 using content::WebContents;
32
33 PageCycler::PageCycler(Browser* browser,
34 const base::FilePath& urls_file)
35 : content::WebContentsObserver(
36 browser->tab_strip_model()->GetActiveWebContents()),
37 browser_(browser),
38 urls_file_(urls_file),
39 url_index_(0),
40 aborted_(false) {
41 BrowserList::AddObserver(this);
42 AddRef(); // Balanced in Finish()/Abort() (only one should be called).
43 }
44
45 PageCycler::~PageCycler() {
46 }
47
48 bool PageCycler::IsLoadCallbackValid(const GURL& validated_url,
49 bool is_main_frame) {
50 // If |url_index_| is equal to zero, that means that this was called before
51 // LoadNextURL() - this can happen at startup, loading the new tab page; or
52 // if the user specified a bad url as the final url in the list. In these
53 // cases, do not report success or failure, and load the next page.
54 if (!url_index_) {
55 LoadNextURL();
56 return false;
57 }
58 return (is_main_frame &&
59 validated_url.spec() != content::kUnreachableWebDataURL);
60 }
61
62 void PageCycler::DidFinishLoad(int64 frame_id,
63 const GURL& validated_url,
64 bool is_main_frame,
65 content::RenderViewHost* render_view_host) {
66 if (IsLoadCallbackValid(validated_url, is_main_frame))
67 LoadSucceeded();
68 }
69
70 void PageCycler::DidFailProvisionalLoad(
71 int64 frame_id,
72 bool is_main_frame,
73 const GURL& validated_url,
74 int error_code,
75 const string16& error_description,
76 content::RenderViewHost* render_view_host) {
77 if (IsLoadCallbackValid(validated_url, is_main_frame))
78 LoadFailed(validated_url, error_description);
79 }
80
81 void PageCycler::Run() {
82 if (browser_)
83 content::BrowserThread::PostBlockingPoolTask(
84 FROM_HERE,
85 base::Bind(&PageCycler::ReadURLsOnBackgroundThread, this));
86 }
87
88 void PageCycler::ReadURLsOnBackgroundThread() {
89 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
90
91 std::string file_contents;
92 std::vector<std::string> url_strings;
93
94 CHECK(base::PathExists(urls_file_)) << urls_file_.value();
95 file_util::ReadFileToString(urls_file_, &file_contents);
96 base::SplitStringAlongWhitespace(file_contents, &url_strings);
97
98 if (!url_strings.size()) {
99 #if defined(OS_POSIX)
100 error_.append(ASCIIToUTF16("Page Cycler: No URLs in given file: " +
101 urls_file_.value()));
102 #elif defined(OS_WIN)
103 error_.append(ASCIIToUTF16("Page Cycler: No URLs in given file: "))
104 .append(urls_file_.value());
105 #endif // OS_WIN
106 }
107
108 for (std::vector<std::string>::const_iterator iter = url_strings.begin();
109 iter != url_strings.end(); ++iter) {
110 GURL gurl(*iter);
111 if (!gurl.is_valid())
112 error_.append(ASCIIToUTF16("Omitting invalid URL: " + *iter + ".\n"));
113 // Since we don't count kUnreachableWebData as a valid load, we don't want
114 // the user to specify this as one of the pages to visit.
115 else if (*iter == content::kUnreachableWebDataURL) {
116 error_.append(ASCIIToUTF16(
117 "Chrome error pages are not allowed as urls. Omitting url: " +
118 *iter + ".\n"));
119 } else {
120 urls_.push_back(gurl);
121 }
122 }
123
124 content::BrowserThread::PostTask(content::BrowserThread::UI,
125 FROM_HERE,
126 base::Bind(&PageCycler::BeginCycle, this));
127 }
128
129 void PageCycler::BeginCycle() {
130 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
131
132 CHECK(browser_);
133 // Upon launch, Chrome will automatically load the newtab page. This can
134 // result in the browser being in a state of loading when PageCycler is ready
135 // to start. Instead of interrupting the load, we wait for it to finish, and
136 // will call LoadNextURL() from DidFinishLoad() or DidFailProvisionalLoad().
137 if (browser_->tab_strip_model()->GetActiveWebContents()->IsLoading())
138 return;
139 LoadNextURL();
140 }
141
142 void PageCycler::LoadNextURL() {
143 CHECK(browser_);
144 if (url_index_ >= urls_.size()) {
145 content::BrowserThread::PostBlockingPoolTask(
146 FROM_HERE,
147 base::Bind(&PageCycler::PrepareResultsOnBackgroundThread, this));
148 return;
149 }
150 if (url_index_) {
151 timings_string_.append(", ");
152 urls_string_.append(", ");
153 }
154 urls_string_.append(urls_[url_index_].spec());
155 initial_time_ = base::TimeTicks::HighResNow();
156 OpenURLParams params(urls_[url_index_],
157 Referrer(),
158 CURRENT_TAB,
159 content::PAGE_TRANSITION_TYPED,
160 false);
161 ++url_index_;
162 browser_->OpenURL(params);
163 }
164
165 void PageCycler::LoadSucceeded() {
166 base::TimeDelta time_elapsed =
167 (base::TimeTicks::HighResNow() - initial_time_) / 1000.0;
168 timings_string_.append(base::Int64ToString(time_elapsed.ToInternalValue()));
169 LoadNextURL();
170 }
171
172 void PageCycler::LoadFailed(const GURL& url,
173 const string16& error_description) {
174 error_.append(ASCIIToUTF16("Failed to load the page at: " +
175 url.spec() + ": ")).append(error_description).
176 append(ASCIIToUTF16("\n"));
177 base::TimeDelta time_elapsed =
178 (base::TimeTicks::HighResNow() - initial_time_) / 1000.0;
179 timings_string_.append(base::Int64ToString(time_elapsed.ToInternalValue()) +
180 (" (failed)"));
181 LoadNextURL();
182 }
183
184 void PageCycler::PrepareResultsOnBackgroundThread() {
185 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
186 std::string output;
187 if (!stats_file_.empty()) {
188 #if defined(OS_POSIX)
189 base::ProcessId pid = base::GetParentProcessId(base::GetCurrentProcId());
190 #elif defined(OS_WIN)
191 base::ProcessId pid = base::GetCurrentProcId();
192 #endif // OS_WIN
193 ChromeProcessList chrome_processes(GetRunningChromeProcesses(pid));
194 output += perf_test::MemoryUsageInfoToString(
195 std::string(), chrome_processes, pid);
196 output +=
197 perf_test::IOPerfInfoToString(std::string(), chrome_processes, pid);
198 output += perf_test::SystemCommitChargeToString(
199 std::string(), base::GetSystemCommitCharge(), false);
200 output.append("Pages: [" + urls_string_ + "]\n");
201 output.append("*RESULT times: t_ref= [" + timings_string_ + "] ms\n");
202 }
203 WriteResultsOnBackgroundThread(output);
204 }
205
206 void PageCycler::WriteResultsOnBackgroundThread(const std::string& output) {
207 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
208
209 if (!output.empty()) {
210 CHECK(!stats_file_.empty());
211 if (base::PathExists(stats_file_)) {
212 VLOG(1) << "PageCycler: Previous stats file found; appending.";
213 file_util::AppendToFile(stats_file_, output.c_str(), output.size());
214 } else {
215 file_util::WriteFile(stats_file_, output.c_str(), output.size());
216 }
217 }
218 if (!errors_file_.empty()) {
219 if (!error_.empty()) {
220 file_util::WriteFile(errors_file_, UTF16ToUTF8(error_).c_str(),
221 error_.size());
222 } else if (base::PathExists(errors_file_)) {
223 // If there is an old error file, delete it to avoid confusion.
224 base::DeleteFile(errors_file_, false);
225 }
226 }
227 if (aborted_) {
228 content::BrowserThread::PostTask(content::BrowserThread::UI,
229 FROM_HERE,
230 base::Bind(&PageCycler::Abort, this));
231 } else {
232 content::BrowserThread::PostTask(content::BrowserThread::UI,
233 FROM_HERE,
234 base::Bind(&PageCycler::Finish, this));
235 }
236 }
237
238 void PageCycler::Finish() {
239 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
240 BrowserList::RemoveObserver(this);
241 browser_->OnWindowClosing();
242 chrome::ExecuteCommand(browser_, IDC_EXIT);
243 Release(); // Balanced in PageCycler constructor;
244 // (only one of Finish/Abort should be called).
245 }
246
247 void PageCycler::Abort() {
248 browser_ = NULL;
249 BrowserList::RemoveObserver(this);
250 Release(); // Balanced in PageCycler constructor;
251 // (only one of Finish/Abort should be called).
252 }
253
254 void PageCycler::OnBrowserAdded(Browser* browser) {}
255
256 void PageCycler::OnBrowserRemoved(Browser* browser) {
257 if (browser == browser_) {
258 aborted_ = true;
259 error_.append(ASCIIToUTF16(
260 "Browser was closed before the run was completed."));
261 DLOG(WARNING) <<
262 "Page Cycler: browser was closed before the run was completed.";
263 content::BrowserThread::PostBlockingPoolTask(
264 FROM_HERE,
265 base::Bind(&PageCycler::PrepareResultsOnBackgroundThread, this));
266 }
267 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698