diff options
-rw-r--r-- | chrome/browser/bug_report_data.cc | 34 | ||||
-rw-r--r-- | chrome/browser/bug_report_data.h | 111 | ||||
-rw-r--r-- | chrome/browser/bug_report_util.cc | 199 | ||||
-rw-r--r-- | chrome/browser/bug_report_util.h | 24 | ||||
-rw-r--r-- | chrome/browser/dom_ui/bug_report_ui.cc | 234 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
6 files changed, 370 insertions, 234 deletions
diff --git a/chrome/browser/bug_report_data.cc b/chrome/browser/bug_report_data.cc new file mode 100644 index 0000000..9219e52 --- /dev/null +++ b/chrome/browser/bug_report_data.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/bug_report_data.h" + +#include "chrome/browser/browser.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/notifications/system_notification.h" +#endif + + + +#if defined(OS_CHROMEOS) +// Called from the same thread as HandleGetDialogDefaults, i.e. the UI thread. +void BugReportData::SyslogsComplete(chromeos::LogDictionaryType* logs, + std::string* zip_content) { + if (sent_report_) { + // We already sent the report, just delete the data. + if (logs) + delete logs; + if (zip_content) + delete zip_content; + } else { + zip_content_ = zip_content; + sys_info_ = logs; // Will get deleted when SendReport() is called. + if (send_sys_info_) { + // We already prepared the report, send it now. + this->SendReport(); + } + } +} +#endif diff --git a/chrome/browser/bug_report_data.h b/chrome/browser/bug_report_data.h new file mode 100644 index 0000000..cc24535 --- /dev/null +++ b/chrome/browser/bug_report_data.h @@ -0,0 +1,111 @@ +// Copyright 2010 Google Inc. All Rights Reserved. +// Author: rkc@google.com (Rahul Chaturvedi) + +#ifndef CHROME_BROWSER_BUG_REPORT_DATA_H_ +#define CHROME_BROWSER_BUG_REPORT_DATA_H_ + + +#include <string> +#include <vector> + +#include "base/utf_string_conversions.h" +#include "chrome/browser/bug_report_util.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/cros/syslogs_library.h" +#endif + +class BugReportData { + public: + // Make sure we initialize these flags to false since SyslogsComplete + // may be triggered before we've called update data; in which case, + // we do not want it to just delete the logs it just gathered, and we + // don't want it to send the report either - this will make sure that if + // SyslogsComplete gets called before UpdateData, we'll simply populate the + // sys_info and zip_content fields and exit without disturbing anything else + BugReportData() : profile_(NULL) +#if defined(OS_CHROMEOS) + , sent_report_(false), send_sys_info_(false) +#endif + { + } + + // Defined in bug_report_ui.cc + void SendReport(); + + void UpdateData(Profile* profile + , const std::string& target_tab_url + , const string16& target_tab_title + , const int problem_type + , const std::string& page_url + , const std::string& description + , const std::vector<unsigned char>& image +#if defined(OS_CHROMEOS) + , const std::string& user_email + , const bool send_sys_info + , const bool sent_report +#endif + ) { + profile_ = profile; + target_tab_url_ = target_tab_url; + target_tab_title_ = target_tab_title; + problem_type_ = problem_type; + page_url_ = page_url; + description_ = description; + image_ = image; +#if defined(OS_CHROMEOS) + user_email_ = user_email; + send_sys_info_ = send_sys_info; + sent_report_ = sent_report; +#endif + } + +#if defined(OS_CHROMEOS) + void SyslogsComplete(chromeos::LogDictionaryType* logs, + std::string* zip_content); +#endif + + const std::string& target_tab_url() { return target_tab_url_; } + const string16& target_tab_title() { return target_tab_title_; } + + int problem_type() { return problem_type_; } + const std::string& page_url() { return page_url_; } + const std::string& description() { return description_; } + const std::vector<unsigned char>& image() { return image_; } +#if defined(OS_CHROMEOS) + const std::string& user_email() { return user_email_; } + const chromeos::LogDictionaryType* sys_info() { return sys_info_; } + const bool send_sys_info() { return send_sys_info_; } + const bool sent_report() { return sent_report_; } + const std::string* zip_content() { return zip_content_; } +#endif + + + private: + Profile* profile_; + + // Target tab url. + std::string target_tab_url_; + // Target tab page title. + string16 target_tab_title_; + + int problem_type_; + std::string page_url_; + std::string description_; + std::vector<unsigned char> image_; + +#if defined(OS_CHROMEOS) + // Chromeos specific values for SendReport. + std::string user_email_; + chromeos::LogDictionaryType* sys_info_; + // Content of the compressed system logs. + std::string* zip_content_; + // NOTE: Extra boolean sent_report_ is required because callback may + // occur before or after we call SendReport(). + bool sent_report_; + // Flag to indicate to SyslogsComplete that it should send the report + bool send_sys_info_; +#endif +}; + +#endif // CHROME_BROWSER_BUG_REPORT_DATA_H_ diff --git a/chrome/browser/bug_report_util.cc b/chrome/browser/bug_report_util.cc index db771cc..a726c74 100644 --- a/chrome/browser/bug_report_util.cc +++ b/chrome/browser/bug_report_util.cc @@ -72,42 +72,21 @@ const size_t kMaxLineCount = 10; const size_t kMaxSystemLogLength = 1024; #endif -} // namespace - +const int64 kInitialRetryDelay = 900000; // 15 minutes +const int64 kRetryDelayIncreaseFactor = 2; +const int64 kRetryDelayLimit = 14400000; // 4 hours -#if defined(OS_CHROMEOS) -class FeedbackNotification { - public: - // Note: notification will show only on one profile at a time. - void Show(Profile* profile, const string16& message, bool urgent) { - if (notification_.get()) { - notification_->Hide(); - } - notification_.reset( - new chromeos::SystemNotification(profile, kNotificationId, - IDR_STATUSBAR_FEEDBACK, - l10n_util::GetStringUTF16( - IDS_BUGREPORT_NOTIFICATION_TITLE))); - notification_->Show(message, urgent, false); - } - private: - FeedbackNotification() {} - friend struct DefaultSingletonTraits<FeedbackNotification>; +} // namespace - scoped_ptr<chromeos::SystemNotification> notification_; - DISALLOW_COPY_AND_ASSIGN(FeedbackNotification); -}; -#endif // Simple URLFetcher::Delegate to clean up URLFetcher on completion. class BugReportUtil::PostCleanup : public URLFetcher::Delegate { public: -#if defined(OS_CHROMEOS) - explicit PostCleanup(Profile* profile); -#else - PostCleanup(); -#endif + PostCleanup(Profile* profile, std::string* post_body, + int64 previous_delay) : profile_(profile), + post_body_(post_body), + previous_delay_(previous_delay) { } // Overridden from URLFetcher::Delegate. virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, @@ -121,18 +100,15 @@ class BugReportUtil::PostCleanup : public URLFetcher::Delegate { private: Profile* profile_; + std::string* post_body_; + int64 previous_delay_; DISALLOW_COPY_AND_ASSIGN(PostCleanup); }; -#if defined(OS_CHROMEOS) - BugReportUtil::PostCleanup::PostCleanup(Profile* profile) - : profile_(profile) { -#else - BugReportUtil::PostCleanup::PostCleanup() : profile_(NULL) { -#endif -} - +// Don't use the data parameter, instead use the pointer we pass into every +// post cleanup object - that pointer will be deleted and deleted only on a +// successful post to the feedback server. void BugReportUtil::PostCleanup::OnURLFetchComplete( const URLFetcher* source, const GURL& url, @@ -143,34 +119,35 @@ void BugReportUtil::PostCleanup::OnURLFetchComplete( std::stringstream error_stream; if (response_code == kHttpPostSuccessNoContent) { + // We've sent our report, delete the report data + delete post_body_; + error_stream << "Success"; - } else if (response_code == kHttpPostFailNoConnection) { - error_stream << "No connection to server."; - } else if ((response_code > kHttpPostFailClientError) && - (response_code < kHttpPostFailServerError)) { - error_stream << "Client error: HTTP response code " << response_code; - } else if (response_code > kHttpPostFailServerError) { - error_stream << "Server error: HTTP response code " << response_code; } else { - error_stream << "Unknown error: HTTP response code " << response_code; - } - - LOG(WARNING) << "Submission to feedback server (" << url - << ") status: " << error_stream.str(); + // Uh oh, feedback failed, send it off to retry + if (previous_delay_) { + if (previous_delay_ < kRetryDelayLimit) + previous_delay_ *= kRetryDelayIncreaseFactor; + } else { + previous_delay_ = kInitialRetryDelay; + } + BugReportUtil::DispatchFeedback(profile_, post_body_, previous_delay_); -#if defined(OS_CHROMEOS) - // Show the notification to the user; this notification will stay active till - // either the user closes it, or we display another notification. - if (response_code == kHttpPostSuccessNoContent) { - Singleton<FeedbackNotification>()->Show(profile_, l10n_util::GetStringUTF16( - IDS_BUGREPORT_FEEDBACK_STATUS_SUCCESS), false); - } else { - Singleton<FeedbackNotification>()->Show(profile_, - l10n_util::GetStringFUTF16(IDS_BUGREPORT_FEEDBACK_STATUS_FAIL, - ASCIIToUTF16(error_stream.str())), - true); + // Process the error for debug output + if (response_code == kHttpPostFailNoConnection) { + error_stream << "No connection to server."; + } else if ((response_code > kHttpPostFailClientError) && + (response_code < kHttpPostFailServerError)) { + error_stream << "Client error: HTTP response code " << response_code; + } else if (response_code > kHttpPostFailServerError) { + error_stream << "Server error: HTTP response code " << response_code; + } else { + error_stream << "Unknown error: HTTP response code " << response_code; + } } -#endif + + LOG(WARNING) << "FEEDBACK: Submission to feedback server (" << url << + ") status: " << error_stream.str() << std::endl; // Delete the URLFetcher. delete source; @@ -213,13 +190,47 @@ void BugReportUtil::SetFeedbackServer(const std::string& server) { feedback_server_ = server; } +// static +void BugReportUtil::DispatchFeedback(Profile* profile, + std::string* post_body, + int64 delay) { + DCHECK(post_body); + + MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableFunction( + &BugReportUtil::SendFeedback, profile, post_body, delay), delay); +} + +// static +void BugReportUtil::SendFeedback(Profile* profile, + std::string* post_body, + int64 previous_delay) { + DCHECK(post_body); + + GURL post_url; + if (CommandLine::ForCurrentProcess()-> + HasSwitch(switches::kFeedbackServer)) + post_url = GURL(CommandLine::ForCurrentProcess()-> + GetSwitchValueASCII(switches::kFeedbackServer)); + else + post_url = GURL(kBugReportPostUrl); + + URLFetcher* fetcher = new URLFetcher(post_url, URLFetcher::POST, + new BugReportUtil::PostCleanup(profile, + post_body, + previous_delay)); + fetcher->set_request_context(profile->GetRequestContext()); + + fetcher->set_upload_data(std::string(kProtBufMimeType), *post_body); + fetcher->Start(); +} + // static void BugReportUtil::AddFeedbackData( userfeedback::ExternalExtensionSubmit* feedback_data, const std::string& key, const std::string& value) { - // We have no reason to log any empty values - gives us no data - if (value == "") return; + // Don't bother with empty keys or values + if (key=="" || value == "") return; // Create log_value object and add it to the web_data object userfeedback::ProductSpecificData log_value; log_value.set_key(key); @@ -263,15 +274,6 @@ void BugReportUtil::SendReport(Profile* profile, #else int png_height) { #endif - GURL post_url; - - if (CommandLine::ForCurrentProcess()-> - HasSwitch(switches::kFeedbackServer)) - post_url = GURL(CommandLine::ForCurrentProcess()-> - GetSwitchValueASCII(switches::kFeedbackServer)); - else - post_url = GURL(kBugReportPostUrl); - // Create google feedback protocol buffer objects userfeedback::ExternalExtensionSubmit feedback_data; // type id set to 0, unused field but needs to be initialized to 0 @@ -320,17 +322,6 @@ void BugReportUtil::SendReport(Profile* profile, SetOSVersion(&os_version); AddFeedbackData(&feedback_data, std::string(kOsVersionTag), os_version); -#if defined(OS_CHROMEOS) - if (sys_info) { - for (chromeos::LogDictionaryType::const_iterator i = sys_info->begin(); - i != sys_info->end(); ++i) - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kCompressSystemFeedback) || ValidFeedbackSize(i->second)) { - AddFeedbackData(&feedback_data, i->first, i->second); - } - } -#endif - // Include the page image if we have one. if (png_data) { userfeedback::PostedScreenshot screenshot; @@ -347,15 +338,24 @@ void BugReportUtil::SendReport(Profile* profile, } #if defined(OS_CHROMEOS) - // Include the page image if we have one. - if (zipped_logs_data && CommandLine::ForCurrentProcess()->HasSwitch( - switches::kCompressSystemFeedback)) { - userfeedback::ProductSpecificBinaryData attachment; - attachment.set_mime_type(kBZip2MimeType); - attachment.set_name(kLogsAttachmentName); - attachment.set_data(std::string(zipped_logs_data, zipped_logs_length)); + if (sys_info) { + // Add the product specific data + for (chromeos::LogDictionaryType::const_iterator i = sys_info->begin(); + i != sys_info->end(); ++i) + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kCompressSystemFeedback) || ValidFeedbackSize(i->second)) { + AddFeedbackData(&feedback_data, i->first, i->second); + } - *(feedback_data.add_product_specific_binary_data()) = attachment; + // If we have zipped logs, add them here + if (zipped_logs_data && CommandLine::ForCurrentProcess()->HasSwitch( + switches::kCompressSystemFeedback)) { + userfeedback::ProductSpecificBinaryData attachment; + attachment.set_mime_type(kBZip2MimeType); + attachment.set_name(kLogsAttachmentName); + attachment.set_data(std::string(zipped_logs_data, zipped_logs_length)); + *(feedback_data.add_product_specific_binary_data()) = attachment; + } } #endif @@ -379,19 +379,12 @@ void BugReportUtil::SendReport(Profile* profile, *(feedback_data.mutable_chrome_data()) = chrome_data; - // We have the body of our POST, so send it off to the server. - URLFetcher* fetcher = new URLFetcher(post_url, URLFetcher::POST, -#if defined(OS_CHROMEOS) - new BugReportUtil::PostCleanup(profile)); -#else - new BugReportUtil::PostCleanup()); -#endif - fetcher->set_request_context(profile->GetRequestContext()); + // Serialize our report to a string pointer we can pass around + std::string* post_body = new std::string; + feedback_data.SerializeToString(post_body); - std::string post_body; - feedback_data.SerializeToString(&post_body); - fetcher->set_upload_data(std::string(kProtBufMimeType), post_body); - fetcher->Start(); + // We have the body of our POST, so send it off to the server with 0 delay + DispatchFeedback(profile, post_body, 0); } // static diff --git a/chrome/browser/bug_report_util.h b/chrome/browser/bug_report_util.h index 7d5af5d..61835d6 100644 --- a/chrome/browser/bug_report_util.h +++ b/chrome/browser/bug_report_util.h @@ -30,18 +30,8 @@ class TabContents; class BugReportUtil { public: -#if defined(OS_CHROMEOS) - enum BugType { - CONNECTIVITY_ISSUE = 0, - SYNC_ISSUE, - CRASH_ISSUE, - PAGE_FORMATTING, - EXTENSION_ISSUE, - SUSPEND_ISSUE, - PHISHING_PAGE, - OTHER_PROBLEM - }; -#else + +#if defined(OS_MACOSX) enum BugType { PAGE_WONT_LOAD = 0, PAGE_LOOKS_ODD, @@ -54,6 +44,7 @@ class BugReportUtil { }; #endif + // SetOSVersion copies the maj.minor.build + servicePack_string // into a string. We currently have: // base::win::GetVersion returns WinVersion, which is just @@ -68,6 +59,11 @@ class BugReportUtil { // This sets the address of the feedback server to be used by SendReport static void SetFeedbackServer(const std::string& server); + // Send the feedback report after the specified delay + static void DispatchFeedback(Profile* profile, std::string* feedback_data, + int64 delay); + + // Generates bug report data. static void SendReport(Profile* profile, const std::string& page_title_text, @@ -99,6 +95,10 @@ class BugReportUtil { userfeedback::ExternalExtensionSubmit* feedback_data, const std::string& key, const std::string& value); + // Send the feedback report + static void SendFeedback(Profile* profile, std::string* feedback_data, + int64 previous_delay); + #if defined(OS_CHROMEOS) static bool ValidFeedbackSize(const std::string& content); #endif diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc index 84a0c34..bfe841c 100644 --- a/chrome/browser/dom_ui/bug_report_ui.cc +++ b/chrome/browser/dom_ui/bug_report_ui.cc @@ -22,6 +22,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/bug_report_data.h" #include "chrome/browser/bug_report_util.h" #include "chrome/browser/dom_ui/dom_ui_screenshot_source.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -196,39 +197,17 @@ class BugReportHandler : public DOMMessageHandler, void SetupScreenshotsSource(); void ClobberScreenshotsSource(); - void CloseTab(); - void SendReport(); -#if defined(OS_CHROMEOS) - void SyslogsComplete(chromeos::LogDictionaryType* logs, - std::string* zip_content); -#endif + void CancelFeedbackCollection(); + void CloseFeedbackTab(); TabContents* tab_; DOMUIScreenshotSource* screenshot_source_; - // Target tab url. - std::string target_tab_url_; - // Target tab page title. + BugReportData* bug_report_; string16 target_tab_title_; - - // These are filled in by HandleSendReport and used in SendReport. - int problem_type_; - std::string page_url_; - std::string description_; - std::vector<unsigned char> image_; - + std::string target_tab_url_; #if defined(OS_CHROMEOS) - // Chromeos specific values for SendReport. - std::string user_email_; - chromeos::LogDictionaryType* sys_info_; - // Flags to control behavior of SyslogsComplete callback. - bool send_sys_info_; - // NOTE: Extra boolean sent_report_ is required because callback may - // occur before or after we call SendReport(). - bool sent_report_; - // Content of the compressed system logs. - std::string* zip_content_; // Variables to track SyslogsLibrary::RequestSyslogs callback. chromeos::SyslogsLibrary::Handle syslogs_handle_; CancelableRequestConsumer syslogs_consumer_; @@ -367,34 +346,41 @@ void BugReportUIHTMLSource::StartDataRequest(const std::string& path, SendResponse(request_id, html_bytes); } + //////////////////////////////////////////////////////////////////////////////// // -// BugReportHandler +// BugReportData // //////////////////////////////////////////////////////////////////////////////// -BugReportHandler::BugReportHandler(TabContents* tab) - : tab_(tab) - , screenshot_source_(NULL) - , problem_type_(0) +void BugReportData::SendReport() { #if defined(OS_CHROMEOS) - , sys_info_(NULL) - , send_sys_info_(false) - , sent_report_(false) - , zip_content_(NULL) - , syslogs_handle_(0) + // In case we already got the syslogs and sent the report, leave + if (sent_report_) return; + // Set send_report_ so that no one else processes SendReport + sent_report_ = true; #endif -{ -} -BugReportHandler::~BugReportHandler() { + int image_data_size = image_.size(); + char* image_data = image_data_size ? + reinterpret_cast<char*>(&(image_.front())) : NULL; + BugReportUtil::SendReport(profile_ + , UTF16ToUTF8(target_tab_title_) + , problem_type_ + , page_url_ + , description_ + , image_data + , image_data_size + , browser::screen_size.width() + , browser::screen_size.height() +#if defined(OS_CHROMEOS) + , user_email_ + , zip_content_ ? zip_content_->c_str() : NULL + , zip_content_ ? zip_content_->length() : 0 + , send_sys_info_ ? sys_info_ : NULL +#endif + ); + #if defined(OS_CHROMEOS) - // If we requested the syslogs but haven't received them, cancel the request. - if (syslogs_handle_ != 0) { - chromeos::SyslogsLibrary* syslogs_lib = - chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); - if (syslogs_lib) - syslogs_lib->CancelRequest(syslogs_handle_); - } if (sys_info_) { delete sys_info_; sys_info_ = NULL; @@ -404,6 +390,31 @@ BugReportHandler::~BugReportHandler() { zip_content_ = NULL; } #endif + + // Once the report has been sent, this object has no purpose in life, delete + // ourselves. + delete this; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// BugReportHandler +// +//////////////////////////////////////////////////////////////////////////////// +BugReportHandler::BugReportHandler(TabContents* tab) + : tab_(tab) + , screenshot_source_(NULL) +#if defined(OS_CHROMEOS) + , syslogs_handle_(0) +#endif +{ +} + +BugReportHandler::~BugReportHandler() { + // Just in case we didn't send off bug_report_ to SendReport + if (bug_report_) + delete bug_report_; } void BugReportHandler::ClobberScreenshotsSource() { @@ -497,6 +508,8 @@ void BugReportHandler::RegisterMessages() { } void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { + bug_report_ = new BugReportData(); + // send back values which the dialog js needs initially ListValue dialog_defaults; @@ -515,7 +528,7 @@ void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { if (syslogs_lib) { syslogs_handle_ = syslogs_lib->RequestSyslogs( true, true, &syslogs_consumer_, - NewCallback(this, &BugReportHandler::SyslogsComplete)); + NewCallback(bug_report_, &BugReportData::SyslogsComplete)); } // 2: user e-mail dialog_defaults.Append(new StringValue(GetUserEmail())); @@ -549,9 +562,10 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { } // #0 - Problem type. + int problem_type; std::string problem_type_str; (*i)->GetAsString(&problem_type_str); - if (!base::StringToInt(problem_type_str, &problem_type_)) { + if (!base::StringToInt(problem_type_str, &problem_type)) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; } @@ -561,14 +575,16 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { } // #1 - Page url. - (*i)->GetAsString(&page_url_); + std::string page_url; + (*i)->GetAsString(&page_url); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; } // #2 - Description. - (*i)->GetAsString(&description_); + std::string description; + (*i)->GetAsString(&description); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; @@ -580,8 +596,9 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { screenshot_path.erase(0, strlen(kScreenshotBaseUrl)); // Get the image to send in the report. + std::vector<unsigned char> image; if (screenshot_path.size() > 0) { - image_ = screenshot_source_->GetScreenshot(screenshot_path); + image = screenshot_source_->GetScreenshot(screenshot_path); } #if defined(OS_CHROMEOS) @@ -591,7 +608,8 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { } // #4 - User e-mail - (*i)->GetAsString(&user_email_); + std::string user_email; + (*i)->GetAsString(&user_email); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; @@ -600,92 +618,70 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { // #5 - System info checkbox. std::string sys_info_checkbox; (*i)->GetAsString(&sys_info_checkbox); - send_sys_info_ = (sys_info_checkbox == "true"); + bool send_sys_info = (sys_info_checkbox == "true"); + + // If we aren't sending the sys_info, cancel the gathering of the syslogs. + if (!send_sys_info) + CancelFeedbackCollection(); + + // Update the data in bug_report_ so it can be sent + bug_report_->UpdateData(dom_ui_->GetProfile() + , target_tab_url_ + , target_tab_title_ + , problem_type + , page_url + , description + , image +#if defined(OS_CHROMEOS) + , user_email + , send_sys_info + , false // sent_report +#endif + ); // If we don't require sys_info, or we have it, or we never requested it // (because libcros failed to load), then send the report now. // Otherwise, the report will get sent when we receive sys_info. - if (!send_sys_info_ || sys_info_ != NULL || syslogs_handle_ == 0) { - SendReport(); - // If we scheduled a callback, don't call SendReport() again. - send_sys_info_ = false; + if (!send_sys_info || bug_report_->sys_info() != NULL || + syslogs_handle_ == 0) { + bug_report_->SendReport(); } #else - SendReport(); + bug_report_->SendReport(); #endif + // Lose the pointer to the BugReportData object; the object will delete itself + // from SendReport, whether we called it, or will be called by the log + // completion routine. + bug_report_ = NULL; + + // Whether we sent the report, or if it will be sent by the Syslogs complete + // function, close our feedback tab anyway, we have no more use for it. + CloseFeedbackTab(); } -void BugReportHandler::SendReport() { - int image_data_size = image_.size(); - char* image_data = image_data_size ? - reinterpret_cast<char*>(&(image_.front())) : NULL; - if (!dom_ui_) - return; - BugReportUtil::SendReport(dom_ui_->GetProfile() - , UTF16ToUTF8(target_tab_title_) - , problem_type_ - , page_url_ - , description_ - , image_data - , image_data_size - , browser::screen_size.width() - , browser::screen_size.height() -#if defined(OS_CHROMEOS) - , user_email_ - , zip_content_ ? zip_content_->c_str() : NULL - , zip_content_ ? zip_content_->length() : 0 - , send_sys_info_ ? sys_info_ : NULL -#endif - ); - -#if defined(OS_CHROMEOS) - if (sys_info_) { - delete sys_info_; - sys_info_ = NULL; - } - if (zip_content_) { - delete zip_content_; - zip_content_ = NULL; - } - sent_report_ = true; -#endif - - CloseTab(); +void BugReportHandler::HandleCancel(const ListValue*) { + CancelFeedbackCollection(); + CloseFeedbackTab(); } +void BugReportHandler::HandleOpenSystemTab(const ListValue* args) { #if defined(OS_CHROMEOS) -// Called from the same thread as HandleGetDialogDefaults, i.e. the UI thread. -void BugReportHandler::SyslogsComplete(chromeos::LogDictionaryType* logs, - std::string* zip_content) { - if (sent_report_) { - // We already sent the report, just delete the data. - if (logs) - delete logs; - if (zip_content) - delete zip_content; - } else { - zip_content_ = zip_content; - sys_info_ = logs; // Will get deleted when SendReport() is called. - if (send_sys_info_) { - // We already prepared the report, send it now. - SendReport(); - } - } - syslogs_handle_ = 0; -} + BrowserList::GetLastActive()->OpenSystemTabAndActivate(); #endif - -void BugReportHandler::HandleCancel(const ListValue*) { - CloseTab(); } -void BugReportHandler::HandleOpenSystemTab(const ListValue* args) { +void BugReportHandler::CancelFeedbackCollection() { #if defined(OS_CHROMEOS) - BrowserList::GetLastActive()->OpenSystemTabAndActivate(); + if (syslogs_handle_ != 0) { + chromeos::SyslogsLibrary* syslogs_lib = + chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); + if (syslogs_lib) + syslogs_lib->CancelRequest(syslogs_handle_); + } #endif } -void BugReportHandler::CloseTab() { +void BugReportHandler::CloseFeedbackTab() { Browser* browser = BrowserList::GetLastActive(); if (browser) { browser->CloseTabContents(tab_); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index df182be..3239ab1 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -352,6 +352,8 @@ 'browser/browsing_data_remover.h', 'browser/browsing_instance.cc', 'browser/browsing_instance.h', + 'browser/bug_report_data.h', + 'browser/bug_report_data.cc', 'browser/bug_report_util.cc', 'browser/bug_report_util.h', # TODO(rkc): Find a better way to include these files |