diff options
-rw-r--r-- | chrome/browser/browser_about_handler.cc | 50 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/syslogs_library.cc | 52 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/syslogs_library.h | 17 | ||||
-rw-r--r-- | chrome/browser/chromeos/dom_ui/system_info_ui.cc | 42 | ||||
-rw-r--r-- | chrome/browser/dom_ui/bug_report_ui.cc | 161 |
5 files changed, 203 insertions, 119 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 8bc83f4..4406a31 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -122,7 +122,6 @@ const char kSandboxPath[] = "sandbox"; #if defined(OS_CHROMEOS) const char kNetworkPath[] = "network"; const char kOSCreditsPath[] = "os-credits"; -const char kSysPath[] = "system"; #endif // Add path here to be included in about:about @@ -150,7 +149,6 @@ const char *kAllAboutPaths[] = { #if defined(OS_CHROMEOS) kNetworkPath, kOSCreditsPath, - kSysPath, #endif }; @@ -789,50 +787,6 @@ std::string AboutSync() { sync_html, &strings , "t" /* template root node id */); } -#if defined(OS_CHROMEOS) -std::string AboutSys(const std::string& query) { - DictionaryValue strings; - strings.SetString("title", l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TITLE)); - strings.SetString("description", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_DESC)); - strings.SetString("table_title", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TABLE_TITLE)); - strings.SetString("expand_all_btn", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND_ALL)); - strings.SetString("collapse_all_btn", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE_ALL)); - strings.SetString("expand_btn", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_EXPAND)); - strings.SetString("collapse_btn", - l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE)); - ChromeURLDataManager::DataSource::SetFontAndTextDirection(&strings); - - chromeos::SyslogsLibrary* syslogs_lib = - chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); - scoped_ptr<chromeos::LogDictionaryType> sys_info; - if (syslogs_lib) - sys_info.reset(syslogs_lib->GetSyslogs(new FilePath())); - if (sys_info.get()) { - ListValue* details = new ListValue(); - strings.Set("details", details); - chromeos::LogDictionaryType::iterator it; - for (it = sys_info.get()->begin(); it != sys_info.get()->end(); ++it) { - DictionaryValue* val = new DictionaryValue; - val->SetString("stat_name", it->first); - val->SetString("stat_value", it->second); - details->Append(val); - } - strings.SetString("anchor", query); - } - static const base::StringPiece sys_html( - ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_ABOUT_SYS_HTML)); - - return jstemplate_builder::GetTemplatesHtml( - sys_html, &strings , "t" /* template root node id */); -} -#endif - std::string VersionNumberToString(uint32 value) { int hi = (value >> 8) & 0xff; int low = value & 0xff; @@ -958,10 +912,6 @@ void AboutSource::StartDataRequest(const std::string& path_raw, #endif } else if (path == kSyncPath) { response = AboutSync(); -#if defined(OS_CHROMEOS) - } else if (path == kSysPath) { - response = AboutSys(info); -#endif } else if (path == kGpuPath) { response = AboutGpu(); } diff --git a/chrome/browser/chromeos/cros/syslogs_library.cc b/chrome/browser/chromeos/cros/syslogs_library.cc index 7c5f4fa..9fed176 100644 --- a/chrome/browser/chromeos/cros/syslogs_library.cc +++ b/chrome/browser/chromeos/cros/syslogs_library.cc @@ -15,12 +15,42 @@ class SyslogsLibraryImpl : public SyslogsLibrary { SyslogsLibraryImpl() {} virtual ~SyslogsLibraryImpl() {} - LogDictionaryType* GetSyslogs(FilePath* tmpfilename) { + virtual Handle RequestSyslogs(FilePath* tmpfilename, + CancelableRequestConsumerBase* consumer, + ReadCompleteCallback* callback) { + // Register the callback request. + scoped_refptr<CancelableRequest<ReadCompleteCallback> > request( + new CancelableRequest<ReadCompleteCallback>(callback)); + AddRequest(request, consumer); + + // Schedule a task on the FILE thread which will then trigger a request + // callback on the calling thread (e.g. UI) when complete. + ChromeThread::PostTask( + ChromeThread::FILE, FROM_HERE, + NewRunnableMethod( + this, &SyslogsLibraryImpl::ReadSyslogs, request, tmpfilename)); + + return request->handle(); + } + + private: + // Called from FILE thread. + void ReadSyslogs( + scoped_refptr<CancelableRequest<ReadCompleteCallback> > request, + FilePath* tmpfilename) { + if (request->canceled()) + return; + + LogDictionaryType* logs = NULL; if (CrosLibrary::Get()->EnsureLoaded()) { - return chromeos::GetSystemLogs(tmpfilename); + logs = chromeos::GetSystemLogs(tmpfilename); } - return NULL; + + // Will call the callback on the calling thread. + request->ForwardResult(Tuple1<LogDictionaryType*>(logs)); } + + DISALLOW_COPY_AND_ASSIGN(SyslogsLibraryImpl); }; class SyslogsLibraryStubImpl : public SyslogsLibrary { @@ -28,12 +58,14 @@ class SyslogsLibraryStubImpl : public SyslogsLibrary { SyslogsLibraryStubImpl() {} virtual ~SyslogsLibraryStubImpl() {} - LogDictionaryType* GetSyslogs(FilePath* tmpfilename) { - return &log_dictionary_; - } + virtual Handle RequestSyslogs(FilePath* tmpfilename, + CancelableRequestConsumerBase* consumer, + ReadCompleteCallback* callback) { + if (callback) + callback->Run(Tuple1<LogDictionaryType*>(NULL)); - private: - LogDictionaryType log_dictionary_; + return 0; + } }; // static @@ -45,3 +77,7 @@ SyslogsLibrary* SyslogsLibrary::GetImpl(bool stub) { } } // namespace chromeos + +// Allows InvokeLater without adding refcounting. SyslogsLibraryImpl is a +// Singleton and won't be deleted until it's last InvokeLater is run. +DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::SyslogsLibraryImpl); diff --git a/chrome/browser/chromeos/cros/syslogs_library.h b/chrome/browser/chromeos/cros/syslogs_library.h index 85c88cc..56a07f7 100644 --- a/chrome/browser/chromeos/cros/syslogs_library.h +++ b/chrome/browser/chromeos/cros/syslogs_library.h @@ -7,18 +7,29 @@ #pragma once #include "base/singleton.h" +#include "chrome/browser/cancelable_request.h" #include "cros/chromeos_syslogs.h" +class CancelableRequestConsumerBase; + namespace chromeos { // This interface defines interaction with the ChromeOS syslogs APIs. -class SyslogsLibrary { +class SyslogsLibrary : public CancelableRequestProvider { public: + typedef Callback1<LogDictionaryType*>::Type ReadCompleteCallback; + SyslogsLibrary() {} virtual ~SyslogsLibrary() {} - // System logs gathered for userfeedback - virtual LogDictionaryType* GetSyslogs(FilePath* tmpfilename) = 0; + // Request system logs. Read happens on the FILE thread and callback is + // called on the thread this is called from (via ForwardResult). + // Logs are owned by callback function (use delete when done with them). + // Returns the request handle. Call CancelRequest(Handle) to cancel + // the request before the callback gets called. + virtual Handle RequestSyslogs(FilePath* tmpfilename, + CancelableRequestConsumerBase* consumer, + ReadCompleteCallback* callback) = 0; // Factory function, creates a new instance and returns ownership. // For normal usage, access the singleton via CrosLibrary::Get(). diff --git a/chrome/browser/chromeos/dom_ui/system_info_ui.cc b/chrome/browser/chromeos/dom_ui/system_info_ui.cc index 01172833..a15f8d80 100644 --- a/chrome/browser/chromeos/dom_ui/system_info_ui.cc +++ b/chrome/browser/chromeos/dom_ui/system_info_ui.cc @@ -46,6 +46,14 @@ class SystemInfoUIHTMLSource : public ChromeURLDataManager::DataSource { private: ~SystemInfoUIHTMLSource() {} + void SyslogsComplete(chromeos::LogDictionaryType* sys_info); + + CancelableRequestConsumer consumer_; + + // Stored data from StartDataRequest() + std::string path_; + int request_id_; + DISALLOW_COPY_AND_ASSIGN(SystemInfoUIHTMLSource); }; @@ -71,12 +79,29 @@ class SystemInfoHandler : public DOMMessageHandler, //////////////////////////////////////////////////////////////////////////////// SystemInfoUIHTMLSource::SystemInfoUIHTMLSource() - : DataSource(chrome::kChromeUISystemInfoHost, MessageLoop::current()) { + : DataSource(chrome::kChromeUISystemInfoHost, MessageLoop::current()), + request_id_(0) { } void SystemInfoUIHTMLSource::StartDataRequest(const std::string& path, bool is_off_the_record, int request_id) { + path_ = path; + request_id_ = request_id; + + chromeos::SyslogsLibrary* syslogs_lib = + chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); + if (syslogs_lib) { + FilePath* tmpfilename = NULL; // use default filepath. + syslogs_lib->RequestSyslogs( + tmpfilename, + &consumer_, + NewCallback(this, &SystemInfoUIHTMLSource::SyslogsComplete)); + } +} + +void SystemInfoUIHTMLSource::SyslogsComplete( + chromeos::LogDictionaryType* sys_info) { DictionaryValue strings; strings.SetString("title", l10n_util::GetStringUTF16(IDS_ABOUT_SYS_TITLE)); strings.SetString("description", @@ -93,24 +118,19 @@ void SystemInfoUIHTMLSource::StartDataRequest(const std::string& path, l10n_util::GetStringUTF16(IDS_ABOUT_SYS_COLLAPSE)); SetFontAndTextDirection(&strings); - chromeos::SyslogsLibrary* syslogs_lib = - chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); - scoped_ptr<chromeos::LogDictionaryType> sys_info; - if (syslogs_lib) - sys_info.reset(syslogs_lib->GetSyslogs(new FilePath())); - if (sys_info.get()) { + if (sys_info) { ListValue* details = new ListValue(); strings.Set("details", details); chromeos::LogDictionaryType::iterator it; - for (it = sys_info.get()->begin(); it != sys_info.get()->end(); ++it) { + for (it = sys_info->begin(); it != sys_info->end(); ++it) { DictionaryValue* val = new DictionaryValue; val->SetString("stat_name", it->first); val->SetString("stat_value", it->second); details->Append(val); } - strings.SetString("anchor", path); + strings.SetString("anchor", path_); + delete sys_info; } - static const base::StringPiece systeminfo_html( ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_ABOUT_SYS_HTML)); @@ -121,7 +141,7 @@ void SystemInfoUIHTMLSource::StartDataRequest(const std::string& path, html_bytes->data.resize(full_html.size()); std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); - SendResponse(request_id, html_bytes); + SendResponse(request_id_, html_bytes); } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc index 6fb0706..c536fc7 100644 --- a/chrome/browser/dom_ui/bug_report_ui.cc +++ b/chrome/browser/dom_ui/bug_report_ui.cc @@ -120,16 +120,6 @@ std::string GetUserEmail() { return manager->logged_in_user().email(); } -chromeos::LogDictionaryType* GetSystemInformation() { - chromeos::LogDictionaryType* sys_info = NULL; - chromeos::SyslogsLibrary* syslogs_lib = - chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); - - if (syslogs_lib) - sys_info = syslogs_lib->GetSyslogs(NULL); - - return sys_info; -} #endif @@ -227,13 +217,33 @@ class BugReportHandler : public DOMMessageHandler, private: void CloseTab(); + void SendReport(); +#if defined(OS_CHROMEOS) + void SyslogsComplete(chromeos::LogDictionaryType* logs); +#endif - std::string page_url_; TabContents* tab_; TabContents* target_tab_; DOMUIScreenshotSource* screenshot_source_; -#if defined (OS_CHROMEOS) + + // 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_; + +#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_; + // Variables to track SyslogsLibrary::RequestSyslogs callback. + chromeos::SyslogsLibrary::Handle syslogs_handle_; + CancelableRequestConsumer syslogs_consumer_; #endif DISALLOW_COPY_AND_ASSIGN(BugReportHandler); @@ -375,10 +385,29 @@ void BugReportUIHTMLSource::StartDataRequest(const std::string& path, // //////////////////////////////////////////////////////////////////////////////// BugReportHandler::BugReportHandler(TabContents* tab) - : tab_(tab), screenshot_source_(NULL) { + : tab_(tab) + , screenshot_source_(NULL) + , problem_type_(0) +#if defined(OS_CHROMEOS) + , sys_info_(NULL) + , send_sys_info_(false) + , sent_report_(false) + , syslogs_handle_(0) +#endif +{ } BugReportHandler::~BugReportHandler() { +#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_); + } + delete sys_info_; +#endif } void BugReportHandler::ClobberScreenshotsSource() { @@ -476,10 +505,17 @@ void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { dialog_defaults.Append(new StringValue("")); #if defined(OS_CHROMEOS) - // 1: user e-mail - sys_info_ = GetSystemInformation(); + // 1: about:system dialog_defaults.Append(new StringValue(chrome::kChromeUISystemInfoURL)); - + // Trigger the request for system information here. + chromeos::SyslogsLibrary* syslogs_lib = + chromeos::CrosLibrary::Get()->GetSyslogsLibrary(); + if (syslogs_lib) { + FilePath* tmpfilename = NULL; // use default filepath. + syslogs_handle_ = syslogs_lib->RequestSyslogs( + tmpfilename, &syslogs_consumer_, + NewCallback(this, &BugReportHandler::SyslogsComplete)); + } // 2: user e-mail dialog_defaults.Append(new StringValue(GetUserEmail())); #endif @@ -513,9 +549,8 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { // #0 - Problem type. std::string problem_type_str; - int problem_type = 0; (*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; } @@ -525,16 +560,14 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { } // #1 - Page url. - std::string page_url; - (*i)->GetAsString(&page_url); + (*i)->GetAsString(&page_url_); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; } // #2 - Description. - std::string description; - (*i)->GetAsString(&description); + (*i)->GetAsString(&description_); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; @@ -544,6 +577,12 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { std::string screenshot_path; (*i)->GetAsString(&screenshot_path); screenshot_path.erase(0, strlen(kScreenshotBaseUrl)); + + // Get the image to send in the report. + if (screenshot_path.size() > 0) { + image_ = screenshot_source_->GetScreenshot(screenshot_path); + } + #if defined(OS_CHROMEOS) if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; @@ -551,8 +590,7 @@ void BugReportHandler::HandleSendReport(const ListValue* list_value) { } // #4 - User e-mail - std::string user_email; - (*i)->GetAsString(&user_email); + (*i)->GetAsString(&user_email_); if (++i == list_value->end()) { LOG(ERROR) << "Incorrect data passed to sendReport."; return; @@ -561,38 +599,67 @@ 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"); + + // 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_ == false || sys_info_ != NULL || syslogs_handle_ == 0) { + SendReport(); + // If we scheduled a callback, don't call SendReport() again. + send_sys_info_ = false; + } +#else + SendReport(); #endif - // Get the image to send in the report. - char* image_data = NULL; - int image_data_size = 0; - // Make sure this object remains in scope till SendReport returns. - std::vector<unsigned char> image; - if (screenshot_path.size() > 0) { - image = screenshot_source_->GetScreenshot(screenshot_path); - image_data = reinterpret_cast<char*>(&(image.front())); - image_data_size = image.size(); - } +} - BugReportUtil::SendReport(dom_ui_->GetProfile(), - UTF16ToUTF8(target_tab_->GetTitle()), - problem_type, - page_url, - description, - image_data, - image_data_size, browser::screen_size.width(), +void BugReportHandler::SendReport() { + int image_data_size = image_.size(); + char* image_data = image_data_size ? + reinterpret_cast<char*>(&(image_.front())) : NULL; + BugReportUtil::SendReport(dom_ui_->GetProfile() + , UTF16ToUTF8(target_tab_->GetTitle()) + , problem_type_ + , page_url_ + , description_ + , image_data + , image_data_size + , browser::screen_size.width() + , browser::screen_size.height() #if defined(OS_CHROMEOS) - browser::screen_size.height(), - user_email, - ((sys_info_checkbox == "true") ? - GetSystemInformation() : NULL)); -#else - browser::screen_size.height()); + , user_email_ + , send_sys_info_ ? sys_info_ : NULL +#endif + ); + +#if defined(OS_CHROMEOS) + delete sys_info_; + sys_info_ = NULL; + sent_report_ = true; #endif CloseTab(); } +#if defined(OS_CHROMEOS) +// Called from the same thread as HandleGetDialogDefaults, i.e. the UI thread. +void BugReportHandler::SyslogsComplete(chromeos::LogDictionaryType* logs) { + if (sent_report_) { + // We already sent the report, just delete the data. + delete logs; + } else { + 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; +} +#endif + void BugReportHandler::HandleCancel(const ListValue*) { CloseTab(); } |