| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/webui/bug_report_ui.h" | |
| 6 | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/memory/weak_ptr.h" | |
| 13 #include "base/message_loop.h" | |
| 14 #include "base/string_number_conversions.h" | |
| 15 #include "base/utf_string_conversions.h" | |
| 16 #include "base/values.h" | |
| 17 #include "chrome/browser/bug_report_data.h" | |
| 18 #include "chrome/browser/bug_report_util.h" | |
| 19 #include "chrome/browser/profiles/profile.h" | |
| 20 #include "chrome/browser/ui/browser.h" | |
| 21 #include "chrome/browser/ui/browser_list.h" | |
| 22 #include "chrome/browser/ui/browser_window.h" | |
| 23 #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" | |
| 24 #include "chrome/browser/ui/webui/screenshot_source.h" | |
| 25 #include "chrome/browser/ui/window_snapshot/window_snapshot.h" | |
| 26 #include "chrome/common/chrome_paths.h" | |
| 27 #include "chrome/common/url_constants.h" | |
| 28 #include "content/browser/tab_contents/tab_contents.h" | |
| 29 #include "content/public/browser/browser_thread.h" | |
| 30 #include "grit/browser_resources.h" | |
| 31 #include "grit/chromium_strings.h" | |
| 32 #include "grit/generated_resources.h" | |
| 33 #include "grit/locale_settings.h" | |
| 34 #include "net/base/escape.h" | |
| 35 #include "ui/base/resource/resource_bundle.h" | |
| 36 | |
| 37 #if defined(OS_CHROMEOS) | |
| 38 #include "base/file_util.h" | |
| 39 #include "base/path_service.h" | |
| 40 #include "base/synchronization/waitable_event.h" | |
| 41 #include "chrome/browser/chromeos/cros/cros_library.h" | |
| 42 #include "chrome/browser/chromeos/login/user_manager.h" | |
| 43 #include "chrome/browser/chromeos/system/syslogs_provider.h" | |
| 44 #endif | |
| 45 | |
| 46 using content::BrowserThread; | |
| 47 | |
| 48 namespace { | |
| 49 | |
| 50 const char kScreenshotBaseUrl[] = "chrome://screenshots/"; | |
| 51 const char kCurrentScreenshotUrl[] = "chrome://screenshots/current"; | |
| 52 #if defined(OS_CHROMEOS) | |
| 53 const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/"; | |
| 54 const char kScreenshotPattern[] = "screenshot-*.png"; | |
| 55 | |
| 56 const size_t kMaxSavedScreenshots = 2; | |
| 57 #endif | |
| 58 | |
| 59 #if defined(OS_CHROMEOS) | |
| 60 | |
| 61 void GetSavedScreenshots(std::vector<std::string>* saved_screenshots, | |
| 62 base::WaitableEvent* done) { | |
| 63 saved_screenshots->clear(); | |
| 64 | |
| 65 FilePath fileshelf_path; | |
| 66 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, | |
| 67 &fileshelf_path)) { | |
| 68 done->Signal(); | |
| 69 return; | |
| 70 } | |
| 71 | |
| 72 file_util::FileEnumerator screenshots(fileshelf_path, false, | |
| 73 file_util::FileEnumerator::FILES, | |
| 74 std::string(kScreenshotPattern)); | |
| 75 FilePath screenshot = screenshots.Next(); | |
| 76 while (!screenshot.empty()) { | |
| 77 saved_screenshots->push_back(std::string(kSavedScreenshotsUrl) + | |
| 78 screenshot.BaseName().value()); | |
| 79 if (saved_screenshots->size() >= kMaxSavedScreenshots) | |
| 80 break; | |
| 81 | |
| 82 screenshot = screenshots.Next(); | |
| 83 } | |
| 84 done->Signal(); | |
| 85 } | |
| 86 | |
| 87 // This fuction posts a task to the file thread to create/list all the current | |
| 88 // and saved screenshots. | |
| 89 void GetScreenshotUrls(std::vector<std::string>* saved_screenshots) { | |
| 90 base::WaitableEvent done(true, false); | |
| 91 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | |
| 92 base::Bind(&GetSavedScreenshots, | |
| 93 saved_screenshots, &done)); | |
| 94 done.Wait(); | |
| 95 } | |
| 96 | |
| 97 std::string GetUserEmail() { | |
| 98 chromeos::UserManager* manager = chromeos::UserManager::Get(); | |
| 99 if (!manager) | |
| 100 return std::string(); | |
| 101 else | |
| 102 return manager->logged_in_user().display_email(); | |
| 103 } | |
| 104 #endif | |
| 105 | |
| 106 // Returns the index of the feedback tab if already open, -1 otherwise | |
| 107 int GetIndexOfFeedbackTab(Browser* browser) { | |
| 108 GURL bug_report_url(chrome::kChromeUIBugReportURL); | |
| 109 for (int i = 0; i < browser->tab_count(); ++i) { | |
| 110 TabContents* tab = browser->GetTabContentsAt(i); | |
| 111 if (tab && tab->GetURL().GetWithEmptyPath() == bug_report_url) | |
| 112 return i; | |
| 113 } | |
| 114 | |
| 115 return -1; | |
| 116 } | |
| 117 | |
| 118 } // namespace | |
| 119 | |
| 120 | |
| 121 namespace browser { | |
| 122 | |
| 123 void ShowHtmlBugReportView(Browser* browser, | |
| 124 const std::string& description_template, | |
| 125 size_t issue_type) { | |
| 126 // First check if we're already open (we cannot depend on ShowSingletonTab | |
| 127 // for this functionality since we need to make *sure* we never get | |
| 128 // instantiated again while we are open - with singleton tabs, that can | |
| 129 // happen) | |
| 130 int feedback_tab_index = GetIndexOfFeedbackTab(browser); | |
| 131 if (feedback_tab_index >= 0) { | |
| 132 // Do not refresh screenshot, do not create a new tab | |
| 133 browser->ActivateTabAt(feedback_tab_index, true); | |
| 134 return; | |
| 135 } | |
| 136 | |
| 137 std::vector<unsigned char>* last_screenshot_png = | |
| 138 BugReportUtil::GetScreenshotPng(); | |
| 139 last_screenshot_png->clear(); | |
| 140 | |
| 141 gfx::NativeWindow native_window = browser->window()->GetNativeHandle(); | |
| 142 gfx::Rect snapshot_bounds = gfx::Rect(browser->window()->GetBounds().size()); | |
| 143 bool success = browser::GrabWindowSnapshot(native_window, | |
| 144 last_screenshot_png, | |
| 145 snapshot_bounds); | |
| 146 BugReportUtil::SetScreenshotSize(success ? snapshot_bounds : gfx::Rect()); | |
| 147 | |
| 148 std::string bug_report_url = std::string(chrome::kChromeUIBugReportURL) + | |
| 149 "#" + base::IntToString(browser->active_index()) + | |
| 150 "?description=" + net::EscapeUrlEncodedData(description_template, false) + | |
| 151 "&issueType=" + base::IntToString(issue_type); | |
| 152 browser->ShowSingletonTab(GURL(bug_report_url)); | |
| 153 } | |
| 154 | |
| 155 } // namespace browser | |
| 156 | |
| 157 // The handler for Javascript messages related to the "bug report" dialog | |
| 158 class BugReportHandler : public WebUIMessageHandler, | |
| 159 public base::SupportsWeakPtr<BugReportHandler> { | |
| 160 public: | |
| 161 explicit BugReportHandler(TabContents* tab); | |
| 162 virtual ~BugReportHandler(); | |
| 163 | |
| 164 // Init work after Attach. Returns true on success. | |
| 165 bool Init(); | |
| 166 | |
| 167 // WebUIMessageHandler implementation. | |
| 168 virtual WebUIMessageHandler* Attach(WebUI* web_ui) OVERRIDE; | |
| 169 virtual void RegisterMessages() OVERRIDE; | |
| 170 | |
| 171 private: | |
| 172 void HandleGetDialogDefaults(const ListValue* args); | |
| 173 void HandleRefreshCurrentScreenshot(const ListValue* args); | |
| 174 #if defined(OS_CHROMEOS) | |
| 175 void HandleRefreshSavedScreenshots(const ListValue* args); | |
| 176 #endif | |
| 177 void HandleSendReport(const ListValue* args); | |
| 178 void HandleCancel(const ListValue* args); | |
| 179 void HandleOpenSystemTab(const ListValue* args); | |
| 180 | |
| 181 void SetupScreenshotsSource(); | |
| 182 void ClobberScreenshotsSource(); | |
| 183 | |
| 184 void CancelFeedbackCollection(); | |
| 185 void CloseFeedbackTab(); | |
| 186 | |
| 187 TabContents* tab_; | |
| 188 ScreenshotSource* screenshot_source_; | |
| 189 | |
| 190 BugReportData* bug_report_data_; | |
| 191 std::string target_tab_url_; | |
| 192 #if defined(OS_CHROMEOS) | |
| 193 // Variables to track SyslogsProvider::RequestSyslogs callback. | |
| 194 chromeos::system::SyslogsProvider::Handle syslogs_handle_; | |
| 195 CancelableRequestConsumer syslogs_consumer_; | |
| 196 #endif | |
| 197 | |
| 198 DISALLOW_COPY_AND_ASSIGN(BugReportHandler); | |
| 199 }; | |
| 200 | |
| 201 ChromeWebUIDataSource* CreateBugReportUIHTMLSource(bool successful_init) { | |
| 202 ChromeWebUIDataSource* source = | |
| 203 new ChromeWebUIDataSource(chrome::kChromeUIBugReportHost); | |
| 204 | |
| 205 source->AddLocalizedString("title", IDS_BUGREPORT_TITLE); | |
| 206 source->AddLocalizedString("page-title", IDS_BUGREPORT_REPORT_PAGE_TITLE); | |
| 207 source->AddLocalizedString("issue-with", IDS_BUGREPORT_ISSUE_WITH); | |
| 208 source->AddLocalizedString("page-url", IDS_BUGREPORT_REPORT_URL_LABEL); | |
| 209 source->AddLocalizedString("description", IDS_BUGREPORT_DESCRIPTION_LABEL); | |
| 210 source->AddLocalizedString("current-screenshot", | |
| 211 IDS_BUGREPORT_SCREENSHOT_LABEL); | |
| 212 source->AddLocalizedString("saved-screenshot", | |
| 213 IDS_BUGREPORT_SAVED_SCREENSHOT_LABEL); | |
| 214 #if defined(OS_CHROMEOS) | |
| 215 source->AddLocalizedString("user-email", IDS_BUGREPORT_USER_EMAIL_LABEL); | |
| 216 source->AddLocalizedString("sysinfo", | |
| 217 IDS_BUGREPORT_INCLUDE_SYSTEM_INFORMATION_CHKBOX); | |
| 218 source->AddLocalizedString("currentscreenshots", | |
| 219 IDS_BUGREPORT_CURRENT_SCREENSHOTS); | |
| 220 source->AddLocalizedString("savedscreenshots", | |
| 221 IDS_BUGREPORT_SAVED_SCREENSHOTS); | |
| 222 source->AddLocalizedString("choose-different-screenshot", | |
| 223 IDS_BUGREPORT_CHOOSE_DIFFERENT_SCREENSHOT); | |
| 224 source->AddLocalizedString("choose-original-screenshot", | |
| 225 IDS_BUGREPORT_CHOOSE_ORIGINAL_SCREENSHOT); | |
| 226 #else | |
| 227 source->AddLocalizedString("currentscreenshots", | |
| 228 IDS_BUGREPORT_INCLUDE_NEW_SCREEN_IMAGE); | |
| 229 #endif | |
| 230 source->AddLocalizedString("noscreenshot", | |
| 231 IDS_BUGREPORT_INCLUDE_NO_SCREENSHOT); | |
| 232 | |
| 233 source->AddLocalizedString("send-report", IDS_BUGREPORT_SEND_REPORT); | |
| 234 source->AddLocalizedString("cancel", IDS_CANCEL); | |
| 235 | |
| 236 // Option strings for the "issue with" drop-down. | |
| 237 source->AddLocalizedString("issue-choose", IDS_BUGREPORT_CHOOSE_ISSUE); | |
| 238 source->AddLocalizedString("no-issue-selected", | |
| 239 IDS_BUGREPORT_NO_ISSUE_SELECTED); | |
| 240 source->AddLocalizedString("no-description", IDS_BUGREPORT_NO_DESCRIPTION); | |
| 241 source->AddLocalizedString("no-saved-screenshots", | |
| 242 IDS_BUGREPORT_NO_SAVED_SCREENSHOTS_HELP); | |
| 243 source->AddLocalizedString("privacy-note", IDS_BUGREPORT_PRIVACY_NOTE); | |
| 244 | |
| 245 // TODO(rkc): Find some way to ensure this order of dropdowns is in sync | |
| 246 // with the order in the userfeedback ChromeData proto buffer | |
| 247 #if defined(OS_CHROMEOS) | |
| 248 // Dropdown for ChromeOS: | |
| 249 // | |
| 250 // Connectivity | |
| 251 // Sync | |
| 252 // Crash | |
| 253 // Page Formatting | |
| 254 // Extensions or Apps | |
| 255 // Standby or Resume | |
| 256 // Phishing Page | |
| 257 // General Feedback/Other | |
| 258 // Autofill (hidden by default) | |
| 259 | |
| 260 source->AddLocalizedString("issue-connectivity", IDS_BUGREPORT_CONNECTIVITY); | |
| 261 source->AddLocalizedString("issue-sync", IDS_BUGREPORT_SYNC); | |
| 262 source->AddLocalizedString("issue-crashes", IDS_BUGREPORT_CRASHES); | |
| 263 source->AddLocalizedString("issue-page-formatting", | |
| 264 IDS_BUGREPORT_PAGE_FORMATTING); | |
| 265 source->AddLocalizedString("issue-extensions", IDS_BUGREPORT_EXTENSIONS); | |
| 266 source->AddLocalizedString("issue-standby", IDS_BUGREPORT_STANDBY_RESUME); | |
| 267 source->AddLocalizedString("issue-phishing", IDS_BUGREPORT_PHISHING_PAGE); | |
| 268 source->AddLocalizedString("issue-other", IDS_BUGREPORT_GENERAL); | |
| 269 source->AddLocalizedString("issue-autofill", IDS_BUGREPORT_AUTOFILL); | |
| 270 #else | |
| 271 // Dropdown for Chrome: | |
| 272 // | |
| 273 // Page formatting or layout | |
| 274 // Pages not loading | |
| 275 // Plug-ins (e.g. Adobe Flash Player, Quicktime, etc) | |
| 276 // Tabs or windows | |
| 277 // Synced preferences | |
| 278 // Crashes | |
| 279 // Extensions or apps | |
| 280 // Phishing | |
| 281 // Other | |
| 282 // Autofill (hidden by default) | |
| 283 | |
| 284 source->AddLocalizedString("issue-page-formatting", | |
| 285 IDS_BUGREPORT_PAGE_FORMATTING); | |
| 286 source->AddLocalizedString("issue-page-load", IDS_BUGREPORT_PAGE_LOAD); | |
| 287 source->AddLocalizedString("issue-plugins", IDS_BUGREPORT_PLUGINS); | |
| 288 source->AddLocalizedString("issue-tabs", IDS_BUGREPORT_TABS); | |
| 289 source->AddLocalizedString("issue-sync", IDS_BUGREPORT_SYNC); | |
| 290 source->AddLocalizedString("issue-crashes", IDS_BUGREPORT_CRASHES); | |
| 291 source->AddLocalizedString("issue-extensions", IDS_BUGREPORT_EXTENSIONS); | |
| 292 source->AddLocalizedString("issue-phishing", IDS_BUGREPORT_PHISHING_PAGE); | |
| 293 source->AddLocalizedString("issue-other", IDS_BUGREPORT_OTHER); | |
| 294 source->AddLocalizedString("issue-autofill", IDS_BUGREPORT_AUTOFILL); | |
| 295 #endif | |
| 296 | |
| 297 source->set_json_path("strings.js"); | |
| 298 source->add_resource_path("bug_report.js", IDR_BUGREPORT_JS); | |
| 299 source->set_default_resource( | |
| 300 successful_init ? IDR_BUGREPORT_HTML : IDR_BUGREPORT_HTML_INVALID); | |
| 301 | |
| 302 return source; | |
| 303 } | |
| 304 | |
| 305 //////////////////////////////////////////////////////////////////////////////// | |
| 306 // | |
| 307 // BugReportHandler | |
| 308 // | |
| 309 //////////////////////////////////////////////////////////////////////////////// | |
| 310 BugReportHandler::BugReportHandler(TabContents* tab) | |
| 311 : tab_(tab), | |
| 312 screenshot_source_(NULL), | |
| 313 bug_report_data_(NULL) | |
| 314 #if defined(OS_CHROMEOS) | |
| 315 , syslogs_handle_(0) | |
| 316 #endif | |
| 317 { | |
| 318 } | |
| 319 | |
| 320 BugReportHandler::~BugReportHandler() { | |
| 321 // Just in case we didn't send off bug_report_data_ to SendReport | |
| 322 if (bug_report_data_) { | |
| 323 // If we're deleting the report object, cancel feedback collection first | |
| 324 CancelFeedbackCollection(); | |
| 325 delete bug_report_data_; | |
| 326 } | |
| 327 // Make sure we don't leave any screenshot data around. | |
| 328 BugReportUtil::ClearScreenshotPng(); | |
| 329 } | |
| 330 | |
| 331 void BugReportHandler::ClobberScreenshotsSource() { | |
| 332 // Re-create our screenshots data source (this clobbers the last source) | |
| 333 // setting the screenshot to NULL, effectively disabling the source | |
| 334 // TODO(rkc): Once there is a method to 'remove' a source, change this code | |
| 335 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); | |
| 336 profile->GetChromeURLDataManager()->AddDataSource(new ScreenshotSource(NULL)); | |
| 337 | |
| 338 BugReportUtil::ClearScreenshotPng(); | |
| 339 } | |
| 340 | |
| 341 void BugReportHandler::SetupScreenshotsSource() { | |
| 342 // If we don't already have a screenshot source object created, create one. | |
| 343 if (!screenshot_source_) { | |
| 344 screenshot_source_ = | |
| 345 new ScreenshotSource(BugReportUtil::GetScreenshotPng()); | |
| 346 } | |
| 347 // Add the source to the data manager. | |
| 348 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); | |
| 349 profile->GetChromeURLDataManager()->AddDataSource(screenshot_source_); | |
| 350 } | |
| 351 | |
| 352 WebUIMessageHandler* BugReportHandler::Attach(WebUI* web_ui) { | |
| 353 SetupScreenshotsSource(); | |
| 354 return WebUIMessageHandler::Attach(web_ui); | |
| 355 } | |
| 356 | |
| 357 bool BugReportHandler::Init() { | |
| 358 std::string page_url; | |
| 359 if (tab_->controller().GetActiveEntry()) { | |
| 360 page_url = tab_->controller().GetActiveEntry()->url().spec(); | |
| 361 } | |
| 362 | |
| 363 std::string params = page_url.substr(strlen(chrome::kChromeUIBugReportURL)); | |
| 364 // Erase the # - the first character. | |
| 365 if (params.length()) | |
| 366 params.erase(params.begin(), params.begin() + 1); | |
| 367 | |
| 368 size_t additional_params_pos = params.find('?'); | |
| 369 if (additional_params_pos != std::string::npos) | |
| 370 params.erase(params.begin() + additional_params_pos, params.end()); | |
| 371 | |
| 372 int index = 0; | |
| 373 if (!base::StringToInt(params, &index)) | |
| 374 return false; | |
| 375 | |
| 376 Browser* browser = BrowserList::GetLastActive(); | |
| 377 // Sanity checks. | |
| 378 if (((index == 0) && (params != "0")) || !browser || | |
| 379 index >= browser->tab_count()) { | |
| 380 return false; | |
| 381 } | |
| 382 | |
| 383 TabContents* target_tab = browser->GetTabContentsAt(index); | |
| 384 if (target_tab) { | |
| 385 target_tab_url_ = target_tab->GetURL().spec(); | |
| 386 } | |
| 387 | |
| 388 // Setup the screenshot source after we've verified input is legit. | |
| 389 SetupScreenshotsSource(); | |
| 390 | |
| 391 return true; | |
| 392 } | |
| 393 | |
| 394 void BugReportHandler::RegisterMessages() { | |
| 395 web_ui_->RegisterMessageCallback("getDialogDefaults", | |
| 396 base::Bind(&BugReportHandler::HandleGetDialogDefaults, | |
| 397 base::Unretained(this))); | |
| 398 web_ui_->RegisterMessageCallback("refreshCurrentScreenshot", | |
| 399 base::Bind(&BugReportHandler::HandleRefreshCurrentScreenshot, | |
| 400 base::Unretained(this))); | |
| 401 #if defined(OS_CHROMEOS) | |
| 402 web_ui_->RegisterMessageCallback("refreshSavedScreenshots", | |
| 403 base::Bind(&BugReportHandler::HandleRefreshSavedScreenshots, | |
| 404 base::Unretained(this))); | |
| 405 #endif | |
| 406 web_ui_->RegisterMessageCallback("sendReport", | |
| 407 base::Bind(&BugReportHandler::HandleSendReport, | |
| 408 base::Unretained(this))); | |
| 409 web_ui_->RegisterMessageCallback("cancel", | |
| 410 base::Bind(&BugReportHandler::HandleCancel, | |
| 411 base::Unretained(this))); | |
| 412 web_ui_->RegisterMessageCallback("openSystemTab", | |
| 413 base::Bind(&BugReportHandler::HandleOpenSystemTab, | |
| 414 base::Unretained(this))); | |
| 415 } | |
| 416 | |
| 417 void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { | |
| 418 // Will delete itself when bug_report_data_->SendReport() is called. | |
| 419 bug_report_data_ = new BugReportData(); | |
| 420 | |
| 421 // send back values which the dialog js needs initially | |
| 422 ListValue dialog_defaults; | |
| 423 | |
| 424 // 0: current url | |
| 425 if (target_tab_url_.length()) | |
| 426 dialog_defaults.Append(new StringValue(target_tab_url_)); | |
| 427 else | |
| 428 dialog_defaults.Append(new StringValue("")); | |
| 429 | |
| 430 #if defined(OS_CHROMEOS) | |
| 431 // 1: about:system | |
| 432 dialog_defaults.Append(new StringValue(chrome::kChromeUISystemInfoURL)); | |
| 433 // Trigger the request for system information here. | |
| 434 chromeos::system::SyslogsProvider* provider = | |
| 435 chromeos::system::SyslogsProvider::GetInstance(); | |
| 436 if (provider) { | |
| 437 syslogs_handle_ = provider->RequestSyslogs( | |
| 438 true, // don't compress. | |
| 439 chromeos::system::SyslogsProvider::SYSLOGS_FEEDBACK, | |
| 440 &syslogs_consumer_, | |
| 441 base::Bind(&BugReportData::SyslogsComplete, | |
| 442 base::Unretained(bug_report_data_))); | |
| 443 } | |
| 444 // 2: user e-mail | |
| 445 dialog_defaults.Append(new StringValue(GetUserEmail())); | |
| 446 #endif | |
| 447 | |
| 448 web_ui_->CallJavascriptFunction("setupDialogDefaults", dialog_defaults); | |
| 449 } | |
| 450 | |
| 451 void BugReportHandler::HandleRefreshCurrentScreenshot(const ListValue*) { | |
| 452 std::string current_screenshot(kCurrentScreenshotUrl); | |
| 453 StringValue screenshot(current_screenshot); | |
| 454 web_ui_->CallJavascriptFunction("setupCurrentScreenshot", screenshot); | |
| 455 } | |
| 456 | |
| 457 | |
| 458 #if defined(OS_CHROMEOS) | |
| 459 void BugReportHandler::HandleRefreshSavedScreenshots(const ListValue*) { | |
| 460 std::vector<std::string> saved_screenshots; | |
| 461 GetScreenshotUrls(&saved_screenshots); | |
| 462 | |
| 463 ListValue screenshots_list; | |
| 464 for (size_t i = 0; i < saved_screenshots.size(); ++i) | |
| 465 screenshots_list.Append(new StringValue(saved_screenshots[i])); | |
| 466 web_ui_->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); | |
| 467 } | |
| 468 #endif | |
| 469 | |
| 470 | |
| 471 void BugReportHandler::HandleSendReport(const ListValue* list_value) { | |
| 472 if (!bug_report_data_) { | |
| 473 LOG(ERROR) << "Bug report hasn't been intialized yet."; | |
| 474 return; | |
| 475 } | |
| 476 | |
| 477 ListValue::const_iterator i = list_value->begin(); | |
| 478 if (i == list_value->end()) { | |
| 479 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 480 return; | |
| 481 } | |
| 482 | |
| 483 // #0 - Problem type. | |
| 484 int problem_type; | |
| 485 std::string problem_type_str; | |
| 486 (*i)->GetAsString(&problem_type_str); | |
| 487 if (!base::StringToInt(problem_type_str, &problem_type)) { | |
| 488 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 489 return; | |
| 490 } | |
| 491 if (++i == list_value->end()) { | |
| 492 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 493 return; | |
| 494 } | |
| 495 | |
| 496 // #1 - Page url. | |
| 497 std::string page_url; | |
| 498 (*i)->GetAsString(&page_url); | |
| 499 if (++i == list_value->end()) { | |
| 500 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 501 return; | |
| 502 } | |
| 503 | |
| 504 // #2 - Description. | |
| 505 std::string description; | |
| 506 (*i)->GetAsString(&description); | |
| 507 if (++i == list_value->end()) { | |
| 508 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 509 return; | |
| 510 } | |
| 511 | |
| 512 // #3 - Screenshot to send. | |
| 513 std::string screenshot_path; | |
| 514 (*i)->GetAsString(&screenshot_path); | |
| 515 screenshot_path.erase(0, strlen(kScreenshotBaseUrl)); | |
| 516 | |
| 517 // Get the image to send in the report. | |
| 518 ScreenshotDataPtr image_ptr; | |
| 519 if (!screenshot_path.empty()) | |
| 520 image_ptr = screenshot_source_->GetCachedScreenshot(screenshot_path); | |
| 521 | |
| 522 #if defined(OS_CHROMEOS) | |
| 523 if (++i == list_value->end()) { | |
| 524 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 525 return; | |
| 526 } | |
| 527 | |
| 528 // #4 - User e-mail | |
| 529 std::string user_email; | |
| 530 (*i)->GetAsString(&user_email); | |
| 531 if (++i == list_value->end()) { | |
| 532 LOG(ERROR) << "Incorrect data passed to sendReport."; | |
| 533 return; | |
| 534 } | |
| 535 | |
| 536 // #5 - System info checkbox. | |
| 537 std::string sys_info_checkbox; | |
| 538 (*i)->GetAsString(&sys_info_checkbox); | |
| 539 bool send_sys_info = (sys_info_checkbox == "true"); | |
| 540 | |
| 541 // If we aren't sending the sys_info, cancel the gathering of the syslogs. | |
| 542 if (!send_sys_info) | |
| 543 CancelFeedbackCollection(); | |
| 544 #endif | |
| 545 | |
| 546 // Update the data in bug_report_data_ so it can be sent | |
| 547 bug_report_data_->UpdateData(Profile::FromWebUI(web_ui_) | |
| 548 , target_tab_url_ | |
| 549 , problem_type | |
| 550 , page_url | |
| 551 , description | |
| 552 , image_ptr | |
| 553 #if defined(OS_CHROMEOS) | |
| 554 , user_email | |
| 555 , send_sys_info | |
| 556 , false // sent_report | |
| 557 #endif | |
| 558 ); | |
| 559 | |
| 560 #if defined(OS_CHROMEOS) | |
| 561 // If we don't require sys_info, or we have it, or we never requested it | |
| 562 // (because libcros failed to load), then send the report now. | |
| 563 // Otherwise, the report will get sent when we receive sys_info. | |
| 564 if (!send_sys_info || bug_report_data_->sys_info() != NULL || | |
| 565 syslogs_handle_ == 0) { | |
| 566 bug_report_data_->SendReport(); | |
| 567 } | |
| 568 #else | |
| 569 bug_report_data_->SendReport(); | |
| 570 #endif | |
| 571 // Lose the pointer to the BugReportData object; the object will delete itself | |
| 572 // from SendReport, whether we called it, or will be called by the log | |
| 573 // completion routine. | |
| 574 bug_report_data_ = NULL; | |
| 575 | |
| 576 // Whether we sent the report, or if it will be sent by the Syslogs complete | |
| 577 // function, close our feedback tab anyway, we have no more use for it. | |
| 578 CloseFeedbackTab(); | |
| 579 } | |
| 580 | |
| 581 void BugReportHandler::HandleCancel(const ListValue*) { | |
| 582 CloseFeedbackTab(); | |
| 583 } | |
| 584 | |
| 585 void BugReportHandler::HandleOpenSystemTab(const ListValue* args) { | |
| 586 #if defined(OS_CHROMEOS) | |
| 587 BrowserList::GetLastActive()->OpenSystemTabAndActivate(); | |
| 588 #endif | |
| 589 } | |
| 590 | |
| 591 void BugReportHandler::CancelFeedbackCollection() { | |
| 592 #if defined(OS_CHROMEOS) | |
| 593 if (syslogs_handle_ != 0) { | |
| 594 chromeos::system::SyslogsProvider* provider = | |
| 595 chromeos::system::SyslogsProvider::GetInstance(); | |
| 596 if (provider) | |
| 597 provider->CancelRequest(syslogs_handle_); | |
| 598 } | |
| 599 #endif | |
| 600 } | |
| 601 | |
| 602 void BugReportHandler::CloseFeedbackTab() { | |
| 603 ClobberScreenshotsSource(); | |
| 604 | |
| 605 Browser* browser = BrowserList::GetLastActive(); | |
| 606 if (browser) { | |
| 607 browser->CloseTabContents(tab_); | |
| 608 } else { | |
| 609 LOG(FATAL) << "Failed to get last active browser."; | |
| 610 } | |
| 611 } | |
| 612 | |
| 613 //////////////////////////////////////////////////////////////////////////////// | |
| 614 // | |
| 615 // BugReportUI | |
| 616 // | |
| 617 //////////////////////////////////////////////////////////////////////////////// | |
| 618 BugReportUI::BugReportUI(TabContents* tab) : HtmlDialogUI(tab) { | |
| 619 BugReportHandler* handler = new BugReportHandler(tab); | |
| 620 AddMessageHandler((handler)->Attach(this)); | |
| 621 | |
| 622 // The handler's init will determine whether we show the error html page. | |
| 623 ChromeWebUIDataSource* html_source = | |
| 624 CreateBugReportUIHTMLSource(handler->Init()); | |
| 625 | |
| 626 // Set up the chrome://bugreport/ source. | |
| 627 Profile* profile = Profile::FromBrowserContext(tab->browser_context()); | |
| 628 profile->GetChromeURLDataManager()->AddDataSource(html_source); | |
| 629 } | |
| OLD | NEW |