Commit 3d00fbd7 authored by mukai@chromium.org's avatar mukai@chromium.org

Allow /drive files in "Report Issue" page.


BUG=140622


Review URL: https://chromiumcodereview.appspot.com/10837253

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151876 0039d316-1c4b-4281-b951-d872f2087c98
parent f924eff4
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/ui/webui/feedback_ui.h" #include "chrome/browser/ui/webui/feedback_ui.h"
#include <algorithm>
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
...@@ -58,6 +59,10 @@ ...@@ -58,6 +59,10 @@
#include "base/file_util.h" #include "base/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h"
#include "chrome/browser/chromeos/gdata/gdata.pb.h"
#include "chrome/browser/chromeos/gdata/gdata_system_service.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/system/syslogs_provider.h" #include "chrome/browser/chromeos/system/syslogs_provider.h"
#include "ui/aura/root_window.h" #include "ui/aura/root_window.h"
...@@ -82,7 +87,8 @@ const char kCustomPageUrlParameter[] = "customPageUrl="; ...@@ -82,7 +87,8 @@ const char kCustomPageUrlParameter[] = "customPageUrl=";
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/"; const char kSavedScreenshotsUrl[] = "chrome://screenshots/saved/";
const char kScreenshotPattern[] = "Screenshot *.png"; const char kScreenshotPrefix[] = "Screenshot ";
const char kScreenshotSuffix[] = ".png";
const char kTimestampParameter[] = "timestamp="; const char kTimestampParameter[] = "timestamp=";
...@@ -90,6 +96,7 @@ const size_t kMaxSavedScreenshots = 2; ...@@ -90,6 +96,7 @@ const size_t kMaxSavedScreenshots = 2;
#endif #endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
size_t kMaxNumScanFiles = 1000;
// Compare two screenshot filepaths, which include the screenshot timestamp // Compare two screenshot filepaths, which include the screenshot timestamp
// in the format of screenshot-yyyymmdd-hhmmss.png. Return true if |filepath1| // in the format of screenshot-yyyymmdd-hhmmss.png. Return true if |filepath1|
...@@ -99,17 +106,6 @@ bool ScreenshotTimestampComp(const std::string& filepath1, ...@@ -99,17 +106,6 @@ bool ScreenshotTimestampComp(const std::string& filepath1,
return filepath1 > filepath2; return filepath1 > filepath2;
} }
void GetSavedScreenshots(std::vector<std::string>* saved_screenshots) {
saved_screenshots->clear();
DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
FeedbackUI::GetMostRecentScreenshots(
download_prefs->DownloadPath(),
saved_screenshots,
kMaxSavedScreenshots);
}
std::string GetUserEmail() { std::string GetUserEmail() {
chromeos::UserManager* manager = chromeos::UserManager::Get(); chromeos::UserManager* manager = chromeos::UserManager::Get();
if (!manager) if (!manager)
...@@ -118,6 +114,46 @@ std::string GetUserEmail() { ...@@ -118,6 +114,46 @@ std::string GetUserEmail() {
return manager->GetLoggedInUser().display_email(); return manager->GetLoggedInUser().display_email();
} }
bool ScreenshotGDataTimestampComp(const gdata::GDataEntryProto& entry1,
const gdata::GDataEntryProto& entry2) {
return entry1.file_info().last_modified() >
entry2.file_info().last_modified();
}
void ReadDirectoryCallback(size_t max_saved,
std::vector<std::string>* saved_screenshots,
base::Closure callback,
gdata::GDataFileError error,
bool hide_hosted_documents,
scoped_ptr<gdata::GDataEntryProtoVector> entries) {
if (error != gdata::GDATA_FILE_OK) {
callback.Run();
return;
}
size_t max_scan = std::min(kMaxNumScanFiles, entries->size());
std::vector<gdata::GDataEntryProto> screenshot_entries;
for (size_t i = 0; i < max_scan; ++i) {
const gdata::GDataEntryProto& entry = (*entries)[i];
if (StartsWithASCII(entry.base_name(), kScreenshotPrefix, true) &&
EndsWith(entry.base_name(), kScreenshotSuffix, true)) {
screenshot_entries.push_back(entry);
}
}
size_t sort_size = std::min(max_saved, screenshot_entries.size());
std::partial_sort(screenshot_entries.begin(),
screenshot_entries.begin() + sort_size,
screenshot_entries.end(),
ScreenshotGDataTimestampComp);
for (size_t i = 0; i < sort_size; ++i) {
const gdata::GDataEntryProto& entry = screenshot_entries[i];
saved_screenshots->push_back(
std::string(kSavedScreenshotsUrl) + entry.resource_id());
}
callback.Run();
}
#else #else
std::string GetUserEmail() { std::string GetUserEmail() {
...@@ -229,6 +265,9 @@ class FeedbackHandler : public WebUIMessageHandler, ...@@ -229,6 +265,9 @@ class FeedbackHandler : public WebUIMessageHandler,
void HandleRefreshSavedScreenshots(const ListValue* args); void HandleRefreshSavedScreenshots(const ListValue* args);
void RefreshSavedScreenshotsCallback( void RefreshSavedScreenshotsCallback(
std::vector<std::string>* saved_screenshots); std::vector<std::string>* saved_screenshots);
void GetMostRecentScreenshotsGData(
const FilePath& filepath, std::vector<std::string>* saved_screenshots,
size_t max_saved, base::Closure callback);
#endif #endif
void HandleSendReport(const ListValue* args); void HandleSendReport(const ListValue* args);
void HandleCancel(const ListValue* args); void HandleCancel(const ListValue* args);
...@@ -337,19 +376,20 @@ void FeedbackHandler::ClobberScreenshotsSource() { ...@@ -337,19 +376,20 @@ void FeedbackHandler::ClobberScreenshotsSource() {
// setting the screenshot to NULL, effectively disabling the source // setting the screenshot to NULL, effectively disabling the source
// TODO(rkc): Once there is a method to 'remove' a source, change this code // TODO(rkc): Once there is a method to 'remove' a source, change this code
Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext()); Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext());
ChromeURLDataManager::AddDataSource(profile, new ScreenshotSource(NULL)); ChromeURLDataManager::AddDataSource(profile,
new ScreenshotSource(NULL, profile));
FeedbackUtil::ClearScreenshotPng(); FeedbackUtil::ClearScreenshotPng();
} }
void FeedbackHandler::SetupScreenshotsSource() { void FeedbackHandler::SetupScreenshotsSource() {
Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext());
// If we don't already have a screenshot source object created, create one. // If we don't already have a screenshot source object created, create one.
if (!screenshot_source_) { if (!screenshot_source_) {
screenshot_source_ = screenshot_source_ =
new ScreenshotSource(FeedbackUtil::GetScreenshotPng()); new ScreenshotSource(FeedbackUtil::GetScreenshotPng(), profile);
} }
// Add the source to the data manager. // Add the source to the data manager.
Profile* profile = Profile::FromBrowserContext(tab_->GetBrowserContext());
ChromeURLDataManager::AddDataSource(profile, screenshot_source_); ChromeURLDataManager::AddDataSource(profile, screenshot_source_);
} }
...@@ -516,11 +556,21 @@ void FeedbackHandler::HandleRefreshCurrentScreenshot(const ListValue*) { ...@@ -516,11 +556,21 @@ void FeedbackHandler::HandleRefreshCurrentScreenshot(const ListValue*) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void FeedbackHandler::HandleRefreshSavedScreenshots(const ListValue*) { void FeedbackHandler::HandleRefreshSavedScreenshots(const ListValue*) {
std::vector<std::string>* saved_screenshots = new std::vector<std::string>; std::vector<std::string>* saved_screenshots = new std::vector<std::string>;
BrowserThread::PostTaskAndReply( FilePath filepath = DownloadPrefs::FromBrowserContext(
BrowserThread::FILE, FROM_HERE, tab_->GetBrowserContext())->DownloadPath();
base::Bind(&GetSavedScreenshots, base::Unretained(saved_screenshots)), base::Closure refresh_callback = base::Bind(
base::Bind(&FeedbackHandler::RefreshSavedScreenshotsCallback, &FeedbackHandler::RefreshSavedScreenshotsCallback,
base::Unretained(this), base::Owned(saved_screenshots))); AsWeakPtr(), base::Owned(saved_screenshots));
if (gdata::util::IsUnderGDataMountPoint(filepath)) {
GetMostRecentScreenshotsGData(
filepath, saved_screenshots, kMaxSavedScreenshots, refresh_callback);
} else {
BrowserThread::PostTaskAndReply(
BrowserThread::FILE, FROM_HERE,
base::Bind(&FeedbackUI::GetMostRecentScreenshots, filepath,
base::Unretained(saved_screenshots), kMaxSavedScreenshots),
refresh_callback);
}
} }
void FeedbackHandler::RefreshSavedScreenshotsCallback( void FeedbackHandler::RefreshSavedScreenshotsCallback(
...@@ -531,6 +581,17 @@ void FeedbackHandler::RefreshSavedScreenshotsCallback( ...@@ -531,6 +581,17 @@ void FeedbackHandler::RefreshSavedScreenshotsCallback(
web_ui()->CallJavascriptFunction("setupSavedScreenshots", screenshots_list); web_ui()->CallJavascriptFunction("setupSavedScreenshots", screenshots_list);
} }
void FeedbackHandler::GetMostRecentScreenshotsGData(
const FilePath& filepath, std::vector<std::string>* saved_screenshots,
size_t max_saved, base::Closure callback) {
gdata::GDataFileSystemInterface* file_system =
gdata::GDataSystemServiceFactory::GetForProfile(
Profile::FromWebUI(web_ui()))->file_system();
file_system->ReadDirectoryByPath(
gdata::util::ExtractGDataPath(filepath),
base::Bind(&ReadDirectoryCallback, max_saved, saved_screenshots,
callback));
}
#endif #endif
...@@ -670,9 +731,11 @@ void FeedbackUI::GetMostRecentScreenshots( ...@@ -670,9 +731,11 @@ void FeedbackUI::GetMostRecentScreenshots(
const FilePath& filepath, const FilePath& filepath,
std::vector<std::string>* saved_screenshots, std::vector<std::string>* saved_screenshots,
size_t max_saved) { size_t max_saved) {
std::string pattern =
std::string(kScreenshotPrefix) + "*" + kScreenshotSuffix;
file_util::FileEnumerator screenshots(filepath, false, file_util::FileEnumerator screenshots(filepath, false,
file_util::FileEnumerator::FILES, file_util::FileEnumerator::FILES,
std::string(kScreenshotPattern)); pattern);
FilePath screenshot = screenshots.Next(); FilePath screenshot = screenshots.Next();
std::vector<std::string> screenshot_filepaths; std::vector<std::string> screenshot_filepaths;
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/shell_delegate.h" #include "ash/shell_delegate.h"
#include "chrome/browser/chromeos/gdata/gdata_file_system_interface.h"
#include "chrome/browser/chromeos/gdata/gdata_system_service.h"
#include "chrome/browser/chromeos/gdata/gdata_util.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#endif #endif
...@@ -30,8 +33,10 @@ static const char kSavedScreenshotsBasePath[] = "saved/"; ...@@ -30,8 +33,10 @@ static const char kSavedScreenshotsBasePath[] = "saved/";
#endif #endif
ScreenshotSource::ScreenshotSource( ScreenshotSource::ScreenshotSource(
std::vector<unsigned char>* current_screenshot) std::vector<unsigned char>* current_screenshot,
: DataSource(chrome::kChromeUIScreenshotPath, MessageLoop::current()) { Profile* profile)
: DataSource(chrome::kChromeUIScreenshotPath, MessageLoop::current()),
profile_(profile) {
// Setup the last screenshot taken. // Setup the last screenshot taken.
if (current_screenshot) if (current_screenshot)
current_screenshot_.reset(new ScreenshotData(*current_screenshot)); current_screenshot_.reset(new ScreenshotData(*current_screenshot));
...@@ -76,10 +81,36 @@ void ScreenshotSource::SendScreenshot(const std::string& screenshot_path, ...@@ -76,10 +81,36 @@ void ScreenshotSource::SendScreenshot(const std::string& screenshot_path,
} else if (path.compare(0, strlen(kSavedScreenshotsBasePath), } else if (path.compare(0, strlen(kSavedScreenshotsBasePath),
kSavedScreenshotsBasePath) == 0) { kSavedScreenshotsBasePath) == 0) {
using content::BrowserThread; using content::BrowserThread;
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&ScreenshotSource::SendSavedScreenshot, std::string filename = path.substr(strlen(kSavedScreenshotsBasePath));
base::Unretained(this), path,
request_id)); url_canon::RawCanonOutputT<char16> decoded;
url_util::DecodeURLEscapeSequences(
filename.data(), filename.size(), &decoded);
// Screenshot filenames don't use non-ascii characters.
std::string decoded_filename = UTF16ToASCII(string16(
decoded.data(), decoded.length()));
DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
FilePath download_path = download_prefs->DownloadPath();
if (gdata::util::IsUnderGDataMountPoint(download_path)) {
gdata::GDataFileSystemInterface* file_system =
gdata::GDataSystemServiceFactory::GetForProfile(
profile_)->file_system();
file_system->GetFileByResourceId(
decoded_filename,
base::Bind(&ScreenshotSource::GetSavedScreenshotCallback,
base::Unretained(this), screenshot_path, request_id),
gdata::GetContentCallback());
} else {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&ScreenshotSource::SendSavedScreenshot,
base::Unretained(this),
screenshot_path,
request_id, download_path.Append(decoded_filename)));
}
#endif #endif
} else { } else {
CacheAndSendScreenshot( CacheAndSendScreenshot(
...@@ -88,23 +119,13 @@ void ScreenshotSource::SendScreenshot(const std::string& screenshot_path, ...@@ -88,23 +119,13 @@ void ScreenshotSource::SendScreenshot(const std::string& screenshot_path,
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void ScreenshotSource::SendSavedScreenshot(const std::string& screenshot_path, void ScreenshotSource::SendSavedScreenshot(
int request_id) { const std::string& screenshot_path,
int request_id,
const FilePath& file) {
ScreenshotDataPtr read_bytes(new ScreenshotData); ScreenshotDataPtr read_bytes(new ScreenshotData);
std::string filename = screenshot_path.substr(
strlen(kSavedScreenshotsBasePath));
url_canon::RawCanonOutputT<char16> decoded;
url_util::DecodeURLEscapeSequences(
filename.data(), filename.size(), &decoded);
// Screenshot filenames don't use non-ascii characters.
std::string decoded_filename = UTF16ToASCII(string16(
decoded.data(), decoded.length()));
int64 file_size = 0; int64 file_size = 0;
DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
FilePath file = download_prefs->DownloadPath().Append(decoded_filename);
if (!file_util::GetFileSize(file, &file_size)) { if (!file_util::GetFileSize(file, &file_size)) {
CacheAndSendScreenshot(screenshot_path, request_id, read_bytes); CacheAndSendScreenshot(screenshot_path, request_id, read_bytes);
return; return;
...@@ -117,6 +138,25 @@ void ScreenshotSource::SendSavedScreenshot(const std::string& screenshot_path, ...@@ -117,6 +138,25 @@ void ScreenshotSource::SendSavedScreenshot(const std::string& screenshot_path,
CacheAndSendScreenshot(screenshot_path, request_id, read_bytes); CacheAndSendScreenshot(screenshot_path, request_id, read_bytes);
} }
void ScreenshotSource::GetSavedScreenshotCallback(
const std::string& screenshot_path,
int request_id,
gdata::GDataFileError error,
const FilePath& file,
const std::string& unused_mime_type,
gdata::GDataFileType file_type) {
if (error != gdata::GDATA_FILE_OK || file_type != gdata::REGULAR_FILE) {
ScreenshotDataPtr read_bytes(new ScreenshotData);
CacheAndSendScreenshot(screenshot_path, request_id, read_bytes);
return;
}
content::BrowserThread::PostTask(
content::BrowserThread::FILE, FROM_HERE,
base::Bind(&ScreenshotSource::SendSavedScreenshot,
base::Unretained(this), screenshot_path, request_id, file));
}
#endif #endif
void ScreenshotSource::CacheAndSendScreenshot( void ScreenshotSource::CacheAndSendScreenshot(
......
...@@ -13,15 +13,24 @@ ...@@ -13,15 +13,24 @@
#include "base/memory/linked_ptr.h" #include "base/memory/linked_ptr.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/gdata/gdata_directory_service.h"
#include "chrome/browser/chromeos/gdata/gdata_errorcode.h"
#endif
typedef std::vector<unsigned char> ScreenshotData; typedef std::vector<unsigned char> ScreenshotData;
typedef linked_ptr<ScreenshotData> ScreenshotDataPtr; typedef linked_ptr<ScreenshotData> ScreenshotDataPtr;
class FilePath;
class Profile;
// ScreenshotSource is the data source that serves screenshots (saved // ScreenshotSource is the data source that serves screenshots (saved
// or current) to the bug report html ui. // or current) to the bug report html ui.
class ScreenshotSource : public ChromeURLDataManager::DataSource { class ScreenshotSource : public ChromeURLDataManager::DataSource {
public: public:
explicit ScreenshotSource( explicit ScreenshotSource(
std::vector<unsigned char>* current_screenshot); std::vector<unsigned char>* current_screenshot,
Profile* profile);
// Called when the network layer has requested a resource underneath // Called when the network layer has requested a resource underneath
// the path we registered. // the path we registered.
...@@ -47,7 +56,18 @@ class ScreenshotSource : public ChromeURLDataManager::DataSource { ...@@ -47,7 +56,18 @@ class ScreenshotSource : public ChromeURLDataManager::DataSource {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// Send a saved screenshot image file specified by the given screenshot path // Send a saved screenshot image file specified by the given screenshot path
// to the requestor. // to the requestor.
void SendSavedScreenshot(const std::string& screenshot_path, int request_id); void SendSavedScreenshot(const std::string& screenshot_path,
int request_id,
const FilePath& file);
// The callback for GData's getting file method.
void GetSavedScreenshotCallback(const std::string& screenshot_path,
int request_id,
gdata::GDataFileError error,
const FilePath& file,
const std::string& unused_mime_type,
gdata::GDataFileType file_type);
#endif #endif
// Sends the screenshot data to the requestor while caching it locally to the // Sends the screenshot data to the requestor while caching it locally to the
// class instance, indexed by path. // class instance, indexed by path.
...@@ -58,6 +78,8 @@ class ScreenshotSource : public ChromeURLDataManager::DataSource { ...@@ -58,6 +78,8 @@ class ScreenshotSource : public ChromeURLDataManager::DataSource {
// Pointer to the screenshot data for the current screenshot. // Pointer to the screenshot data for the current screenshot.
ScreenshotDataPtr current_screenshot_; ScreenshotDataPtr current_screenshot_;
Profile* profile_;
// Key: Relative path to the screenshot (including filename) // Key: Relative path to the screenshot (including filename)
// Value: Pointer to the screenshot data associated with the path. // Value: Pointer to the screenshot data associated with the path.
std::map<std::string, ScreenshotDataPtr> cached_screenshots_; std::map<std::string, ScreenshotDataPtr> cached_screenshots_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment