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

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

Issue 10830179: gdata: Save screenshot to /drive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add bug ID. Created 8 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 12 matching lines...) Expand all
23 #include "chrome/browser/prefs/pref_service.h" 23 #include "chrome/browser/prefs/pref_service.h"
24 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/profiles/profile_manager.h" 25 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/browser/ui/window_snapshot/window_snapshot.h" 26 #include "chrome/browser/ui/window_snapshot/window_snapshot.h"
27 #include "chrome/common/pref_names.h" 27 #include "chrome/common/pref_names.h"
28 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
29 #include "ui/aura/root_window.h" 29 #include "ui/aura/root_window.h"
30 #include "ui/aura/window.h" 30 #include "ui/aura/window.h"
31 31
32 #if defined(OS_CHROMEOS) 32 #if defined(OS_CHROMEOS)
33 #include "chrome/browser/chromeos/gdata/gdata_util.h"
33 #include "chrome/browser/chromeos/login/user_manager.h" 34 #include "chrome/browser/chromeos/login/user_manager.h"
34 #endif 35 #endif
35 36
36 namespace { 37 namespace {
37 const int kScreenshotMinimumIntervalInMS = 500; 38 const int kScreenshotMinimumIntervalInMS = 500;
38 39
39 bool ShouldUse24HourClock() { 40 bool ShouldUse24HourClock() {
40 #if defined(OS_CHROMEOS) 41 #if defined(OS_CHROMEOS)
41 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 42 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
42 if (profile) { 43 if (profile) {
43 PrefService* pref_service = profile->GetPrefs(); 44 PrefService* pref_service = profile->GetPrefs();
44 if (pref_service) { 45 if (pref_service) {
45 return pref_service->GetBoolean(prefs::kUse24HourClock); 46 return pref_service->GetBoolean(prefs::kUse24HourClock);
46 } 47 }
47 } 48 }
48 #endif 49 #endif
49 return base::GetHourClockType() == base::k24HourClock; 50 return base::GetHourClockType() == base::k24HourClock;
50 } 51 }
51 52
52 FilePath GetScreenshotPath(const FilePath& base_directory, 53 std::string GetScreenShotBaseFilename(bool use_24hour_clock) {
53 bool use_24hour_clock) {
54 base::Time::Exploded now; 54 base::Time::Exploded now;
55 base::Time::Now().LocalExplode(&now); 55 base::Time::Now().LocalExplode(&now);
56 56
57 // We don't use base/i18n/time_formatting.h here because it doesn't 57 // We don't use base/i18n/time_formatting.h here because it doesn't
58 // support our format. Don't use ICU either to avoid i18n file names 58 // support our format. Don't use ICU either to avoid i18n file names
59 // for non-English locales. 59 // for non-English locales.
60 // TODO(mukai): integrate this logic somewhere time_formatting.h 60 // TODO(mukai): integrate this logic somewhere time_formatting.h
61 std::string file_name = base::StringPrintf( 61 std::string file_name = base::StringPrintf(
62 "Screenshot %d-%02d-%02d ", now.year, now.month, now.day_of_month); 62 "Screenshot %d-%02d-%02d ", now.year, now.month, now.day_of_month);
63 63
64 if (use_24hour_clock) { 64 if (use_24hour_clock) {
65 file_name.append(base::StringPrintf( 65 file_name.append(base::StringPrintf(
66 "%02d:%02d:%02d", now.hour, now.minute, now.second)); 66 "%02d:%02d:%02d", now.hour, now.minute, now.second));
67 } else { 67 } else {
68 int hour = now.hour; 68 int hour = now.hour;
69 if (hour > 12) { 69 if (hour > 12) {
70 hour -= 12; 70 hour -= 12;
71 } else if (hour == 0) { 71 } else if (hour == 0) {
72 hour = 12; 72 hour = 12;
73 } 73 }
74 file_name.append(base::StringPrintf( 74 file_name.append(base::StringPrintf(
75 "%d:%02d:%02d ", hour, now.minute, now.second)); 75 "%d:%02d:%02d ", hour, now.minute, now.second));
76 file_name.append((now.hour >= 12) ? "PM" : "AM"); 76 file_name.append((now.hour >= 12) ? "PM" : "AM");
77 } 77 }
78 78
79 return file_name;
80 }
81
82 FilePath GetScreenshotPath(const FilePath& base_directory,
83 const std::string& base_name) {
84 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
79 for (int retry = 0; retry < INT_MAX; retry++) { 85 for (int retry = 0; retry < INT_MAX; retry++) {
80 std::string retry_suffix; 86 std::string retry_suffix;
81 if (retry > 0) 87 if (retry > 0)
82 retry_suffix = base::StringPrintf(" (%d)", retry + 1); 88 retry_suffix = base::StringPrintf(" (%d)", retry + 1);
83 89
84 FilePath file_path = base_directory.AppendASCII( 90 FilePath file_path = base_directory.AppendASCII(
85 file_name + retry_suffix + ".png"); 91 base_name + retry_suffix + ".png");
86 if (!file_util::PathExists(file_path)) 92 if (!file_util::PathExists(file_path))
87 return file_path; 93 return file_path;
88 } 94 }
89
90 return FilePath(); 95 return FilePath();
91 } 96 }
92 97
93 // |is_logged_in| is used only for ChromeOS. Otherwise it is always true. 98 void SaveScreenshotToLocalFile(scoped_refptr<base::RefCountedBytes> png_data,
94 void SaveScreenshot(const FilePath& screenshot_directory, 99 const FilePath& screenshot_path) {
95 bool use_24hour_clock,
96 scoped_refptr<base::RefCountedBytes> png_data) {
97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 100 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
98
99 FilePath screenshot_path = GetScreenshotPath(
100 screenshot_directory, use_24hour_clock);
101
102 if (screenshot_path.empty()) {
103 LOG(ERROR) << "Failed to find a screenshot file name.";
104 return;
105 }
106
107 if (static_cast<size_t>(file_util::WriteFile( 101 if (static_cast<size_t>(file_util::WriteFile(
108 screenshot_path, 102 screenshot_path,
109 reinterpret_cast<char*>(&(png_data->data()[0])), 103 reinterpret_cast<char*>(&(png_data->data()[0])),
110 png_data->size())) != png_data->size()) { 104 png_data->size())) != png_data->size()) {
111 LOG(ERROR) << "Failed to save to " << screenshot_path.value(); 105 LOG(ERROR) << "Failed to save to " << screenshot_path.value();
112 } 106 }
113 } 107 }
114 108
109 void SaveScreenshot(const FilePath& screenshot_directory,
110 const std::string& base_name,
111 scoped_refptr<base::RefCountedBytes> png_data) {
112 FilePath screenshot_path = GetScreenshotPath(screenshot_directory, base_name);
113 if (screenshot_path.empty()) {
114 LOG(ERROR) << "Failed to find a screenshot file name.";
115 return;
116 }
117 SaveScreenshotToLocalFile(png_data, screenshot_path);
118 }
119
120 // TODO(kinaba): crbug.com/140425, remove this ungly #ifdef dispatch.
121 #ifdef OS_CHROMEOS
122 void SaveScreenshotToGData(scoped_refptr<base::RefCountedBytes> png_data,
123 gdata::GDataFileError error,
124 const FilePath& local_path) {
125 if (error != gdata::GDATA_FILE_OK) {
126 LOG(ERROR) << "Failed to write screenshot image to Google Drive: " << error;
127 return;
128 }
129 SaveScreenshotToLocalFile(png_data, local_path);
130 }
131
132 void PostSaveScreenshotTask(const FilePath& screenshot_directory,
133 const std::string& base_name,
134 scoped_refptr<base::RefCountedBytes> png_data) {
135 if (gdata::util::IsUnderGDataMountPoint(screenshot_directory)) {
136 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
137 if (profile) {
138 // TODO(kinaba,mukai): crbug.com/140749. Take care of the case
139 // "base_name.png" already exists.
140 gdata::util::PrepareWritableFileAndRun(
141 profile,
142 screenshot_directory.Append(base_name + ".png"),
143 base::Bind(&SaveScreenshotToGData, png_data));
144 }
145 } else {
146 content::BrowserThread::PostTask(
147 content::BrowserThread::FILE, FROM_HERE,
148 base::Bind(&SaveScreenshot, screenshot_directory, base_name, png_data));
149 }
150 }
151 #else
152 void PostSaveScreenshotTask(const FilePath& screenshot_directory,
153 const std::string& base_name,
154 scoped_refptr<base::RefCountedBytes> png_data) {
155 content::BrowserThread::PostTask(
156 content::BrowserThread::FILE, FROM_HERE,
157 base::Bind(&SaveScreenshot, screenshot_directory, base_name, png_data));
158 }
159 #endif
160
115 bool AreScreenshotsDisabled() { 161 bool AreScreenshotsDisabled() {
116 return g_browser_process->local_state()->GetBoolean( 162 return g_browser_process->local_state()->GetBoolean(
117 prefs::kDisableScreenshots); 163 prefs::kDisableScreenshots);
118 } 164 }
119 165
120 bool GrabWindowSnapshot(aura::Window* window, 166 bool GrabWindowSnapshot(aura::Window* window,
121 const gfx::Rect& snapshot_bounds, 167 const gfx::Rect& snapshot_bounds,
122 std::vector<unsigned char>* png_data) { 168 std::vector<unsigned char>* png_data) {
123 #if defined(OS_LINUX) 169 #if defined(OS_LINUX)
124 // browser::GrabWindowSnapshot checks this too, but RootWindow::GrabSnapshot 170 // browser::GrabWindowSnapshot checks this too, but RootWindow::GrabSnapshot
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext( 221 DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
176 ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext()); 222 ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
177 screenshot_directory = download_prefs->DownloadPath(); 223 screenshot_directory = download_prefs->DownloadPath();
178 } else { 224 } else {
179 if (!file_util::GetTempDir(&screenshot_directory)) { 225 if (!file_util::GetTempDir(&screenshot_directory)) {
180 LOG(ERROR) << "Failed to find temporary directory."; 226 LOG(ERROR) << "Failed to find temporary directory.";
181 return; 227 return;
182 } 228 }
183 } 229 }
184 230
185 bool use_24hour_clock = ShouldUse24HourClock();
186
187 if (GrabWindowSnapshot(window, rect, &png_data->data())) { 231 if (GrabWindowSnapshot(window, rect, &png_data->data())) {
188 last_screenshot_timestamp_ = base::Time::Now(); 232 last_screenshot_timestamp_ = base::Time::Now();
189 DisplayVisualFeedback(rect); 233 DisplayVisualFeedback(rect);
190 content::BrowserThread::PostTask( 234 PostSaveScreenshotTask(screenshot_directory,
191 content::BrowserThread::FILE, FROM_HERE, 235 GetScreenShotBaseFilename(ShouldUse24HourClock()),
192 base::Bind(&SaveScreenshot, screenshot_directory, use_24hour_clock, 236 png_data);
193 png_data));
194 } else { 237 } else {
195 LOG(ERROR) << "Failed to grab the window screenshot"; 238 LOG(ERROR) << "Failed to grab the window screenshot";
196 } 239 }
197 } 240 }
198 241
199 bool ScreenshotTaker::CanTakeScreenshot() { 242 bool ScreenshotTaker::CanTakeScreenshot() {
200 return last_screenshot_timestamp_.is_null() || 243 return last_screenshot_timestamp_.is_null() ||
201 base::Time::Now() - last_screenshot_timestamp_ > 244 base::Time::Now() - last_screenshot_timestamp_ >
202 base::TimeDelta::FromMilliseconds( 245 base::TimeDelta::FromMilliseconds(
203 kScreenshotMinimumIntervalInMS); 246 kScreenshotMinimumIntervalInMS);
(...skipping 14 matching lines...) Expand all
218 ash::internal::kShellWindowId_OverlayContainer)->layer(); 261 ash::internal::kShellWindowId_OverlayContainer)->layer();
219 parent->Add(visual_feedback_layer_.get()); 262 parent->Add(visual_feedback_layer_.get());
220 visual_feedback_layer_->SetVisible(true); 263 visual_feedback_layer_->SetVisible(true);
221 264
222 MessageLoopForUI::current()->PostDelayedTask( 265 MessageLoopForUI::current()->PostDelayedTask(
223 FROM_HERE, 266 FROM_HERE,
224 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer, 267 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer,
225 base::Unretained(this)), 268 base::Unretained(this)),
226 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs)); 269 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs));
227 } 270 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698