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