| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/feedback_ui.h" | 5 #include "chrome/browser/ui/webui/feedback_ui.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <vector> | 8 #include <vector> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
| 15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 16 #include "base/time.h" | 17 #include "base/time.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 #include "grit/locale_settings.h" | 52 #include "grit/locale_settings.h" |
| 52 #include "net/base/escape.h" | 53 #include "net/base/escape.h" |
| 53 #include "ui/base/resource/resource_bundle.h" | 54 #include "ui/base/resource/resource_bundle.h" |
| 54 | 55 |
| 55 #if defined(OS_CHROMEOS) | 56 #if defined(OS_CHROMEOS) |
| 56 #include "ash/shell.h" | 57 #include "ash/shell.h" |
| 57 #include "ash/shell_delegate.h" | 58 #include "ash/shell_delegate.h" |
| 58 #include "base/file_util.h" | 59 #include "base/file_util.h" |
| 59 #include "base/path_service.h" | 60 #include "base/path_service.h" |
| 60 #include "chrome/browser/chromeos/cros/cros_library.h" | 61 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 62 #include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h" |
| 63 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| 64 #include "chrome/browser/chromeos/gdata/gdata_system_service.h" |
| 65 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| 61 #include "chrome/browser/chromeos/login/user_manager.h" | 66 #include "chrome/browser/chromeos/login/user_manager.h" |
| 62 #include "chrome/browser/chromeos/system/syslogs_provider.h" | 67 #include "chrome/browser/chromeos/system/syslogs_provider.h" |
| 63 #include "ui/aura/root_window.h" | 68 #include "ui/aura/root_window.h" |
| 64 #include "ui/aura/window.h" | 69 #include "ui/aura/window.h" |
| 65 #endif | 70 #endif |
| 66 | 71 |
| 67 using content::BrowserThread; | 72 using content::BrowserThread; |
| 68 using content::WebContents; | 73 using content::WebContents; |
| 69 using content::WebUIMessageHandler; | 74 using content::WebUIMessageHandler; |
| 70 using ui::WebDialogUI; | 75 using ui::WebDialogUI; |
| 71 | 76 |
| 72 namespace { | 77 namespace { |
| 73 | 78 |
| 74 const char kScreenshotBaseUrl[] = "chrome://screenshots/"; | 79 const char kScreenshotBaseUrl[] = "chrome://screenshots/"; |
| 75 const char kCurrentScreenshotUrl[] = "chrome://screenshots/current"; | 80 const char kCurrentScreenshotUrl[] = "chrome://screenshots/current"; |
| 76 | 81 |
| 77 const char kCategoryTagParameter[] = "categoryTag="; | 82 const char kCategoryTagParameter[] = "categoryTag="; |
| 78 const char kDescriptionParameter[] = "description="; | 83 const char kDescriptionParameter[] = "description="; |
| 79 const char kSessionIDParameter[] = "session_id="; | 84 const char kSessionIDParameter[] = "session_id="; |
| 80 const char kTabIndexParameter[] = "tab_index="; | 85 const char kTabIndexParameter[] = "tab_index="; |
| 81 const char kCustomPageUrlParameter[] = "customPageUrl="; | 86 const char kCustomPageUrlParameter[] = "customPageUrl="; |
| 82 | 87 |
| 83 #if defined(OS_CHROMEOS) | 88 #if defined(OS_CHROMEOS) |
| 84 const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/"; | 89 const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/"; |
| 85 const char kScreenshotPattern[] = "Screenshot *.png"; | 90 const char kScreenshotPrefix[] = "Screenshot "; |
| 91 const char kScreenshotSuffix[] = ".png"; |
| 86 | 92 |
| 87 const char kTimestampParameter[] = "timestamp="; | 93 const char kTimestampParameter[] = "timestamp="; |
| 88 | 94 |
| 89 const size_t kMaxSavedScreenshots = 2; | 95 const size_t kMaxSavedScreenshots = 2; |
| 90 #endif | 96 #endif |
| 91 | 97 |
| 92 #if defined(OS_CHROMEOS) | 98 #if defined(OS_CHROMEOS) |
| 99 size_t kMaxNumScanFiles = 1000; |
| 93 | 100 |
| 94 // Compare two screenshot filepaths, which include the screenshot timestamp | 101 // Compare two screenshot filepaths, which include the screenshot timestamp |
| 95 // in the format of screenshot-yyyymmdd-hhmmss.png. Return true if |filepath1| | 102 // in the format of screenshot-yyyymmdd-hhmmss.png. Return true if |filepath1| |
| 96 // is more recent |filepath2|. | 103 // is more recent |filepath2|. |
| 97 bool ScreenshotTimestampComp(const std::string& filepath1, | 104 bool ScreenshotTimestampComp(const std::string& filepath1, |
| 98 const std::string& filepath2) { | 105 const std::string& filepath2) { |
| 99 return filepath1 > filepath2; | 106 return filepath1 > filepath2; |
| 100 } | 107 } |
| 101 | 108 |
| 102 void GetSavedScreenshots(std::vector<std::string>* saved_screenshots) { | |
| 103 saved_screenshots->clear(); | |
| 104 | |
| 105 DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext( | |
| 106 ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext()); | |
| 107 FeedbackUI::GetMostRecentScreenshots( | |
| 108 download_prefs->DownloadPath(), | |
| 109 saved_screenshots, | |
| 110 kMaxSavedScreenshots); | |
| 111 } | |
| 112 | |
| 113 std::string GetUserEmail() { | 109 std::string GetUserEmail() { |
| 114 chromeos::UserManager* manager = chromeos::UserManager::Get(); | 110 chromeos::UserManager* manager = chromeos::UserManager::Get(); |
| 115 if (!manager) | 111 if (!manager) |
| 116 return std::string(); | 112 return std::string(); |
| 117 else | 113 else |
| 118 return manager->GetLoggedInUser().display_email(); | 114 return manager->GetLoggedInUser().display_email(); |
| 119 } | 115 } |
| 120 | 116 |
| 117 bool ScreenshotGDataTimestampComp(const gdata::GDataEntryProto& entry1, |
| 118 const gdata::GDataEntryProto& entry2) { |
| 119 return entry1.file_info().last_modified() > |
| 120 entry2.file_info().last_modified(); |
| 121 } |
| 122 |
| 123 void ReadDirectoryCallback(size_t max_saved, |
| 124 std::vector<std::string>* saved_screenshots, |
| 125 base::Closure callback, |
| 126 gdata::GDataFileError error, |
| 127 bool hide_hosted_documents, |
| 128 scoped_ptr<gdata::GDataEntryProtoVector> entries) { |
| 129 if (error != gdata::GDATA_FILE_OK) { |
| 130 callback.Run(); |
| 131 return; |
| 132 } |
| 133 |
| 134 size_t max_scan = std::min(kMaxNumScanFiles, entries->size()); |
| 135 std::vector<gdata::GDataEntryProto> screenshot_entries; |
| 136 for (size_t i = 0; i < max_scan; ++i) { |
| 137 const gdata::GDataEntryProto& entry = (*entries)[i]; |
| 138 if (StartsWithASCII(entry.base_name(), kScreenshotPrefix, true) && |
| 139 EndsWith(entry.base_name(), kScreenshotSuffix, true)) { |
| 140 screenshot_entries.push_back(entry); |
| 141 } |
| 142 } |
| 143 |
| 144 size_t sort_size = std::min(max_saved, screenshot_entries.size()); |
| 145 std::partial_sort(screenshot_entries.begin(), |
| 146 screenshot_entries.begin() + sort_size, |
| 147 screenshot_entries.end(), |
| 148 ScreenshotGDataTimestampComp); |
| 149 for (size_t i = 0; i < sort_size; ++i) { |
| 150 const gdata::GDataEntryProto& entry = screenshot_entries[i]; |
| 151 saved_screenshots->push_back( |
| 152 std::string(kSavedScreenshotsUrl) + entry.resource_id()); |
| 153 } |
| 154 callback.Run(); |
| 155 } |
| 156 |
| 121 #else | 157 #else |
| 122 | 158 |
| 123 std::string GetUserEmail() { | 159 std::string GetUserEmail() { |
| 124 Profile* profile = ProfileManager::GetLastUsedProfile(); | 160 Profile* profile = ProfileManager::GetLastUsedProfile(); |
| 125 if (!profile) | 161 if (!profile) |
| 126 return std::string(); | 162 return std::string(); |
| 127 | 163 |
| 128 SigninManager* signin = SigninManagerFactory::GetForProfile(profile); | 164 SigninManager* signin = SigninManagerFactory::GetForProfile(profile); |
| 129 if (!signin) | 165 if (!signin) |
| 130 return std::string(); | 166 return std::string(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // WebUIMessageHandler implementation. | 258 // WebUIMessageHandler implementation. |
| 223 virtual void RegisterMessages() OVERRIDE; | 259 virtual void RegisterMessages() OVERRIDE; |
| 224 | 260 |
| 225 private: | 261 private: |
| 226 void HandleGetDialogDefaults(const ListValue* args); | 262 void HandleGetDialogDefaults(const ListValue* args); |
| 227 void HandleRefreshCurrentScreenshot(const ListValue* args); | 263 void HandleRefreshCurrentScreenshot(const ListValue* args); |
| 228 #if defined(OS_CHROMEOS) | 264 #if defined(OS_CHROMEOS) |
| 229 void HandleRefreshSavedScreenshots(const ListValue* args); | 265 void HandleRefreshSavedScreenshots(const ListValue* args); |
| 230 void RefreshSavedScreenshotsCallback( | 266 void RefreshSavedScreenshotsCallback( |
| 231 std::vector<std::string>* saved_screenshots); | 267 std::vector<std::string>* saved_screenshots); |
| 268 void GetMostRecentScreenshotsGData( |
| 269 const FilePath& filepath, std::vector<std::string>* saved_screenshots, |
| 270 size_t max_saved, base::Closure callback); |
| 232 #endif | 271 #endif |
| 233 void HandleSendReport(const ListValue* args); | 272 void HandleSendReport(const ListValue* args); |
| 234 void HandleCancel(const ListValue* args); | 273 void HandleCancel(const ListValue* args); |
| 235 void HandleOpenSystemTab(const ListValue* args); | 274 void HandleOpenSystemTab(const ListValue* args); |
| 236 | 275 |
| 237 void SetupScreenshotsSource(); | 276 void SetupScreenshotsSource(); |
| 238 void ClobberScreenshotsSource(); | 277 void ClobberScreenshotsSource(); |
| 239 | 278 |
| 240 void CancelFeedbackCollection(); | 279 void CancelFeedbackCollection(); |
| 241 void CloseFeedbackTab(); | 280 void CloseFeedbackTab(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 } | 369 } |
| 331 // Make sure we don't leave any screenshot data around. | 370 // Make sure we don't leave any screenshot data around. |
| 332 FeedbackUtil::ClearScreenshotPng(); | 371 FeedbackUtil::ClearScreenshotPng(); |
| 333 } | 372 } |
| 334 | 373 |
| 335 void FeedbackHandler::ClobberScreenshotsSource() { | 374 void FeedbackHandler::ClobberScreenshotsSource() { |
| 336 // Re-create our screenshots data source (this clobbers the last source) | 375 // Re-create our screenshots data source (this clobbers the last source) |
| 337 // setting the screenshot to NULL, effectively disabling the source | 376 // setting the screenshot to NULL, effectively disabling the source |
| 338 // TODO(rkc): Once there is a method to 'remove' a source, change this code | 377 // TODO(rkc): Once there is a method to 'remove' a source, change this code |
| 339 Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext()); | 378 Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext()); |
| 340 ChromeURLDataManager::AddDataSource(profile, new ScreenshotSource(NULL)); | 379 ChromeURLDataManager::AddDataSource(profile, |
| 380 new ScreenshotSource(NULL, profile)); |
| 341 | 381 |
| 342 FeedbackUtil::ClearScreenshotPng(); | 382 FeedbackUtil::ClearScreenshotPng(); |
| 343 } | 383 } |
| 344 | 384 |
| 345 void FeedbackHandler::SetupScreenshotsSource() { | 385 void FeedbackHandler::SetupScreenshotsSource() { |
| 386 Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext()); |
| 346 // If we don't already have a screenshot source object created, create one. | 387 // If we don't already have a screenshot source object created, create one. |
| 347 if (!screenshot_source_) { | 388 if (!screenshot_source_) { |
| 348 screenshot_source_ = | 389 screenshot_source_ = |
| 349 new ScreenshotSource(FeedbackUtil::GetScreenshotPng()); | 390 new ScreenshotSource(FeedbackUtil::GetScreenshotPng(), profile); |
| 350 } | 391 } |
| 351 // Add the source to the data manager. | 392 // Add the source to the data manager. |
| 352 Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext()); | |
| 353 ChromeURLDataManager::AddDataSource(profile, screenshot_source_); | 393 ChromeURLDataManager::AddDataSource(profile, screenshot_source_); |
| 354 } | 394 } |
| 355 | 395 |
| 356 bool FeedbackHandler::Init() { | 396 bool FeedbackHandler::Init() { |
| 357 std::string page_url; | 397 std::string page_url; |
| 358 if (tab_->GetController().GetActiveEntry()) { | 398 if (tab_->GetController().GetActiveEntry()) { |
| 359 page_url = tab_->GetController().GetActiveEntry()->GetURL().spec(); | 399 page_url = tab_->GetController().GetActiveEntry()->GetURL().spec(); |
| 360 } | 400 } |
| 361 | 401 |
| 362 url_parse::Parsed parts; | 402 url_parse::Parsed parts; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 | 549 |
| 510 void FeedbackHandler::HandleRefreshCurrentScreenshot(const ListValue*) { | 550 void FeedbackHandler::HandleRefreshCurrentScreenshot(const ListValue*) { |
| 511 std::string current_screenshot(kCurrentScreenshotUrl); | 551 std::string current_screenshot(kCurrentScreenshotUrl); |
| 512 StringValue screenshot(current_screenshot); | 552 StringValue screenshot(current_screenshot); |
| 513 web_ui()->CallJavascriptFunction("setupCurrentScreenshot", screenshot); | 553 web_ui()->CallJavascriptFunction("setupCurrentScreenshot", screenshot); |
| 514 } | 554 } |
| 515 | 555 |
| 516 #if defined(OS_CHROMEOS) | 556 #if defined(OS_CHROMEOS) |
| 517 void FeedbackHandler::HandleRefreshSavedScreenshots(const ListValue*) { | 557 void FeedbackHandler::HandleRefreshSavedScreenshots(const ListValue*) { |
| 518 std::vector<std::string>* saved_screenshots = new std::vector<std::string>; | 558 std::vector<std::string>* saved_screenshots = new std::vector<std::string>; |
| 519 BrowserThread::PostTaskAndReply( | 559 FilePath filepath = DownloadPrefs::FromBrowserContext( |
| 520 BrowserThread::FILE, FROM_HERE, | 560 tab_->GetBrowserContext())->DownloadPath(); |
| 521 base::Bind(&GetSavedScreenshots, base::Unretained(saved_screenshots)), | 561 base::Closure refresh_callback = base::Bind( |
| 522 base::Bind(&FeedbackHandler::RefreshSavedScreenshotsCallback, | 562 &FeedbackHandler::RefreshSavedScreenshotsCallback, |
| 523 base::Unretained(this), base::Owned(saved_screenshots))); | 563 AsWeakPtr(), base::Owned(saved_screenshots)); |
| 564 if (gdata::util::IsUnderGDataMountPoint(filepath)) { |
| 565 GetMostRecentScreenshotsGData( |
| 566 filepath, saved_screenshots, kMaxSavedScreenshots, refresh_callback); |
| 567 } else { |
| 568 BrowserThread::PostTaskAndReply( |
| 569 BrowserThread::FILE, FROM_HERE, |
| 570 base::Bind(&FeedbackUI::GetMostRecentScreenshots, filepath, |
| 571 base::Unretained(saved_screenshots), kMaxSavedScreenshots), |
| 572 refresh_callback); |
| 573 } |
| 524 } | 574 } |
| 525 | 575 |
| 526 void FeedbackHandler::RefreshSavedScreenshotsCallback( | 576 void FeedbackHandler::RefreshSavedScreenshotsCallback( |
| 527 std::vector<std::string>* saved_screenshots) { | 577 std::vector<std::string>* saved_screenshots) { |
| 528 ListValue screenshots_list; | 578 ListValue screenshots_list; |
| 529 for (size_t i = 0; i < saved_screenshots->size(); ++i) | 579 for (size_t i = 0; i < saved_screenshots->size(); ++i) |
| 530 screenshots_list.Append(new StringValue((*saved_screenshots)[i])); | 580 screenshots_list.Append(new StringValue((*saved_screenshots)[i])); |
| 531 web_ui()->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); | 581 web_ui()->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); |
| 532 } | 582 } |
| 533 | 583 |
| 584 void FeedbackHandler::GetMostRecentScreenshotsGData( |
| 585 const FilePath& filepath, std::vector<std::string>* saved_screenshots, |
| 586 size_t max_saved, base::Closure callback) { |
| 587 gdata::GDataFileSystemInterface* file_system = |
| 588 gdata::GDataSystemServiceFactory::GetForProfile( |
| 589 Profile::FromWebUI(web_ui()))->file_system(); |
| 590 file_system->ReadDirectoryByPath( |
| 591 gdata::util::ExtractGDataPath(filepath), |
| 592 base::Bind(&ReadDirectoryCallback, max_saved, saved_screenshots, |
| 593 callback)); |
| 594 } |
| 534 #endif | 595 #endif |
| 535 | 596 |
| 536 | 597 |
| 537 void FeedbackHandler::HandleSendReport(const ListValue* list_value) { | 598 void FeedbackHandler::HandleSendReport(const ListValue* list_value) { |
| 538 if (!feedback_data_) { | 599 if (!feedback_data_) { |
| 539 LOG(ERROR) << "Bug report hasn't been intialized yet."; | 600 LOG(ERROR) << "Bug report hasn't been intialized yet."; |
| 540 return; | 601 return; |
| 541 } | 602 } |
| 542 // TODO(rkc): Find a better way to do this check. | 603 // TODO(rkc): Find a better way to do this check. |
| 543 #if defined(OS_CHROMEOS) | 604 #if defined(OS_CHROMEOS) |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 Profile* profile = Profile::FromWebUI(web_ui); | 724 Profile* profile = Profile::FromWebUI(web_ui); |
| 664 ChromeURLDataManager::AddDataSource(profile, html_source); | 725 ChromeURLDataManager::AddDataSource(profile, html_source); |
| 665 } | 726 } |
| 666 | 727 |
| 667 #if defined(OS_CHROMEOS) | 728 #if defined(OS_CHROMEOS) |
| 668 // static | 729 // static |
| 669 void FeedbackUI::GetMostRecentScreenshots( | 730 void FeedbackUI::GetMostRecentScreenshots( |
| 670 const FilePath& filepath, | 731 const FilePath& filepath, |
| 671 std::vector<std::string>* saved_screenshots, | 732 std::vector<std::string>* saved_screenshots, |
| 672 size_t max_saved) { | 733 size_t max_saved) { |
| 734 std::string pattern = |
| 735 std::string(kScreenshotPrefix) + "*" + kScreenshotSuffix; |
| 673 file_util::FileEnumerator screenshots(filepath, false, | 736 file_util::FileEnumerator screenshots(filepath, false, |
| 674 file_util::FileEnumerator::FILES, | 737 file_util::FileEnumerator::FILES, |
| 675 std::string(kScreenshotPattern)); | 738 pattern); |
| 676 FilePath screenshot = screenshots.Next(); | 739 FilePath screenshot = screenshots.Next(); |
| 677 | 740 |
| 678 std::vector<std::string> screenshot_filepaths; | 741 std::vector<std::string> screenshot_filepaths; |
| 679 while (!screenshot.empty()) { | 742 while (!screenshot.empty()) { |
| 680 screenshot_filepaths.push_back(screenshot.BaseName().value()); | 743 screenshot_filepaths.push_back(screenshot.BaseName().value()); |
| 681 screenshot = screenshots.Next(); | 744 screenshot = screenshots.Next(); |
| 682 } | 745 } |
| 683 | 746 |
| 684 size_t sort_size = std::min(max_saved, screenshot_filepaths.size()); | 747 size_t sort_size = std::min(max_saved, screenshot_filepaths.size()); |
| 685 std::partial_sort(screenshot_filepaths.begin(), | 748 std::partial_sort(screenshot_filepaths.begin(), |
| 686 screenshot_filepaths.begin() + sort_size, | 749 screenshot_filepaths.begin() + sort_size, |
| 687 screenshot_filepaths.end(), | 750 screenshot_filepaths.end(), |
| 688 ScreenshotTimestampComp); | 751 ScreenshotTimestampComp); |
| 689 for (size_t i = 0; i < sort_size; ++i) | 752 for (size_t i = 0; i < sort_size; ++i) |
| 690 saved_screenshots->push_back(std::string(kSavedScreenshotsUrl) + | 753 saved_screenshots->push_back(std::string(kSavedScreenshotsUrl) + |
| 691 screenshot_filepaths[i]); | 754 screenshot_filepaths[i]); |
| 692 } | 755 } |
| 693 #endif | 756 #endif |
| OLD | NEW |