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

Side by Side Diff: chrome/browser/feedback/feedback_util.cc

Issue 12529024: Fix feedback log collection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/feedback/feedback_util.h" 5 #include "chrome/browser/feedback/feedback_util.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/file_version_info.h" 13 #include "base/file_version_info.h"
15 #include "base/memory/singleton.h" 14 #include "base/memory/singleton.h"
16 #include "base/message_loop.h" 15 #include "base/message_loop.h"
17 #include "base/string_util.h" 16 #include "base/string_util.h"
18 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
18 #include "base/strings/string_compress.h"
19 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
20 #include "base/win/windows_version.h" 20 #include "base/win/windows_version.h"
21 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/safe_browsing/safe_browsing_util.h" 23 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
24 #include "chrome/browser/ui/browser_list.h" 24 #include "chrome/browser/ui/browser_list.h"
25 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/chrome_version_info.h" 26 #include "chrome/common/chrome_version_info.h"
27 #include "chrome/common/metrics/metrics_log_manager.h"
27 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/navigation_controller.h" 29 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
30 #include "content/public/common/content_client.h" 31 #include "content/public/common/content_client.h"
31 #include "googleurl/src/gurl.h" 32 #include "googleurl/src/gurl.h"
32 #include "grit/generated_resources.h" 33 #include "grit/generated_resources.h"
33 #include "grit/locale_settings.h" 34 #include "grit/locale_settings.h"
34 #include "grit/theme_resources.h" 35 #include "grit/theme_resources.h"
35 #include "net/base/load_flags.h" 36 #include "net/base/load_flags.h"
36 #include "net/url_request/url_fetcher.h" 37 #include "net/url_request/url_fetcher.h"
37 #include "net/url_request/url_fetcher_delegate.h" 38 #include "net/url_request/url_fetcher_delegate.h"
38 #include "net/url_request/url_request_status.h" 39 #include "net/url_request/url_request_status.h"
39 #include "third_party/icu/public/common/unicode/locid.h" 40 #include "third_party/icu/public/common/unicode/locid.h"
40 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
41 42
42 #if defined(USE_ASH)
43 #include "ash/shell.h"
44 #include "ash/shell_delegate.h"
45 #endif
46
47 using content::WebContents; 43 using content::WebContents;
48 44
49 const char kSyncDataKey[] = "about_sync_data";
50
51 #if defined(OS_CHROMEOS)
52 const char kHUDLogDataKey[] = "hud_log";
53 #endif
54
55 namespace {
56
57 const int kFeedbackVersion = 1; 45 const int kFeedbackVersion = 1;
58 46
59 const char kReportPhishingUrl[] = 47 const char kReportPhishingUrl[] =
60 "http://www.google.com/safebrowsing/report_phish/"; 48 "http://www.google.com/safebrowsing/report_phish/";
61 49
62 // URL to post bug reports to. 50 // URL to post bug reports to.
63 const char kFeedbackPostUrl[] = 51 const char kFeedbackPostUrl[] =
64 "https://www.google.com/tools/feedback/chrome/__submit"; 52 "https://www.google.com/tools/feedback/chrome/__submit";
65 53
66 const char kProtBufMimeType[] = "application/x-protobuf"; 54 const char kProtBufMimeType[] = "application/x-protobuf";
67 const char kPngMimeType[] = "image/png"; 55 const char kPngMimeType[] = "image/png";
68 56
69 // Tags we use in product specific data 57 // Tags we use in product specific data
70 const char kChromeVersionTag[] = "CHROME VERSION"; 58 const char kChromeVersionTag[] = "CHROME VERSION";
71 const char kOsVersionTag[] = "OS VERSION"; 59 const char kOsVersionTag[] = "OS VERSION";
72 #if defined(OS_CHROMEOS)
73 const char kTimestampTag[] = "TIMESTAMP";
74 #endif
75 60
76 const int kHttpPostSuccessNoContent = 204; 61 const int kHttpPostSuccessNoContent = 204;
77 const int kHttpPostFailNoConnection = -1; 62 const int kHttpPostFailNoConnection = -1;
78 const int kHttpPostFailClientError = 400; 63 const int kHttpPostFailClientError = 400;
79 const int kHttpPostFailServerError = 500; 64 const int kHttpPostFailServerError = 500;
80 65
81 #if defined(OS_CHROMEOS)
82 const char kBZip2MimeType[] = "application/x-bzip2";
83 const char kLogsAttachmentName[] = "system_logs.bz2";
84 const char kArbitraryMimeType[] = "application/octet-stream";
85 #endif
86
87 const int64 kInitialRetryDelay = 900000; // 15 minutes 66 const int64 kInitialRetryDelay = 900000; // 15 minutes
88 const int64 kRetryDelayIncreaseFactor = 2; 67 const int64 kRetryDelayIncreaseFactor = 2;
89 const int64 kRetryDelayLimit = 14400000; // 4 hours 68 const int64 kRetryDelayLimit = 14400000; // 4 hours
90 69
91 void ReadFileToStringNoResult(const base::FilePath& path, 70 #if defined(OS_CHROMEOS)
92 std::string* contents) { 71 const size_t kFeedbackMaxLength = 4 * 1024;
93 if (!file_util::ReadFileToString(path, contents)) 72 const size_t kFeedbackMaxLineCount = 40;
94 if (contents) 73
95 contents->clear(); 74 const char kBZip2MimeType[] = "application/x-bzip2";
75 const char kLogsAttachmentName[] = "system_logs.bz2";
76 const char kArbitraryMimeType[] = "application/octet-stream";
77
78 const char kMultilineIndicatorString[] = "<multiline>\n";
79 const char kMultilineStartString[] = "---------- START ----------\n";
80 const char kMultilineEndString[] = "---------- END ----------\n\n";
81
82 const char kTimestampTag[] = "TIMESTAMP";
83 #endif
84
85 namespace {
86
87 #if defined(OS_CHROMEOS)
88 std::string ZipLogs(chromeos::SystemLogsResponse* sys_info) {
89 std::string syslogs_string;
90 for (chromeos::SystemLogsResponse::const_iterator it = sys_info->begin();
91 it != sys_info->end(); ++it) {
92 std::string key = it->first;
93 std::string value = it->second;
94
95 TrimString(key, "\n ", &key);
96 TrimString(value, "\n ", &value);
97
98 if (value.find("\n") != std::string::npos) {
99 syslogs_string.append(
100 key + "=" + kMultilineIndicatorString +
101 kMultilineStartString +
102 value + "\n" +
103 kMultilineEndString);
104 } else {
105 syslogs_string.append(key + "=" + value + "\n");
106 }
107 }
108 std::string compressed_logs;
109 if (base::Bzip2Compress(syslogs_string, &compressed_logs))
110 return compressed_logs;
111 else
112 return std::string();
96 } 113 }
114 #endif
97 115
98 } // namespace 116 } // namespace
99 117
100 118
101 // Simple net::URLFetcherDelegate to clean up URLFetcher on completion. 119 // Simple net::URLFetcherDelegate to clean up URLFetcher on completion.
102 class FeedbackUtil::PostCleanup : public net::URLFetcherDelegate { 120 class FeedbackUtil::PostCleanup : public net::URLFetcherDelegate {
103 public: 121 public:
104 PostCleanup(Profile* profile, 122 PostCleanup(Profile* profile,
105 std::string* post_body, 123 std::string* post_body,
106 int64 previous_delay) : profile_(profile), 124 int64 previous_delay) : profile_(profile),
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 // Create log_value object and add it to the web_data object 247 // Create log_value object and add it to the web_data object
230 userfeedback::ProductSpecificData log_value; 248 userfeedback::ProductSpecificData log_value;
231 log_value.set_key(key); 249 log_value.set_key(key);
232 log_value.set_value(value); 250 log_value.set_value(value);
233 userfeedback::WebData* web_data = feedback_data->mutable_web_data(); 251 userfeedback::WebData* web_data = feedback_data->mutable_web_data();
234 *(web_data->add_product_specific_data()) = log_value; 252 *(web_data->add_product_specific_data()) = log_value;
235 } 253 }
236 254
237 #if defined(OS_CHROMEOS) 255 #if defined(OS_CHROMEOS)
238 bool FeedbackUtil::ValidFeedbackSize(const std::string& content) { 256 bool FeedbackUtil::ValidFeedbackSize(const std::string& content) {
239 if (content.length() > chromeos::system::kFeedbackMaxLength) 257 if (content.length() > kFeedbackMaxLength)
240 return false; 258 return false;
241 const size_t line_count = std::count(content.begin(), content.end(), '\n'); 259 const size_t line_count = std::count(content.begin(), content.end(), '\n');
242 if (line_count > chromeos::system::kFeedbackMaxLineCount) 260 if (line_count > kFeedbackMaxLineCount)
243 return false; 261 return false;
244 return true; 262 return true;
245 } 263 }
246 #endif 264 #endif
247 265
248 // static 266 // static
249 void FeedbackUtil::SendReport(const FeedbackData& data) { 267 void FeedbackUtil::SendReport(scoped_refptr<FeedbackData> data) {
250 #if defined(OS_CHROMEOS) 268 if (!data) {
251 if (data.attached_filename().size() && 269 LOG(ERROR) << "FeedbackUtil::SendReport called with NULL data!";
252 base::FilePath::IsSeparator(data.attached_filename()[0]) && 270 NOTREACHED();
253 !data.attached_filedata()) {
254 // Read the attached file and then send this report.
255 std::string* file_data = new std::string;
256
257 base::FilePath root =
258 ash::Shell::GetInstance()->delegate()->
259 GetCurrentBrowserContext()->GetPath();
260 base::FilePath filepath = root.Append(data.attached_filename().substr(1));
261 std::string stripped_filename = filepath.BaseName().value();
262
263 // Read the file into file_data, then call send report again with the
264 // stripped filename and file data (which will skip this code path).
265 content::BrowserThread::PostTaskAndReply(
266 content::BrowserThread::FILE, FROM_HERE,
267 base::Bind(&ReadFileToStringNoResult,
268 filepath,
269 file_data),
270 base::Bind(&FeedbackUtil::SendReport,
271 FeedbackData(data.profile(),
272 data.category_tag(),
273 data.page_url(),
274 data.description(),
275 data.user_email(),
276 data.image(),
277 data.sys_info(),
278 data.zip_content(),
279 data.timestamp(),
280 stripped_filename,
281 file_data)));
282 return; 271 return;
283 } 272 }
284 #endif
285 273
286 // Create google feedback protocol buffer objects 274 // Create google feedback protocol buffer objects
287 userfeedback::ExtensionSubmit feedback_data; 275 userfeedback::ExtensionSubmit feedback_data;
288 // type id set to 0, unused field but needs to be initialized to 0 276 // type id set to 0, unused field but needs to be initialized to 0
289 feedback_data.set_type_id(0); 277 feedback_data.set_type_id(0);
290 278
291 userfeedback::CommonData* common_data = feedback_data.mutable_common_data(); 279 userfeedback::CommonData* common_data = feedback_data.mutable_common_data();
292 userfeedback::WebData* web_data = feedback_data.mutable_web_data(); 280 userfeedback::WebData* web_data = feedback_data.mutable_web_data();
293 281
294 // Set our user agent. 282 // Set our user agent.
295 userfeedback::Navigator* navigator = web_data->mutable_navigator(); 283 userfeedback::Navigator* navigator = web_data->mutable_navigator();
296 navigator->set_user_agent(content::GetUserAgent(GURL())); 284 navigator->set_user_agent(content::GetUserAgent(GURL()));
297 285
298 // Set GAIA id to 0. We're not using gaia id's for recording 286 // Set GAIA id to 0. We're not using gaia id's for recording
299 // use feedback - we're using the e-mail field, allows users to 287 // use feedback - we're using the e-mail field, allows users to
300 // submit feedback from incognito mode and specify any mail id 288 // submit feedback from incognito mode and specify any mail id
301 // they wish 289 // they wish
302 common_data->set_gaia_id(0); 290 common_data->set_gaia_id(0);
303 291
304 // Add the user e-mail to the feedback object 292 // Add the user e-mail to the feedback object
305 common_data->set_user_email(data.user_email()); 293 common_data->set_user_email(data->user_email());
306 294
307 // Add the description to the feedback object 295 // Add the description to the feedback object
308 common_data->set_description(data.description()); 296 common_data->set_description(data->description());
309 297
310 // Add the language 298 // Add the language
311 std::string chrome_locale = g_browser_process->GetApplicationLocale(); 299 std::string chrome_locale = g_browser_process->GetApplicationLocale();
312 common_data->set_source_description_language(chrome_locale); 300 common_data->set_source_description_language(chrome_locale);
313 301
314 // Set the url 302 // Set the url
315 web_data->set_url(data.page_url()); 303 web_data->set_url(data->page_url());
316 304
317 // Add the Chrome version 305 // Add the Chrome version
318 chrome::VersionInfo version_info; 306 chrome::VersionInfo version_info;
319 if (version_info.is_valid()) { 307 if (version_info.is_valid()) {
320 std::string chrome_version = version_info.Name() + " - " + 308 std::string chrome_version = version_info.Name() + " - " +
321 version_info.Version() + 309 version_info.Version() +
322 " (" + version_info.LastChange() + ")"; 310 " (" + version_info.LastChange() + ")";
323 AddFeedbackData(&feedback_data, std::string(kChromeVersionTag), 311 AddFeedbackData(&feedback_data, std::string(kChromeVersionTag),
324 chrome_version); 312 chrome_version);
325 } 313 }
326 314
327 // We don't need the OS version for ChromeOS since we get it in 315 // We don't need the OS version for ChromeOS since we get it in
328 // CHROMEOS_RELEASE_VERSION from /etc/lsb-release 316 // CHROMEOS_RELEASE_VERSION from /etc/lsb-release
329 #if !defined(OS_CHROMEOS) 317 #if !defined(OS_CHROMEOS)
330 // Add OS version (eg, for WinXP SP2: "5.1.2600 Service Pack 2"). 318 // Add OS version (eg, for WinXP SP2: "5.1.2600 Service Pack 2").
331 std::string os_version = ""; 319 std::string os_version = "";
332 SetOSVersion(&os_version); 320 SetOSVersion(&os_version);
333 AddFeedbackData(&feedback_data, std::string(kOsVersionTag), os_version); 321 AddFeedbackData(&feedback_data, std::string(kOsVersionTag), os_version);
334 #endif 322 #endif
335 323
336 // Include the page image if we have one. 324 // Include the page image if we have one.
337 if (data.image().get() && data.image()->size()) { 325 if (data->image().get() && data->image()->size()) {
338 userfeedback::PostedScreenshot screenshot; 326 userfeedback::PostedScreenshot screenshot;
339 screenshot.set_mime_type(kPngMimeType); 327 screenshot.set_mime_type(kPngMimeType);
340 // Set the dimensions of the screenshot 328 // Set the dimensions of the screenshot
341 userfeedback::Dimensions dimensions; 329 userfeedback::Dimensions dimensions;
342 gfx::Rect& screen_size = GetScreenshotSize(); 330 gfx::Rect& screen_size = GetScreenshotSize();
343 dimensions.set_width(static_cast<float>(screen_size.width())); 331 dimensions.set_width(static_cast<float>(screen_size.width()));
344 dimensions.set_height(static_cast<float>(screen_size.height())); 332 dimensions.set_height(static_cast<float>(screen_size.height()));
345 *(screenshot.mutable_dimensions()) = dimensions; 333 *(screenshot.mutable_dimensions()) = dimensions;
346 334
347 int image_data_size = data.image()->size(); 335 int image_data_size = data->image()->size();
348 char* image_data = reinterpret_cast<char*>(&(data.image()->front())); 336 char* image_data = reinterpret_cast<char*>(&(data->image()->front()));
349 screenshot.set_binary_content(std::string(image_data, image_data_size)); 337 screenshot.set_binary_content(std::string(image_data, image_data_size));
350 338
351 // Set the screenshot object in feedback 339 // Set the screenshot object in feedback
352 *(feedback_data.mutable_screenshot()) = screenshot; 340 *(feedback_data.mutable_screenshot()) = screenshot;
353 } 341 }
354 342
355 #if defined(OS_CHROMEOS) 343 #if defined(OS_CHROMEOS)
356 if (data.sys_info()) { 344 if (data->sys_info()) {
357 // Add the product specific data 345 // Add the product specific data
358 for (chromeos::system::LogDictionaryType::const_iterator i = 346 for (chromeos::SystemLogsResponse::const_iterator i =
359 data.sys_info()->begin(); i != data.sys_info()->end(); ++i) { 347 data->sys_info()->begin(); i != data->sys_info()->end(); ++i) {
360 if (i->first == kSyncDataKey || 348 if (ValidFeedbackSize(i->second)) {
361 i->first == kHUDLogDataKey ||
362 ValidFeedbackSize(i->second)) {
363 AddFeedbackData(&feedback_data, i->first, i->second); 349 AddFeedbackData(&feedback_data, i->first, i->second);
364 } 350 }
365 } 351 }
366 352
367 // If we have zipped logs, add them here 353 std::string compressed_logs = ZipLogs(data->sys_info());
368 if (data.zip_content()) { 354 if (compressed_logs.size()) {
369 userfeedback::ProductSpecificBinaryData attachment; 355 userfeedback::ProductSpecificBinaryData attachment;
370 attachment.set_mime_type(kBZip2MimeType); 356 attachment.set_mime_type(kBZip2MimeType);
371 attachment.set_name(kLogsAttachmentName); 357 attachment.set_name(kLogsAttachmentName);
372 attachment.set_data(*data.zip_content()); 358 attachment.set_data(compressed_logs);
373 delete data.zip_content();
374 *(feedback_data.add_product_specific_binary_data()) = attachment; 359 *(feedback_data.add_product_specific_binary_data()) = attachment;
375 } 360 }
376 } 361 }
377 delete data.sys_info();
378 362
379 if (data.timestamp() != "") 363 if (data->timestamp() != "")
380 AddFeedbackData(&feedback_data, std::string(kTimestampTag), 364 AddFeedbackData(&feedback_data, std::string(kTimestampTag),
381 data.timestamp()); 365 data->timestamp());
382 366
383 if (data.attached_filename() != "" && data.attached_filedata() && 367 if (data->attached_filename() != "" &&
384 data.attached_filedata()->size()) { 368 data->attached_filedata() &&
369 data->attached_filedata()->size()) {
385 userfeedback::ProductSpecificBinaryData attached_file; 370 userfeedback::ProductSpecificBinaryData attached_file;
386 attached_file.set_mime_type(kArbitraryMimeType); 371 attached_file.set_mime_type(kArbitraryMimeType);
387 attached_file.set_name(data.attached_filename()); 372 attached_file.set_name(data->attached_filename());
388 attached_file.set_data(*data.attached_filedata()); 373 attached_file.set_data(*data->attached_filedata());
389 delete data.attached_filedata(); 374 delete data->attached_filedata();
390 *(feedback_data.add_product_specific_binary_data()) = attached_file; 375 *(feedback_data.add_product_specific_binary_data()) = attached_file;
391 } 376 }
392 #endif 377 #endif
393 378
394 // Set our category tag if we have one 379 // Set our category tag if we have one
395 if (data.category_tag().size()) 380 if (data->category_tag().size())
396 feedback_data.set_category_tag(data.category_tag()); 381 feedback_data.set_category_tag(data->category_tag());
397 382
398 // Set our Chrome specific data 383 // Set our Chrome specific data
399 userfeedback::ChromeData chrome_data; 384 userfeedback::ChromeData chrome_data;
400 chrome_data.set_chrome_platform( 385 chrome_data.set_chrome_platform(
401 #if defined(OS_CHROMEOS) 386 #if defined(OS_CHROMEOS)
402 userfeedback::ChromeData_ChromePlatform_CHROME_OS); 387 userfeedback::ChromeData_ChromePlatform_CHROME_OS);
403 userfeedback::ChromeOsData chrome_os_data; 388 userfeedback::ChromeOsData chrome_os_data;
404 chrome_os_data.set_category( 389 chrome_os_data.set_category(
405 userfeedback::ChromeOsData_ChromeOsCategory_OTHER); 390 userfeedback::ChromeOsData_ChromeOsCategory_OTHER);
406 *(chrome_data.mutable_chrome_os_data()) = chrome_os_data; 391 *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
407 #else 392 #else
408 userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER); 393 userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER);
409 userfeedback::ChromeBrowserData chrome_browser_data; 394 userfeedback::ChromeBrowserData chrome_browser_data;
410 chrome_browser_data.set_category( 395 chrome_browser_data.set_category(
411 userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER); 396 userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER);
412 *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data; 397 *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
413 #endif 398 #endif
414 399
415 *(feedback_data.mutable_chrome_data()) = chrome_data; 400 *(feedback_data.mutable_chrome_data()) = chrome_data;
416 401
417 // Serialize our report to a string pointer we can pass around 402 // Serialize our report to a string pointer we can pass around
418 std::string* post_body = new std::string; 403 std::string* post_body = new std::string;
419 feedback_data.SerializeToString(post_body); 404 feedback_data.SerializeToString(post_body);
420 405
421 // We have the body of our POST, so send it off to the server with 0 delay 406 // We have the body of our POST, so send it off to the server with 0 delay
422 DispatchFeedback(data.profile(), post_body, 0); 407 DispatchFeedback(data->profile(), post_body, 0);
423 } 408 }
424 409
425 #if defined(FULL_SAFE_BROWSING) 410 #if defined(FULL_SAFE_BROWSING)
426 // static 411 // static
427 void FeedbackUtil::ReportPhishing(WebContents* current_tab, 412 void FeedbackUtil::ReportPhishing(WebContents* current_tab,
428 const std::string& phishing_url) { 413 const std::string& phishing_url) {
429 current_tab->GetController().LoadURL( 414 current_tab->GetController().LoadURL(
430 safe_browsing_util::GeneratePhishingReportUrl( 415 safe_browsing_util::GeneratePhishingReportUrl(
431 kReportPhishingUrl, phishing_url, 416 kReportPhishingUrl, phishing_url,
432 false /* not client-side detection */), 417 false /* not client-side detection */),
(...skipping 24 matching lines...) Expand all
457 if (screenshot_size == NULL) 442 if (screenshot_size == NULL)
458 screenshot_size = new gfx::Rect(); 443 screenshot_size = new gfx::Rect();
459 return *screenshot_size; 444 return *screenshot_size;
460 } 445 }
461 446
462 // static 447 // static
463 void FeedbackUtil::SetScreenshotSize(const gfx::Rect& rect) { 448 void FeedbackUtil::SetScreenshotSize(const gfx::Rect& rect) {
464 gfx::Rect& screen_size = GetScreenshotSize(); 449 gfx::Rect& screen_size = GetScreenshotSize();
465 screen_size = rect; 450 screen_size = rect;
466 } 451 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698