Index: chrome/browser/ui/ash/screenshot_taker.cc |
diff --git a/chrome/browser/ui/ash/screenshot_taker.cc b/chrome/browser/ui/ash/screenshot_taker.cc |
index e1ed8b888ce73516a95b6f1b21f30acbba513453..befe25cb51719935830709388838c56c031d2210 100644 |
--- a/chrome/browser/ui/ash/screenshot_taker.cc |
+++ b/chrome/browser/ui/ash/screenshot_taker.cc |
@@ -35,7 +35,16 @@ |
#endif |
namespace { |
-const int kScreenshotMinimumIntervalInMS = 500; |
+// How opaque should the layer that we flash onscreen to provide visual |
+// feedback after the screenshot is taken be? |
+const float kVisualFeedbackLayerOpacity = 0.25f; |
+ |
+// How long should the visual feedback layer be displayed? |
+const int64 kVisualFeedbackLayerDisplayTimeMs = 100; |
+ |
+// The minimum interval between two screenshot commands. It has to be |
+// more than 1000 to prevent the conflict of filenames. |
+const int kScreenshotMinimumIntervalInMS = 1000; |
bool ShouldUse24HourClock() { |
#if defined(OS_CHROMEOS) |
@@ -50,7 +59,12 @@ bool ShouldUse24HourClock() { |
return base::GetHourClockType() == base::k24HourClock; |
} |
-std::string GetScreenShotBaseFilename(bool use_24hour_clock) { |
+bool AreScreenshotsDisabled() { |
+ return g_browser_process->local_state()->GetBoolean( |
+ prefs::kDisableScreenshots); |
+} |
+ |
+std::string GetScreenshotBaseFilename() { |
base::Time::Exploded now; |
base::Time::Now().LocalExplode(&now); |
@@ -61,7 +75,7 @@ std::string GetScreenShotBaseFilename(bool use_24hour_clock) { |
std::string file_name = base::StringPrintf( |
"Screenshot %d-%02d-%02d at ", now.year, now.month, now.day_of_month); |
- if (use_24hour_clock) { |
+ if (ShouldUse24HourClock()) { |
file_name.append(base::StringPrintf( |
"%02d.%02d.%02d", now.hour, now.minute, now.second)); |
} else { |
@@ -79,25 +93,32 @@ std::string GetScreenShotBaseFilename(bool use_24hour_clock) { |
return file_name; |
} |
-FilePath GetScreenshotPath(const FilePath& base_directory, |
- const std::string& base_name) { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
- for (int retry = 0; retry < INT_MAX; retry++) { |
- std::string retry_suffix; |
- if (retry > 0) |
- retry_suffix = base::StringPrintf(" (%d)", retry + 1); |
- |
- FilePath file_path = base_directory.AppendASCII( |
- base_name + retry_suffix + ".png"); |
- if (!file_util::PathExists(file_path)) |
- return file_path; |
+bool GetScreenshotDirectory(FilePath* directory) { |
+ if (AreScreenshotsDisabled()) |
+ return false; |
+ |
+ bool is_logged_in = true; |
+#if defined(OS_CHROMEOS) |
+ is_logged_in = chromeos::UserManager::Get()->IsUserLoggedIn(); |
+#endif |
+ |
+ if (is_logged_in) { |
+ DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext( |
+ ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext()); |
+ *directory = download_prefs->DownloadPath(); |
+ } else { |
+ if (!file_util::GetTempDir(directory)) { |
+ LOG(ERROR) << "Failed to find temporary directory."; |
+ return false; |
+ } |
} |
- return FilePath(); |
+ return true; |
} |
-void SaveScreenshotToLocalFile(scoped_refptr<base::RefCountedBytes> png_data, |
- const FilePath& screenshot_path) { |
+void SaveScreenshot(const FilePath& screenshot_path, |
+ scoped_refptr<base::RefCountedBytes> png_data) { |
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
+ DCHECK(!screenshot_path.empty()); |
if (static_cast<size_t>(file_util::WriteFile( |
screenshot_path, |
reinterpret_cast<char*>(&(png_data->data()[0])), |
@@ -106,17 +127,6 @@ void SaveScreenshotToLocalFile(scoped_refptr<base::RefCountedBytes> png_data, |
} |
} |
-void SaveScreenshot(const FilePath& screenshot_directory, |
- const std::string& base_name, |
- scoped_refptr<base::RefCountedBytes> png_data) { |
- FilePath screenshot_path = GetScreenshotPath(screenshot_directory, base_name); |
- if (screenshot_path.empty()) { |
- LOG(ERROR) << "Failed to find a screenshot file name."; |
- return; |
- } |
- SaveScreenshotToLocalFile(png_data, screenshot_path); |
-} |
- |
// TODO(kinaba): crbug.com/140425, remove this ungly #ifdef dispatch. |
#ifdef OS_CHROMEOS |
void SaveScreenshotToGData(scoped_refptr<base::RefCountedBytes> png_data, |
@@ -126,43 +136,34 @@ void SaveScreenshotToGData(scoped_refptr<base::RefCountedBytes> png_data, |
LOG(ERROR) << "Failed to write screenshot image to Google Drive: " << error; |
return; |
} |
- SaveScreenshotToLocalFile(png_data, local_path); |
+ SaveScreenshot(local_path, png_data); |
} |
-void PostSaveScreenshotTask(const FilePath& screenshot_directory, |
- const std::string& base_name, |
+void PostSaveScreenshotTask(const FilePath& screenshot_path, |
scoped_refptr<base::RefCountedBytes> png_data) { |
- if (gdata::util::IsUnderGDataMountPoint(screenshot_directory)) { |
+ if (gdata::util::IsUnderGDataMountPoint(screenshot_path)) { |
Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); |
if (profile) { |
- // TODO(kinaba,mukai): crbug.com/140749. Take care of the case |
- // "base_name.png" already exists. |
gdata::util::PrepareWritableFileAndRun( |
profile, |
- screenshot_directory.Append(base_name + ".png"), |
+ screenshot_path, |
base::Bind(&SaveScreenshotToGData, png_data)); |
} |
} else { |
content::BrowserThread::PostTask( |
content::BrowserThread::FILE, FROM_HERE, |
- base::Bind(&SaveScreenshot, screenshot_directory, base_name, png_data)); |
+ base::Bind(&SaveScreenshot, screenshot_path, png_data)); |
} |
} |
#else |
-void PostSaveScreenshotTask(const FilePath& screenshot_directory, |
- const std::string& base_name, |
+void PostSaveScreenshotTask(const FilePath& screenshot_path, |
scoped_refptr<base::RefCountedBytes> png_data) { |
content::BrowserThread::PostTask( |
content::BrowserThread::FILE, FROM_HERE, |
- base::Bind(&SaveScreenshot, screenshot_directory, base_name, png_data)); |
+ base::Bind(&SaveScreenshot, screenshot_path, png_data)); |
} |
#endif |
-bool AreScreenshotsDisabled() { |
- return g_browser_process->local_state()->GetBoolean( |
- prefs::kDisableScreenshots); |
-} |
- |
bool GrabWindowSnapshot(aura::Window* window, |
const gfx::Rect& snapshot_bounds, |
std::vector<unsigned char>* png_data) { |
@@ -182,13 +183,6 @@ bool GrabWindowSnapshot(aura::Window* window, |
return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds); |
} |
-// How opaque should the layer that we flash onscreen to provide visual |
-// feedback after the screenshot is taken be? |
-const float kVisualFeedbackLayerOpacity = 0.25f; |
- |
-// How long should the visual feedback layer be displayed? |
-const int64 kVisualFeedbackLayerDisplayTimeMs = 100; |
- |
} // namespace |
ScreenshotTaker::ScreenshotTaker() { |
@@ -197,42 +191,47 @@ ScreenshotTaker::ScreenshotTaker() { |
ScreenshotTaker::~ScreenshotTaker() { |
} |
-void ScreenshotTaker::HandleTakeScreenshot(aura::Window* window) { |
- HandleTakePartialScreenshot(window, window->bounds()); |
+void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() { |
+ FilePath screenshot_directory; |
+ if (!GetScreenshotDirectory(&screenshot_directory)) |
+ return; |
+ |
+ std::string screenshot_basename = GetScreenshotBaseFilename(); |
+ ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows(); |
+ for (size_t i = 0; i < root_windows.size(); ++i) { |
+ aura::RootWindow* root_window = root_windows[i]; |
+ scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); |
+ std::string basename = screenshot_basename; |
+ gfx::Rect rect = root_window->bounds(); |
+ if (root_windows.size() > 1) |
+ basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); |
+ if (GrabWindowSnapshot(root_window, rect, &png_data->data())) { |
+ DisplayVisualFeedback(rect); |
+ PostSaveScreenshotTask( |
+ screenshot_directory.AppendASCII(basename + ".png"), png_data); |
+ } else { |
+ LOG(ERROR) << "Failed to grab the window screenshot for " << i; |
+ } |
+ } |
+ last_screenshot_timestamp_ = base::Time::Now(); |
} |
void ScreenshotTaker::HandleTakePartialScreenshot( |
aura::Window* window, const gfx::Rect& rect) { |
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- if (AreScreenshotsDisabled()) |
+ FilePath screenshot_directory; |
+ if (!GetScreenshotDirectory(&screenshot_directory)) |
return; |
scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); |
- bool is_logged_in = true; |
-#if defined(OS_CHROMEOS) |
- is_logged_in = chromeos::UserManager::Get()->IsUserLoggedIn(); |
-#endif |
- |
- FilePath screenshot_directory; |
- if (is_logged_in) { |
- DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext( |
- ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext()); |
- screenshot_directory = download_prefs->DownloadPath(); |
- } else { |
- if (!file_util::GetTempDir(&screenshot_directory)) { |
- LOG(ERROR) << "Failed to find temporary directory."; |
- return; |
- } |
- } |
- |
if (GrabWindowSnapshot(window, rect, &png_data->data())) { |
last_screenshot_timestamp_ = base::Time::Now(); |
DisplayVisualFeedback(rect); |
- PostSaveScreenshotTask(screenshot_directory, |
- GetScreenShotBaseFilename(ShouldUse24HourClock()), |
- png_data); |
+ PostSaveScreenshotTask( |
+ screenshot_directory.AppendASCII(GetScreenshotBaseFilename() + ".png"), |
+ png_data); |
} else { |
LOG(ERROR) << "Failed to grab the window screenshot"; |
} |