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 |