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

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: requested changes 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/drive_file_system_util.h" 30 #include "chrome/browser/chromeos/gdata/drive_file_system_util.h"
34 #include "chrome/browser/chromeos/login/user_manager.h" 31 #include "chrome/browser/chromeos/login/user_manager.h"
32 #include "chrome/browser/chromeos/gdata/gdata_util.h"
csilv 2012/09/13 05:32:17 nit: swap order of lines 31 & 32 for alphabetical
35 #endif 33 #endif
36 34
37 namespace { 35 namespace {
38 // How opaque should the layer that we flash onscreen to provide visual 36 // How opaque should the layer that we flash onscreen to provide visual
39 // feedback after the screenshot is taken be? 37 // feedback after the screenshot is taken be?
40 const float kVisualFeedbackLayerOpacity = 0.25f; 38 const float kVisualFeedbackLayerOpacity = 0.25f;
41 39
42 // How long should the visual feedback layer be displayed? 40 // How long should the visual feedback layer be displayed?
43 const int64 kVisualFeedbackLayerDisplayTimeMs = 100; 41 const int64 kVisualFeedbackLayerDisplayTimeMs = 100;
44 42
45 // The minimum interval between two screenshot commands. It has to be 43 // The minimum interval between two screenshot commands. It has to be
46 // more than 1000 to prevent the conflict of filenames. 44 // more than 1000 to prevent the conflict of filenames.
47 const int kScreenshotMinimumIntervalInMS = 1000; 45 const int kScreenshotMinimumIntervalInMS = 1000;
48 46
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 47
118 void SaveScreenshot(const FilePath& screenshot_path, 48 void SaveScreenshot(const FilePath& screenshot_path,
119 scoped_refptr<base::RefCountedBytes> png_data) { 49 scoped_refptr<base::RefCountedBytes> png_data) {
120 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 50 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
121 DCHECK(!screenshot_path.empty()); 51 DCHECK(!screenshot_path.empty());
122 if (static_cast<size_t>(file_util::WriteFile( 52 if (static_cast<size_t>(file_util::WriteFile(
123 screenshot_path, 53 screenshot_path,
124 reinterpret_cast<char*>(&(png_data->data()[0])), 54 reinterpret_cast<char*>(&(png_data->data()[0])),
125 png_data->size())) != png_data->size()) { 55 png_data->size())) != png_data->size()) {
126 LOG(ERROR) << "Failed to save to " << screenshot_path.value(); 56 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)); 93 base::Bind(&SaveScreenshot, screenshot_path, png_data));
164 } 94 }
165 #endif 95 #endif
166 96
167 bool GrabWindowSnapshot(aura::Window* window, 97 bool GrabWindowSnapshot(aura::Window* window,
168 const gfx::Rect& snapshot_bounds, 98 const gfx::Rect& snapshot_bounds,
169 std::vector<unsigned char>* png_data) { 99 std::vector<unsigned char>* png_data) {
170 #if defined(OS_LINUX) 100 #if defined(OS_LINUX)
171 // chrome::GrabWindowSnapshotForUser checks this too, but 101 // chrome::GrabWindowSnapshotForUser checks this too, but
172 // RootWindow::GrabSnapshot does not. 102 // RootWindow::GrabSnapshot does not.
173 if (AreScreenshotsDisabled()) 103 if (ScreenshotSource::AreScreenshotsDisabled())
174 return false; 104 return false;
175 105
176 // We use XGetImage() for Linux/ChromeOS for performance reasons. 106 // We use XGetImage() for Linux/ChromeOS for performance reasons.
177 // See crbug.com/119492 107 // See crbug.com/119492
178 // TODO(mukai): remove this when the performance issue has been fixed. 108 // TODO(mukai): remove this when the performance issue has been fixed.
179 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data)) 109 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data))
180 return true; 110 return true;
181 #endif // OS_LINUX 111 #endif // OS_LINUX
182 112
183 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds); 113 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds);
184 } 114 }
185 115
186 } // namespace 116 } // namespace
187 117
188 ScreenshotTaker::ScreenshotTaker() { 118 ScreenshotTaker::ScreenshotTaker() {
189 } 119 }
190 120
191 ScreenshotTaker::~ScreenshotTaker() { 121 ScreenshotTaker::~ScreenshotTaker() {
192 } 122 }
193 123
194 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() { 124 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() {
195 FilePath screenshot_directory; 125 FilePath screenshot_directory;
196 if (!GetScreenshotDirectory(&screenshot_directory)) 126 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
197 return; 127 return;
198 128
199 std::string screenshot_basename = GetScreenshotBaseFilename(); 129 std::string screenshot_basename =
130 ScreenshotSource::GetScreenshotBaseFilename();
200 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows(); 131 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows();
201 for (size_t i = 0; i < root_windows.size(); ++i) { 132 for (size_t i = 0; i < root_windows.size(); ++i) {
202 aura::RootWindow* root_window = root_windows[i]; 133 aura::RootWindow* root_window = root_windows[i];
203 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 134 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
204 std::string basename = screenshot_basename; 135 std::string basename = screenshot_basename;
205 gfx::Rect rect = root_window->bounds(); 136 gfx::Rect rect = root_window->bounds();
206 if (root_windows.size() > 1) 137 if (root_windows.size() > 1)
207 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); 138 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1));
208 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) { 139 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) {
209 DisplayVisualFeedback(rect); 140 DisplayVisualFeedback(rect);
210 PostSaveScreenshotTask( 141 PostSaveScreenshotTask(
211 screenshot_directory.AppendASCII(basename + ".png"), png_data); 142 screenshot_directory.AppendASCII(basename + ".png"), png_data);
212 } else { 143 } else {
213 LOG(ERROR) << "Failed to grab the window screenshot for " << i; 144 LOG(ERROR) << "Failed to grab the window screenshot for " << i;
214 } 145 }
215 } 146 }
216 last_screenshot_timestamp_ = base::Time::Now(); 147 last_screenshot_timestamp_ = base::Time::Now();
217 } 148 }
218 149
219 void ScreenshotTaker::HandleTakePartialScreenshot( 150 void ScreenshotTaker::HandleTakePartialScreenshot(
220 aura::Window* window, const gfx::Rect& rect) { 151 aura::Window* window, const gfx::Rect& rect) {
221 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 152 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
222 153
223 FilePath screenshot_directory; 154 FilePath screenshot_directory;
224 if (!GetScreenshotDirectory(&screenshot_directory)) 155 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
225 return; 156 return;
226 157
227 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 158 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
228 159
229 if (GrabWindowSnapshot(window, rect, &png_data->data())) { 160 if (GrabWindowSnapshot(window, rect, &png_data->data())) {
230 last_screenshot_timestamp_ = base::Time::Now(); 161 last_screenshot_timestamp_ = base::Time::Now();
231 DisplayVisualFeedback(rect); 162 DisplayVisualFeedback(rect);
232 PostSaveScreenshotTask( 163 PostSaveScreenshotTask(
233 screenshot_directory.AppendASCII(GetScreenshotBaseFilename() + ".png"), 164 screenshot_directory.AppendASCII(
234 png_data); 165 ScreenshotSource::GetScreenshotBaseFilename() + ".png"),
166 png_data);
235 } else { 167 } else {
236 LOG(ERROR) << "Failed to grab the window screenshot"; 168 LOG(ERROR) << "Failed to grab the window screenshot";
237 } 169 }
238 } 170 }
239 171
240 bool ScreenshotTaker::CanTakeScreenshot() { 172 bool ScreenshotTaker::CanTakeScreenshot() {
241 return last_screenshot_timestamp_.is_null() || 173 return last_screenshot_timestamp_.is_null() ||
242 base::Time::Now() - last_screenshot_timestamp_ > 174 base::Time::Now() - last_screenshot_timestamp_ >
243 base::TimeDelta::FromMilliseconds( 175 base::TimeDelta::FromMilliseconds(
244 kScreenshotMinimumIntervalInMS); 176 kScreenshotMinimumIntervalInMS);
(...skipping 14 matching lines...) Expand all
259 ash::internal::kShellWindowId_OverlayContainer)->layer(); 191 ash::internal::kShellWindowId_OverlayContainer)->layer();
260 parent->Add(visual_feedback_layer_.get()); 192 parent->Add(visual_feedback_layer_.get());
261 visual_feedback_layer_->SetVisible(true); 193 visual_feedback_layer_->SetVisible(true);
262 194
263 MessageLoopForUI::current()->PostDelayedTask( 195 MessageLoopForUI::current()->PostDelayedTask(
264 FROM_HERE, 196 FROM_HERE,
265 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer, 197 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer,
266 base::Unretained(this)), 198 base::Unretained(this)),
267 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs)); 199 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs));
268 } 200 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/webui/feedback_ui.cc » ('j') | chrome/browser/ui/webui/screenshot_source.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698