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/feedback/feedback_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/file_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/metrics/variations/variations_http_header_provider.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_util.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/metrics/metrics_log_manager.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/http/http_request_headers.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/locid.h"
4158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "third_party/zlib/google/zip.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochusing content::WebContents;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace {
4858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochconst base::FilePath::CharType kLogsFilename[] =
4958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    FILE_PATH_LITERAL("system_logs.txt");
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnamespace chrome {
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kAppLauncherCategoryTag[] = "AppLauncher";
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}  // namespace chrome
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst int kFeedbackVersion = 1;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kReportPhishingUrl[] =
593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    "http://www.google.com/safebrowsing/report_phish/";
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URL to post bug reports to.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFeedbackPostUrl[] =
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://www.google.com/tools/feedback/chrome/__submit";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kProtBufMimeType[] = "application/x-protobuf";
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPngMimeType[] = "image/png";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Tags we use in product specific data
693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kChromeVersionTag[] = "CHROME VERSION";
703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kOsVersionTag[] = "OS VERSION";
713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHttpPostSuccessNoContent = 204;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHttpPostFailNoConnection = -1;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHttpPostFailClientError = 400;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHttpPostFailServerError = 500;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kInitialRetryDelay = 900000;  // 15 minutes
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kRetryDelayIncreaseFactor = 2;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kRetryDelayLimit = 14400000;  // 4 hours
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kFeedbackMaxLength = 4 * 1024;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kFeedbackMaxLineCount = 40;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kArbitraryMimeType[] = "application/octet-stream";
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLogsAttachmentName[] = "system_logs.zip";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kTimestampTag[] = "TIMESTAMP";
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kChromeOSProductId = 208;
913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kChromeBrowserProductId = 237;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple net::URLFetcherDelegate to clean up URLFetcher on completion.
963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochclass FeedbackUtil::PostCleanup : public net::URLFetcherDelegate {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PostCleanup(Profile* profile,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              std::string* post_body,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int64 previous_delay) : profile_(profile),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      post_body_(post_body),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      previous_delay_(previous_delay) { }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from net::URLFetcherDelegate.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~PostCleanup() {}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* post_body_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 previous_delay_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostCleanup);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use the data parameter, instead use the pointer we pass into every
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// post cleanup object - that pointer will be deleted and deleted only on a
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// successful post to the feedback server.
1203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::PostCleanup::OnURLFetchComplete(
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::stringstream error_stream;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_code = source->GetResponseCode();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_code == kHttpPostSuccessNoContent) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We've sent our report, delete the report data
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete post_body_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_stream << "Success";
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Uh oh, feedback failed, send it off to retry
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (previous_delay_) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (previous_delay_ < kRetryDelayLimit)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        previous_delay_ *= kRetryDelayIncreaseFactor;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      previous_delay_ = kInitialRetryDelay;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    FeedbackUtil::DispatchFeedback(profile_, post_body_, previous_delay_);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Process the error for debug output
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (response_code == kHttpPostFailNoConnection) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_stream << "No connection to server.";
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((response_code > kHttpPostFailClientError) &&
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (response_code < kHttpPostFailServerError)) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_stream << "Client error: HTTP response code " << response_code;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (response_code > kHttpPostFailServerError) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_stream << "Server error: HTTP response code " << response_code;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_stream << "Unknown error: HTTP response code " << response_code;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(WARNING) << "FEEDBACK: Submission to feedback server (" <<
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               source->GetURL() << ") status: " << error_stream.str();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete the URLFetcher.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete source;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And then delete ourselves.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::SetOSVersion(std::string* os_version) {
1633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_WIN)
1643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
1653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::win::OSInfo::VersionNumber version_number = os_info->version_number();
1663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *os_version = base::StringPrintf("%d.%d.%d",
1673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                   version_number.major,
1683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                   version_number.minor,
1693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                   version_number.build);
1703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  int service_pack = os_info->service_pack().major;
1713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (service_pack > 0)
1723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    os_version->append(base::StringPrintf("Service Pack %d", service_pack));
1733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#elif defined(OS_MACOSX)
1743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *os_version = base::SysInfo::OperatingSystemVersion();
1753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#else
1763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  *os_version = "unknown";
1773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
1783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::DispatchFeedback(Profile* profile,
1823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                    std::string* post_body,
1833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                    int64 delay) {
1843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DCHECK(post_body);
1853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::MessageLoop::current()->PostDelayedTask(
1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      FROM_HERE,
1883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      base::Bind(&FeedbackUtil::SendFeedback, profile, post_body, delay),
1893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      base::TimeDelta::FromMilliseconds(delay));
1903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::SendFeedback(Profile* profile,
1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                std::string* post_body,
1953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                int64 previous_delay) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(post_body);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL post_url;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HasSwitch(switches::kFeedbackServer))
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    post_url = GURL(CommandLine::ForCurrentProcess()->
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetSwitchValueASCII(switches::kFeedbackServer));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    post_url = GURL(kFeedbackPostUrl);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLFetcher* fetcher = net::URLFetcher::Create(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      post_url, net::URLFetcher::POST,
2083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      new FeedbackUtil::PostCleanup(profile, post_body, previous_delay));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->SetRequestContext(profile->GetRequestContext());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->SetLoadFlags(
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES);
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  net::HttpRequestHeaders headers;
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome_variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      fetcher->GetOriginalURL(), profile->IsOffTheRecord(), false, &headers);
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fetcher->SetExtraRequestHeaders(headers.ToString());
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->SetUploadData(std::string(kProtBufMimeType), *post_body);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->Start();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::AddFeedbackData(
2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    userfeedback::ExtensionSubmit* feedback_data,
2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& key, const std::string& value) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't bother with empty keys or values
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key == "" || value == "") return;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create log_value object and add it to the web_data object
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::ProductSpecificData log_value;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log_value.set_key(key);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log_value.set_value(value);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::WebData* web_data = feedback_data->mutable_web_data();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *(web_data->add_product_specific_data()) = log_value;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool FeedbackUtil::ValidFeedbackSize(const std::string& content) {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (content.length() > kFeedbackMaxLength)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t line_count = std::count(content.begin(), content.end(), '\n');
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (line_count > kFeedbackMaxLineCount)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
2493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::SendReport(scoped_refptr<FeedbackData> data) {
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!data.get()) {
2513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    LOG(ERROR) << "FeedbackUtil::SendReport called with NULL data!";
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Create google feedback protocol buffer objects
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::ExtensionSubmit feedback_data;
2583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // type id set to 0, unused field but needs to be initialized to 0
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  feedback_data.set_type_id(0);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::CommonData* common_data = feedback_data.mutable_common_data();
2623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  userfeedback::WebData* web_data = feedback_data.mutable_web_data();
2633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set our user agent.
2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  userfeedback::Navigator* navigator = web_data->mutable_navigator();
2663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  navigator->set_user_agent(content::GetUserAgent(GURL()));
2673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set GAIA id to 0. We're not using gaia id's for recording
2693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // use feedback - we're using the e-mail field, allows users to
2703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // submit feedback from incognito mode and specify any mail id
2713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // they wish
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  common_data->set_gaia_id(0);
2733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Add the user e-mail to the feedback object
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  common_data->set_user_email(data->user_email());
2763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Add the description to the feedback object
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  common_data->set_description(data->description());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Add the language
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string chrome_locale = g_browser_process->GetApplicationLocale();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  common_data->set_source_description_language(chrome_locale);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set the url
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_data->set_url(data->page_url());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Add the Chrome version
2883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  chrome::VersionInfo version_info;
2893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (version_info.is_valid()) {
2903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string chrome_version = version_info.Name() + " - " +
2913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        version_info.Version() +
2923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        " (" + version_info.LastChange() + ")";
2933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    AddFeedbackData(&feedback_data, std::string(kChromeVersionTag),
2943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                    chrome_version);
2953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // We don't need the OS version for ChromeOS since we get it in
2983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // CHROMEOS_RELEASE_VERSION from /etc/lsb-release
2993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if !defined(OS_CHROMEOS)
3003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Add OS version (eg, for WinXP SP2: "5.1.2600 Service Pack 2").
3013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string os_version;
3023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetOSVersion(&os_version);
3033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  AddFeedbackData(&feedback_data, std::string(kOsVersionTag), os_version);
3043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
3053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Include the page image if we have one.
3073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (data->image().get() && data->image()->size()) {
3083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    userfeedback::PostedScreenshot screenshot;
3093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    screenshot.set_mime_type(kPngMimeType);
3103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // Set the dimensions of the screenshot
3113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    userfeedback::Dimensions dimensions;
3123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    gfx::Rect& screen_size = GetScreenshotSize();
3133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    dimensions.set_width(static_cast<float>(screen_size.width()));
3143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    dimensions.set_height(static_cast<float>(screen_size.height()));
3153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    *(screenshot.mutable_dimensions()) = dimensions;
3163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    int image_data_size = data->image()->size();
3183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    char* image_data = reinterpret_cast<char*>(&(data->image()->front()));
3193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    screenshot.set_binary_content(std::string(image_data, image_data_size));
3203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // Set the screenshot object in feedback
3223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    *(feedback_data.mutable_screenshot()) = screenshot;
3233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
3243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (data->sys_info()) {
3273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // Add the product specific data
3283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    for (chromeos::SystemLogsResponse::const_iterator i =
3292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        data->sys_info()->begin(); i != data->sys_info()->end(); ++i) {
3303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      if (ValidFeedbackSize(i->second)) {
3313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        AddFeedbackData(&feedback_data, i->first, i->second);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (data->compressed_logs() && data->compressed_logs()->size()) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      userfeedback::ProductSpecificBinaryData attachment;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      attachment.set_mime_type(kArbitraryMimeType);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attachment.set_name(kLogsAttachmentName);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      attachment.set_data(*(data->compressed_logs()));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *(feedback_data.add_product_specific_binary_data()) = attachment;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (data->timestamp() != "")
3453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    AddFeedbackData(&feedback_data, std::string(kTimestampTag),
3463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                    data->timestamp());
3473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (data->attached_filename() != "" &&
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data->attached_filedata() &&
3503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      data->attached_filedata()->size()) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    userfeedback::ProductSpecificBinaryData attached_file;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    attached_file.set_mime_type(kArbitraryMimeType);
3533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    attached_file.set_name(data->attached_filename());
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    attached_file.set_data(*data->attached_filedata());
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *(feedback_data.add_product_specific_binary_data()) = attached_file;
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set our category tag if we have one
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (data->category_tag().size())
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    feedback_data.set_bucket(data->category_tag());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set our Chrome specific data
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::ChromeData chrome_data;
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  chrome_data.set_chrome_platform(
3663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      userfeedback::ChromeData_ChromePlatform_CHROME_OS);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::ChromeOsData chrome_os_data;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_os_data.set_category(
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      userfeedback::ChromeOsData_ChromeOsCategory_OTHER);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *(chrome_data.mutable_chrome_os_data()) = chrome_os_data;
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback_data.set_product_id(kChromeOSProductId);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      userfeedback::ChromeData_ChromePlatform_CHROME_BROWSER);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  userfeedback::ChromeBrowserData chrome_browser_data;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_browser_data.set_category(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      userfeedback::ChromeBrowserData_ChromeBrowserCategory_OTHER);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *(chrome_data.mutable_chrome_browser_data()) = chrome_browser_data;
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback_data.set_product_id(kChromeBrowserProductId);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *(feedback_data.mutable_chrome_data()) = chrome_data;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serialize our report to a string pointer we can pass around
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* post_body = new std::string;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  feedback_data.SerializeToString(post_body);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // We have the body of our POST, so send it off to the server with 0 delay
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DispatchFeedback(data->profile(), post_body, 0);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(FULL_SAFE_BROWSING)
3933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
3943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::ReportPhishing(WebContents* current_tab,
3953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                  const std::string& phishing_url) {
3963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  current_tab->GetController().LoadURL(
3973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      safe_browsing_util::GeneratePhishingReportUrl(
3983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          kReportPhishingUrl, phishing_url,
3993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          false /* not client-side detection */),
4003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      content::Referrer(),
4013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      content::PAGE_TRANSITION_LINK,
4023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      std::string());
4033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
4053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstatic std::vector<unsigned char>* screenshot_png = NULL;
4073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstatic gfx::Rect* screenshot_size = NULL;
4083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
4103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::vector<unsigned char>* FeedbackUtil::GetScreenshotPng() {
4113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (screenshot_png == NULL)
4123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    screenshot_png = new std::vector<unsigned char>;
4133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return screenshot_png;
4143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
4173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::ClearScreenshotPng() {
4183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (screenshot_png)
4193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    screenshot_png->clear();
4203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
4233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochgfx::Rect& FeedbackUtil::GetScreenshotSize() {
4243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (screenshot_size == NULL)
4253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    screenshot_size = new gfx::Rect();
4263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return *screenshot_size;
4273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
4303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid FeedbackUtil::SetScreenshotSize(const gfx::Rect& rect) {
4313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  gfx::Rect& screen_size = GetScreenshotSize();
4323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  screen_size = rect;
4333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
4363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool FeedbackUtil::ZipString(const std::string& logs,
4373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                             std::string* compressed_logs) {
438ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath temp_path;
439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::FilePath zip_file;
440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Create a temporary directory, put the logs into a file in it. Create
442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // another temporary file to receive the zip file in.
44358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL(""), &temp_path))
444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
44558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  if (file_util::WriteFile(temp_path.Append(kLogsFilename),
44658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch                           logs.c_str(), logs.size()) == -1)
447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
448ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!file_util::CreateTemporaryFile(&zip_file))
449ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
450ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!zip::Zip(temp_path, zip_file, false))
452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
453ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!file_util::ReadFileToString(zip_file, compressed_logs))
455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return false;
456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
457ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return true;
458ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
459