Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: chrome/browser/ui/ash/screenshot_taker.cc

Issue 10908081: Refactor screenshot directory source (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Include cleanup Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/ash/screenshot_taker.h" 5 #include "chrome/browser/ui/ash/screenshot_taker.h"
6 6
7 #include <climits> 7 #include <climits>
8 #include <string> 8 #include <string>
9 9
10 #include "ash/shell.h" 10 #include "ash/shell.h"
11 #include "ash/shell_delegate.h" 11 #include "ash/shell_delegate.h"
12 #include "ash/shell_window_ids.h" 12 #include "ash/shell_window_ids.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/file_path.h" 14 #include "base/file_path.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/i18n/time_formatting.h"
17 #include "base/logging.h" 16 #include "base/logging.h"
18 #include "base/memory/ref_counted_memory.h" 17 #include "base/memory/ref_counted_memory.h"
19 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
20 #include "base/time.h" 19 #include "base/time.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/download/download_prefs.h" 20 #include "chrome/browser/download/download_prefs.h"
23 #include "chrome/browser/prefs/pref_service.h"
24 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h" 22 #include "chrome/browser/profiles/profile_manager.h"
23 #include "chrome/browser/ui/webui/screenshot_source.h"
26 #include "chrome/browser/ui/window_snapshot/window_snapshot.h" 24 #include "chrome/browser/ui/window_snapshot/window_snapshot.h"
27 #include "chrome/common/pref_names.h"
28 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
29 #include "ui/aura/root_window.h" 26 #include "ui/aura/root_window.h"
30 #include "ui/aura/window.h" 27 #include "ui/aura/window.h"
31 28
32 #if defined(OS_CHROMEOS) 29 #if defined(OS_CHROMEOS)
33 #include "chrome/browser/chromeos/gdata/gdata_util.h" 30 #include "chrome/browser/chromeos/gdata/gdata_util.h"
34 #include "chrome/browser/chromeos/login/user_manager.h"
35 #endif 31 #endif
36 32
37 namespace { 33 namespace {
38 // How opaque should the layer that we flash onscreen to provide visual 34 // How opaque should the layer that we flash onscreen to provide visual
39 // feedback after the screenshot is taken be? 35 // feedback after the screenshot is taken be?
40 const float kVisualFeedbackLayerOpacity = 0.25f; 36 const float kVisualFeedbackLayerOpacity = 0.25f;
41 37
42 // How long should the visual feedback layer be displayed? 38 // How long should the visual feedback layer be displayed?
43 const int64 kVisualFeedbackLayerDisplayTimeMs = 100; 39 const int64 kVisualFeedbackLayerDisplayTimeMs = 100;
44 40
45 // The minimum interval between two screenshot commands. It has to be 41 // The minimum interval between two screenshot commands. It has to be
46 // more than 1000 to prevent the conflict of filenames. 42 // more than 1000 to prevent the conflict of filenames.
47 const int kScreenshotMinimumIntervalInMS = 1000; 43 const int kScreenshotMinimumIntervalInMS = 1000;
48 44
49 bool ShouldUse24HourClock() {
50 #if defined(OS_CHROMEOS)
51 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
52 if (profile) {
53 PrefService* pref_service = profile->GetPrefs();
54 if (pref_service) {
55 return pref_service->GetBoolean(prefs::kUse24HourClock);
56 }
57 }
58 #endif
59 return base::GetHourClockType() == base::k24HourClock;
60 }
61
62 bool AreScreenshotsDisabled() {
63 return g_browser_process->local_state()->GetBoolean(
64 prefs::kDisableScreenshots);
65 }
66
67 std::string GetScreenshotBaseFilename() {
68 base::Time::Exploded now;
69 base::Time::Now().LocalExplode(&now);
70
71 // We don't use base/i18n/time_formatting.h here because it doesn't
72 // support our format. Don't use ICU either to avoid i18n file names
73 // for non-English locales.
74 // TODO(mukai): integrate this logic somewhere time_formatting.h
75 std::string file_name = base::StringPrintf(
76 "Screenshot %d-%02d-%02d at ", now.year, now.month, now.day_of_month);
77
78 if (ShouldUse24HourClock()) {
79 file_name.append(base::StringPrintf(
80 "%02d.%02d.%02d", now.hour, now.minute, now.second));
81 } else {
82 int hour = now.hour;
83 if (hour > 12) {
84 hour -= 12;
85 } else if (hour == 0) {
86 hour = 12;
87 }
88 file_name.append(base::StringPrintf(
89 "%d.%02d.%02d ", hour, now.minute, now.second));
90 file_name.append((now.hour >= 12) ? "PM" : "AM");
91 }
92
93 return file_name;
94 }
95
96 bool GetScreenshotDirectory(FilePath* directory) {
97 if (AreScreenshotsDisabled())
98 return false;
99
100 bool is_logged_in = true;
101 #if defined(OS_CHROMEOS)
102 is_logged_in = chromeos::UserManager::Get()->IsUserLoggedIn();
103 #endif
104
105 if (is_logged_in) {
106 DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
107 ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
108 *directory = download_prefs->DownloadPath();
109 } else {
110 if (!file_util::GetTempDir(directory)) {
111 LOG(ERROR) << "Failed to find temporary directory.";
112 return false;
113 }
114 }
115 return true;
116 }
117 45
118 void SaveScreenshot(const FilePath& screenshot_path, 46 void SaveScreenshot(const FilePath& screenshot_path,
119 scoped_refptr<base::RefCountedBytes> png_data) { 47 scoped_refptr<base::RefCountedBytes> png_data) {
120 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 48 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
121 DCHECK(!screenshot_path.empty()); 49 DCHECK(!screenshot_path.empty());
122 if (static_cast<size_t>(file_util::WriteFile( 50 if (static_cast<size_t>(file_util::WriteFile(
123 screenshot_path, 51 screenshot_path,
124 reinterpret_cast<char*>(&(png_data->data()[0])), 52 reinterpret_cast<char*>(&(png_data->data()[0])),
125 png_data->size())) != png_data->size()) { 53 png_data->size())) != png_data->size()) {
126 LOG(ERROR) << "Failed to save to " << screenshot_path.value(); 54 LOG(ERROR) << "Failed to save to " << screenshot_path.value();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 base::Bind(&SaveScreenshot, screenshot_path, png_data)); 91 base::Bind(&SaveScreenshot, screenshot_path, png_data));
164 } 92 }
165 #endif 93 #endif
166 94
167 bool GrabWindowSnapshot(aura::Window* window, 95 bool GrabWindowSnapshot(aura::Window* window,
168 const gfx::Rect& snapshot_bounds, 96 const gfx::Rect& snapshot_bounds,
169 std::vector<unsigned char>* png_data) { 97 std::vector<unsigned char>* png_data) {
170 #if defined(OS_LINUX) 98 #if defined(OS_LINUX)
171 // chrome::GrabWindowSnapshotForUser checks this too, but 99 // chrome::GrabWindowSnapshotForUser checks this too, but
172 // RootWindow::GrabSnapshot does not. 100 // RootWindow::GrabSnapshot does not.
173 if (AreScreenshotsDisabled()) 101 if (ScreenshotSource::AreScreenshotsDisabled())
174 return false; 102 return false;
175 103
176 // We use XGetImage() for Linux/ChromeOS for performance reasons. 104 // We use XGetImage() for Linux/ChromeOS for performance reasons.
177 // See crbug.com/119492 105 // See crbug.com/119492
178 // TODO(mukai): remove this when the performance issue has been fixed. 106 // TODO(mukai): remove this when the performance issue has been fixed.
179 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data)) 107 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data))
180 return true; 108 return true;
181 #endif // OS_LINUX 109 #endif // OS_LINUX
182 110
183 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds); 111 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds);
184 } 112 }
185 113
186 } // namespace 114 } // namespace
187 115
188 ScreenshotTaker::ScreenshotTaker() { 116 ScreenshotTaker::ScreenshotTaker() {
189 } 117 }
190 118
191 ScreenshotTaker::~ScreenshotTaker() { 119 ScreenshotTaker::~ScreenshotTaker() {
192 } 120 }
193 121
194 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() { 122 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() {
195 FilePath screenshot_directory; 123 FilePath screenshot_directory;
196 if (!GetScreenshotDirectory(&screenshot_directory)) 124 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
197 return; 125 return;
198 126
199 std::string screenshot_basename = GetScreenshotBaseFilename(); 127 std::string screenshot_basename =
128 ScreenshotSource::GetScreenshotBaseFilename();
200 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows(); 129 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows();
201 for (size_t i = 0; i < root_windows.size(); ++i) { 130 for (size_t i = 0; i < root_windows.size(); ++i) {
202 aura::RootWindow* root_window = root_windows[i]; 131 aura::RootWindow* root_window = root_windows[i];
203 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 132 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
204 std::string basename = screenshot_basename; 133 std::string basename = screenshot_basename;
205 gfx::Rect rect = root_window->bounds(); 134 gfx::Rect rect = root_window->bounds();
206 if (root_windows.size() > 1) 135 if (root_windows.size() > 1)
207 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); 136 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1));
208 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) { 137 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) {
209 DisplayVisualFeedback(rect); 138 DisplayVisualFeedback(rect);
210 PostSaveScreenshotTask( 139 PostSaveScreenshotTask(
211 screenshot_directory.AppendASCII(basename + ".png"), png_data); 140 screenshot_directory.AppendASCII(basename + ".png"), png_data);
212 } else { 141 } else {
213 LOG(ERROR) << "Failed to grab the window screenshot for " << i; 142 LOG(ERROR) << "Failed to grab the window screenshot for " << i;
214 } 143 }
215 } 144 }
216 last_screenshot_timestamp_ = base::Time::Now(); 145 last_screenshot_timestamp_ = base::Time::Now();
217 } 146 }
218 147
219 void ScreenshotTaker::HandleTakePartialScreenshot( 148 void ScreenshotTaker::HandleTakePartialScreenshot(
220 aura::Window* window, const gfx::Rect& rect) { 149 aura::Window* window, const gfx::Rect& rect) {
221 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 150 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
222 151
223 FilePath screenshot_directory; 152 FilePath screenshot_directory;
224 if (!GetScreenshotDirectory(&screenshot_directory)) 153 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
225 return; 154 return;
226 155
227 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 156 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
228 157
229 if (GrabWindowSnapshot(window, rect, &png_data->data())) { 158 if (GrabWindowSnapshot(window, rect, &png_data->data())) {
230 last_screenshot_timestamp_ = base::Time::Now(); 159 last_screenshot_timestamp_ = base::Time::Now();
231 DisplayVisualFeedback(rect); 160 DisplayVisualFeedback(rect);
232 PostSaveScreenshotTask( 161 PostSaveScreenshotTask(
233 screenshot_directory.AppendASCII(GetScreenshotBaseFilename() + ".png"), 162 screenshot_directory.AppendASCII(
234 png_data); 163 ScreenshotSource::GetScreenshotBaseFilename() + ".png"),
164 png_data);
235 } else { 165 } else {
236 LOG(ERROR) << "Failed to grab the window screenshot"; 166 LOG(ERROR) << "Failed to grab the window screenshot";
237 } 167 }
238 } 168 }
239 169
240 bool ScreenshotTaker::CanTakeScreenshot() { 170 bool ScreenshotTaker::CanTakeScreenshot() {
241 return last_screenshot_timestamp_.is_null() || 171 return last_screenshot_timestamp_.is_null() ||
242 base::Time::Now() - last_screenshot_timestamp_ > 172 base::Time::Now() - last_screenshot_timestamp_ >
243 base::TimeDelta::FromMilliseconds( 173 base::TimeDelta::FromMilliseconds(
244 kScreenshotMinimumIntervalInMS); 174 kScreenshotMinimumIntervalInMS);
(...skipping 14 matching lines...) Expand all
259 ash::internal::kShellWindowId_OverlayContainer)->layer(); 189 ash::internal::kShellWindowId_OverlayContainer)->layer();
260 parent->Add(visual_feedback_layer_.get()); 190 parent->Add(visual_feedback_layer_.get());
261 visual_feedback_layer_->SetVisible(true); 191 visual_feedback_layer_->SetVisible(true);
262 192
263 MessageLoopForUI::current()->PostDelayedTask( 193 MessageLoopForUI::current()->PostDelayedTask(
264 FROM_HERE, 194 FROM_HERE,
265 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer, 195 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer,
266 base::Unretained(this)), 196 base::Unretained(this)),
267 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs)); 197 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs));
268 } 198 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/webui/screenshot_source.h » ('j') | chrome/browser/ui/webui/screenshot_source.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698