OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/bug_report_ui.h" | 5 #include "chrome/browser/ui/webui/bug_report_ui.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 } | 120 } |
121 | 121 |
122 return -1; | 122 return -1; |
123 } | 123 } |
124 | 124 |
125 } // namespace | 125 } // namespace |
126 | 126 |
127 | 127 |
128 namespace browser { | 128 namespace browser { |
129 | 129 |
130 // TODO(rkc): Eventually find a better way to do this | |
131 std::vector<unsigned char>* last_screenshot_png = 0; | |
132 gfx::Rect screen_size; | |
133 | |
134 void RefreshLastScreenshot(Browser* browser) { | |
135 if (last_screenshot_png) | |
136 last_screenshot_png->clear(); | |
137 else | |
138 last_screenshot_png = new std::vector<unsigned char>; | |
139 | |
140 gfx::NativeWindow native_window = browser->window()->GetNativeHandle(); | |
141 screen_size = browser::GrabWindowSnapshot(native_window, last_screenshot_png); | |
142 } | |
143 | |
144 void ShowHtmlBugReportView(Browser* browser, | 130 void ShowHtmlBugReportView(Browser* browser, |
145 const std::string& description_template, | 131 const std::string& description_template, |
146 size_t issue_type) { | 132 size_t issue_type) { |
147 // First check if we're already open (we cannot depend on ShowSingletonTab | 133 // First check if we're already open (we cannot depend on ShowSingletonTab |
148 // for this functionality since we need to make *sure* we never get | 134 // for this functionality since we need to make *sure* we never get |
149 // instantiated again while we are open - with singleton tabs, that can | 135 // instantiated again while we are open - with singleton tabs, that can |
150 // happen) | 136 // happen) |
151 int feedback_tab_index = GetIndexOfFeedbackTab(browser); | 137 int feedback_tab_index = GetIndexOfFeedbackTab(browser); |
152 if (feedback_tab_index >= 0) { | 138 if (feedback_tab_index >= 0) { |
153 // Do not refresh screenshot, do not create a new tab | 139 // Do not refresh screenshot, do not create a new tab |
154 browser->ActivateTabAt(feedback_tab_index, true); | 140 browser->ActivateTabAt(feedback_tab_index, true); |
155 return; | 141 return; |
156 } | 142 } |
157 | 143 |
158 RefreshLastScreenshot(browser); | 144 std::vector<unsigned char>* last_screenshot_png = |
| 145 BugReportUtil::GetScreenshotPng(); |
| 146 last_screenshot_png->clear(); |
| 147 |
| 148 gfx::NativeWindow native_window = browser->window()->GetNativeHandle(); |
| 149 BugReportUtil::SetScreenshotSize( |
| 150 browser::GrabWindowSnapshot(native_window, last_screenshot_png)); |
| 151 |
159 std::string bug_report_url = std::string(chrome::kChromeUIBugReportURL) + | 152 std::string bug_report_url = std::string(chrome::kChromeUIBugReportURL) + |
160 "#" + base::IntToString(browser->active_index()) + | 153 "#" + base::IntToString(browser->active_index()) + |
161 "?description=" + EscapeUrlEncodedData(description_template, false) + | 154 "?description=" + EscapeUrlEncodedData(description_template, false) + |
162 "&issueType=" + base::IntToString(issue_type); | 155 "&issueType=" + base::IntToString(issue_type); |
163 browser->ShowSingletonTab(GURL(bug_report_url)); | 156 browser->ShowSingletonTab(GURL(bug_report_url)); |
164 } | 157 } |
165 | 158 |
166 } // namespace browser | 159 } // namespace browser |
167 | 160 |
168 | 161 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 | 205 |
213 void SetupScreenshotsSource(); | 206 void SetupScreenshotsSource(); |
214 void ClobberScreenshotsSource(); | 207 void ClobberScreenshotsSource(); |
215 | 208 |
216 void CancelFeedbackCollection(); | 209 void CancelFeedbackCollection(); |
217 void CloseFeedbackTab(); | 210 void CloseFeedbackTab(); |
218 | 211 |
219 TabContents* tab_; | 212 TabContents* tab_; |
220 ScreenshotSource* screenshot_source_; | 213 ScreenshotSource* screenshot_source_; |
221 | 214 |
222 BugReportData* bug_report_; | 215 BugReportData* bug_report_data_; |
223 std::string target_tab_url_; | 216 std::string target_tab_url_; |
224 #if defined(OS_CHROMEOS) | 217 #if defined(OS_CHROMEOS) |
225 // Variables to track SyslogsProvider::RequestSyslogs callback. | 218 // Variables to track SyslogsProvider::RequestSyslogs callback. |
226 chromeos::system::SyslogsProvider::Handle syslogs_handle_; | 219 chromeos::system::SyslogsProvider::Handle syslogs_handle_; |
227 CancelableRequestConsumer syslogs_consumer_; | 220 CancelableRequestConsumer syslogs_consumer_; |
228 #endif | 221 #endif |
229 | 222 |
230 DISALLOW_COPY_AND_ASSIGN(BugReportHandler); | 223 DISALLOW_COPY_AND_ASSIGN(BugReportHandler); |
231 }; | 224 }; |
232 | 225 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 | 372 |
380 std::string full_html = jstemplate_builder::GetI18nTemplateHtml( | 373 std::string full_html = jstemplate_builder::GetI18nTemplateHtml( |
381 bug_report_html_, &localized_strings); | 374 bug_report_html_, &localized_strings); |
382 | 375 |
383 SendResponse(request_id, base::RefCountedString::TakeString(&full_html)); | 376 SendResponse(request_id, base::RefCountedString::TakeString(&full_html)); |
384 } | 377 } |
385 | 378 |
386 | 379 |
387 //////////////////////////////////////////////////////////////////////////////// | 380 //////////////////////////////////////////////////////////////////////////////// |
388 // | 381 // |
389 // BugReportData | |
390 // | |
391 //////////////////////////////////////////////////////////////////////////////// | |
392 void BugReportData::SendReport() { | |
393 #if defined(OS_CHROMEOS) | |
394 // In case we already got the syslogs and sent the report, leave | |
395 if (sent_report_) return; | |
396 // Set send_report_ so that no one else processes SendReport | |
397 sent_report_ = true; | |
398 #endif | |
399 | |
400 int image_data_size = image_.size(); | |
401 char* image_data = image_data_size ? | |
402 reinterpret_cast<char*>(&(image_.front())) : NULL; | |
403 BugReportUtil::SendReport(profile_ | |
404 , problem_type_ | |
405 , page_url_ | |
406 , description_ | |
407 , image_data | |
408 , image_data_size | |
409 , browser::screen_size.width() | |
410 , browser::screen_size.height() | |
411 #if defined(OS_CHROMEOS) | |
412 , user_email_ | |
413 , zip_content_ ? zip_content_->c_str() : NULL | |
414 , zip_content_ ? zip_content_->length() : 0 | |
415 , send_sys_info_ ? sys_info_ : NULL | |
416 #endif | |
417 ); | |
418 | |
419 #if defined(OS_CHROMEOS) | |
420 if (sys_info_) { | |
421 delete sys_info_; | |
422 sys_info_ = NULL; | |
423 } | |
424 if (zip_content_) { | |
425 delete zip_content_; | |
426 zip_content_ = NULL; | |
427 } | |
428 #endif | |
429 | |
430 // Once the report has been sent, this object has no purpose in life, delete | |
431 // ourselves. | |
432 delete this; | |
433 } | |
434 | |
435 | |
436 //////////////////////////////////////////////////////////////////////////////// | |
437 // | |
438 // BugReportHandler | 382 // BugReportHandler |
439 // | 383 // |
440 //////////////////////////////////////////////////////////////////////////////// | 384 //////////////////////////////////////////////////////////////////////////////// |
441 BugReportHandler::BugReportHandler(TabContents* tab) | 385 BugReportHandler::BugReportHandler(TabContents* tab) |
442 : tab_(tab), | 386 : tab_(tab), |
443 screenshot_source_(NULL), | 387 screenshot_source_(NULL), |
444 bug_report_(NULL) | 388 bug_report_data_(NULL) |
445 #if defined(OS_CHROMEOS) | 389 #if defined(OS_CHROMEOS) |
446 , syslogs_handle_(0) | 390 , syslogs_handle_(0) |
447 #endif | 391 #endif |
448 { | 392 { |
449 } | 393 } |
450 | 394 |
451 BugReportHandler::~BugReportHandler() { | 395 BugReportHandler::~BugReportHandler() { |
452 // Just in case we didn't send off bug_report_ to SendReport | 396 // Just in case we didn't send off bug_report_data_ to SendReport |
453 if (bug_report_) { | 397 if (bug_report_data_) { |
454 // If we're deleting the report object, cancel feedback collection first | 398 // If we're deleting the report object, cancel feedback collection first |
455 CancelFeedbackCollection(); | 399 CancelFeedbackCollection(); |
456 delete bug_report_; | 400 delete bug_report_data_; |
457 } | 401 } |
| 402 // Make sure we don't leave any screenshot data around. |
| 403 BugReportUtil::ClearScreenshotPng(); |
458 } | 404 } |
459 | 405 |
460 void BugReportHandler::ClobberScreenshotsSource() { | 406 void BugReportHandler::ClobberScreenshotsSource() { |
461 // Re-create our screenshots data source (this clobbers the last source) | 407 // Re-create our screenshots data source (this clobbers the last source) |
462 // setting the screenshot to NULL, effectively disabling the source | 408 // setting the screenshot to NULL, effectively disabling the source |
463 // TODO(rkc): Once there is a method to 'remove' a source, change this code | 409 // TODO(rkc): Once there is a method to 'remove' a source, change this code |
464 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); | 410 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); |
465 profile->GetChromeURLDataManager()->AddDataSource(new ScreenshotSource(NULL)); | 411 profile->GetChromeURLDataManager()->AddDataSource(new ScreenshotSource(NULL)); |
466 | 412 |
467 // clobber last screenshot | 413 BugReportUtil::ClearScreenshotPng(); |
468 if (browser::last_screenshot_png) | |
469 browser::last_screenshot_png->clear(); | |
470 } | 414 } |
471 | 415 |
472 void BugReportHandler::SetupScreenshotsSource() { | 416 void BugReportHandler::SetupScreenshotsSource() { |
473 // If we don't already have a screenshot source object created, create one. | 417 // If we don't already have a screenshot source object created, create one. |
474 if (!screenshot_source_) | 418 if (!screenshot_source_) { |
475 screenshot_source_ = new ScreenshotSource(browser::last_screenshot_png); | 419 screenshot_source_ = |
476 | 420 new ScreenshotSource(BugReportUtil::GetScreenshotPng()); |
| 421 } |
477 // Add the source to the data manager. | 422 // Add the source to the data manager. |
478 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); | 423 Profile* profile = Profile::FromBrowserContext(tab_->browser_context()); |
479 profile->GetChromeURLDataManager()->AddDataSource(screenshot_source_); | 424 profile->GetChromeURLDataManager()->AddDataSource(screenshot_source_); |
480 } | 425 } |
481 | 426 |
482 WebUIMessageHandler* BugReportHandler::Attach(WebUI* web_ui) { | 427 WebUIMessageHandler* BugReportHandler::Attach(WebUI* web_ui) { |
483 SetupScreenshotsSource(); | 428 SetupScreenshotsSource(); |
484 return WebUIMessageHandler::Attach(web_ui); | 429 return WebUIMessageHandler::Attach(web_ui); |
485 } | 430 } |
486 | 431 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 #endif | 484 #endif |
540 web_ui_->RegisterMessageCallback("sendReport", | 485 web_ui_->RegisterMessageCallback("sendReport", |
541 NewCallback(this, &BugReportHandler::HandleSendReport)); | 486 NewCallback(this, &BugReportHandler::HandleSendReport)); |
542 web_ui_->RegisterMessageCallback("cancel", | 487 web_ui_->RegisterMessageCallback("cancel", |
543 NewCallback(this, &BugReportHandler::HandleCancel)); | 488 NewCallback(this, &BugReportHandler::HandleCancel)); |
544 web_ui_->RegisterMessageCallback("openSystemTab", | 489 web_ui_->RegisterMessageCallback("openSystemTab", |
545 NewCallback(this, &BugReportHandler::HandleOpenSystemTab)); | 490 NewCallback(this, &BugReportHandler::HandleOpenSystemTab)); |
546 } | 491 } |
547 | 492 |
548 void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { | 493 void BugReportHandler::HandleGetDialogDefaults(const ListValue*) { |
549 bug_report_ = new BugReportData(); | 494 // Will delete itself when bug_report_data_->SendReport() is called. |
| 495 bug_report_data_ = new BugReportData(); |
550 | 496 |
551 // send back values which the dialog js needs initially | 497 // send back values which the dialog js needs initially |
552 ListValue dialog_defaults; | 498 ListValue dialog_defaults; |
553 | 499 |
554 // 0: current url | 500 // 0: current url |
555 if (target_tab_url_.length()) | 501 if (target_tab_url_.length()) |
556 dialog_defaults.Append(new StringValue(target_tab_url_)); | 502 dialog_defaults.Append(new StringValue(target_tab_url_)); |
557 else | 503 else |
558 dialog_defaults.Append(new StringValue("")); | 504 dialog_defaults.Append(new StringValue("")); |
559 | 505 |
560 #if defined(OS_CHROMEOS) | 506 #if defined(OS_CHROMEOS) |
561 // 1: about:system | 507 // 1: about:system |
562 dialog_defaults.Append(new StringValue(chrome::kChromeUISystemInfoURL)); | 508 dialog_defaults.Append(new StringValue(chrome::kChromeUISystemInfoURL)); |
563 // Trigger the request for system information here. | 509 // Trigger the request for system information here. |
564 chromeos::system::SyslogsProvider* provider = | 510 chromeos::system::SyslogsProvider* provider = |
565 chromeos::system::SyslogsProvider::GetInstance(); | 511 chromeos::system::SyslogsProvider::GetInstance(); |
566 if (provider) { | 512 if (provider) { |
567 syslogs_handle_ = provider->RequestSyslogs( | 513 syslogs_handle_ = provider->RequestSyslogs( |
568 true, // don't compress. | 514 true, // don't compress. |
569 chromeos::system::SyslogsProvider::SYSLOGS_FEEDBACK, | 515 chromeos::system::SyslogsProvider::SYSLOGS_FEEDBACK, |
570 &syslogs_consumer_, | 516 &syslogs_consumer_, |
571 NewCallback(bug_report_, &BugReportData::SyslogsComplete)); | 517 NewCallback(bug_report_data_, &BugReportData::SyslogsComplete)); |
572 } | 518 } |
573 // 2: user e-mail | 519 // 2: user e-mail |
574 dialog_defaults.Append(new StringValue(GetUserEmail())); | 520 dialog_defaults.Append(new StringValue(GetUserEmail())); |
575 #endif | 521 #endif |
576 | 522 |
577 web_ui_->CallJavascriptFunction("setupDialogDefaults", dialog_defaults); | 523 web_ui_->CallJavascriptFunction("setupDialogDefaults", dialog_defaults); |
578 } | 524 } |
579 | 525 |
580 void BugReportHandler::HandleRefreshCurrentScreenshot(const ListValue*) { | 526 void BugReportHandler::HandleRefreshCurrentScreenshot(const ListValue*) { |
581 std::string current_screenshot(kCurrentScreenshotUrl); | 527 std::string current_screenshot(kCurrentScreenshotUrl); |
582 StringValue screenshot(current_screenshot); | 528 StringValue screenshot(current_screenshot); |
583 web_ui_->CallJavascriptFunction("setupCurrentScreenshot", screenshot); | 529 web_ui_->CallJavascriptFunction("setupCurrentScreenshot", screenshot); |
584 } | 530 } |
585 | 531 |
586 | 532 |
587 #if defined(OS_CHROMEOS) | 533 #if defined(OS_CHROMEOS) |
588 void BugReportHandler::HandleRefreshSavedScreenshots(const ListValue*) { | 534 void BugReportHandler::HandleRefreshSavedScreenshots(const ListValue*) { |
589 std::vector<std::string> saved_screenshots; | 535 std::vector<std::string> saved_screenshots; |
590 GetScreenshotUrls(&saved_screenshots); | 536 GetScreenshotUrls(&saved_screenshots); |
591 | 537 |
592 ListValue screenshots_list; | 538 ListValue screenshots_list; |
593 for (size_t i = 0; i < saved_screenshots.size(); ++i) | 539 for (size_t i = 0; i < saved_screenshots.size(); ++i) |
594 screenshots_list.Append(new StringValue(saved_screenshots[i])); | 540 screenshots_list.Append(new StringValue(saved_screenshots[i])); |
595 web_ui_->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); | 541 web_ui_->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); |
596 } | 542 } |
597 #endif | 543 #endif |
598 | 544 |
599 | 545 |
600 void BugReportHandler::HandleSendReport(const ListValue* list_value) { | 546 void BugReportHandler::HandleSendReport(const ListValue* list_value) { |
601 if (!bug_report_) { | 547 if (!bug_report_data_) { |
602 LOG(ERROR) << "Bug report hasn't been intialized yet."; | 548 LOG(ERROR) << "Bug report hasn't been intialized yet."; |
603 return; | 549 return; |
604 } | 550 } |
605 | 551 |
606 ListValue::const_iterator i = list_value->begin(); | 552 ListValue::const_iterator i = list_value->begin(); |
607 if (i == list_value->end()) { | 553 if (i == list_value->end()) { |
608 LOG(ERROR) << "Incorrect data passed to sendReport."; | 554 LOG(ERROR) << "Incorrect data passed to sendReport."; |
609 return; | 555 return; |
610 } | 556 } |
611 | 557 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 // #5 - System info checkbox. | 611 // #5 - System info checkbox. |
666 std::string sys_info_checkbox; | 612 std::string sys_info_checkbox; |
667 (*i)->GetAsString(&sys_info_checkbox); | 613 (*i)->GetAsString(&sys_info_checkbox); |
668 bool send_sys_info = (sys_info_checkbox == "true"); | 614 bool send_sys_info = (sys_info_checkbox == "true"); |
669 | 615 |
670 // If we aren't sending the sys_info, cancel the gathering of the syslogs. | 616 // If we aren't sending the sys_info, cancel the gathering of the syslogs. |
671 if (!send_sys_info) | 617 if (!send_sys_info) |
672 CancelFeedbackCollection(); | 618 CancelFeedbackCollection(); |
673 #endif | 619 #endif |
674 | 620 |
675 // Update the data in bug_report_ so it can be sent | 621 // Update the data in bug_report_data_ so it can be sent |
676 bug_report_->UpdateData(web_ui_->GetProfile() | 622 bug_report_data_->UpdateData(web_ui_->GetProfile() |
677 , target_tab_url_ | 623 , target_tab_url_ |
678 , problem_type | 624 , problem_type |
679 , page_url | 625 , page_url |
680 , description | 626 , description |
681 , image | 627 , image |
682 #if defined(OS_CHROMEOS) | 628 #if defined(OS_CHROMEOS) |
683 , user_email | 629 , user_email |
684 , send_sys_info | 630 , send_sys_info |
685 , false // sent_report | 631 , false // sent_report |
686 #endif | 632 #endif |
687 ); | 633 ); |
688 | 634 |
689 #if defined(OS_CHROMEOS) | 635 #if defined(OS_CHROMEOS) |
690 // If we don't require sys_info, or we have it, or we never requested it | 636 // If we don't require sys_info, or we have it, or we never requested it |
691 // (because libcros failed to load), then send the report now. | 637 // (because libcros failed to load), then send the report now. |
692 // Otherwise, the report will get sent when we receive sys_info. | 638 // Otherwise, the report will get sent when we receive sys_info. |
693 if (!send_sys_info || bug_report_->sys_info() != NULL || | 639 if (!send_sys_info || bug_report_data_->sys_info() != NULL || |
694 syslogs_handle_ == 0) { | 640 syslogs_handle_ == 0) { |
695 bug_report_->SendReport(); | 641 bug_report_data_->SendReport(); |
696 } | 642 } |
697 #else | 643 #else |
698 bug_report_->SendReport(); | 644 bug_report_data_->SendReport(); |
699 #endif | 645 #endif |
700 // Lose the pointer to the BugReportData object; the object will delete itself | 646 // Lose the pointer to the BugReportData object; the object will delete itself |
701 // from SendReport, whether we called it, or will be called by the log | 647 // from SendReport, whether we called it, or will be called by the log |
702 // completion routine. | 648 // completion routine. |
703 bug_report_ = NULL; | 649 bug_report_data_ = NULL; |
704 | 650 |
705 // Whether we sent the report, or if it will be sent by the Syslogs complete | 651 // Whether we sent the report, or if it will be sent by the Syslogs complete |
706 // function, close our feedback tab anyway, we have no more use for it. | 652 // function, close our feedback tab anyway, we have no more use for it. |
707 CloseFeedbackTab(); | 653 CloseFeedbackTab(); |
708 } | 654 } |
709 | 655 |
710 void BugReportHandler::HandleCancel(const ListValue*) { | 656 void BugReportHandler::HandleCancel(const ListValue*) { |
711 CloseFeedbackTab(); | 657 CloseFeedbackTab(); |
712 } | 658 } |
713 | 659 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 AddMessageHandler((handler)->Attach(this)); | 695 AddMessageHandler((handler)->Attach(this)); |
750 | 696 |
751 // The handler's init will specify which html | 697 // The handler's init will specify which html |
752 // resource we'll display to the user | 698 // resource we'll display to the user |
753 BugReportUIHTMLSource* html_source = | 699 BugReportUIHTMLSource* html_source = |
754 new BugReportUIHTMLSource(handler->Init()); | 700 new BugReportUIHTMLSource(handler->Init()); |
755 // Set up the chrome://bugreport/ source. | 701 // Set up the chrome://bugreport/ source. |
756 Profile* profile = Profile::FromBrowserContext(tab->browser_context()); | 702 Profile* profile = Profile::FromBrowserContext(tab->browser_context()); |
757 profile->GetChromeURLDataManager()->AddDataSource(html_source); | 703 profile->GetChromeURLDataManager()->AddDataSource(html_source); |
758 } | 704 } |
OLD | NEW |