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

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

Issue 13105002: Screenshot effect non-obvious (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 8 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
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_util.h" 14 #include "base/file_util.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/ref_counted_memory.h" 17 #include "base/memory/ref_counted_memory.h"
18 #include "base/stringprintf.h" 18 #include "base/stringprintf.h"
19 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/sequenced_worker_pool.h"
20 #include "base/time.h" 20 #include "base/time.h"
21 #include "base/utf_string_conversions.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/chromeos/extensions/file_manager_util.h"
21 #include "chrome/browser/download/download_prefs.h" 24 #include "chrome/browser/download/download_prefs.h"
25 #include "chrome/browser/notifications/notification.h"
26 #include "chrome/browser/notifications/notification_ui_manager.h"
22 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/profiles/profile_manager.h" 28 #include "chrome/browser/profiles/profile_manager.h"
24 #include "chrome/browser/ui/webui/screenshot_source.h" 29 #include "chrome/browser/ui/webui/screenshot_source.h"
25 #include "chrome/browser/ui/window_snapshot/window_snapshot.h" 30 #include "chrome/browser/ui/window_snapshot/window_snapshot.h"
26 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
32 #include "grit/ash_strings.h"
33 #include "grit/theme_resources.h"
27 #include "ui/aura/root_window.h" 34 #include "ui/aura/root_window.h"
28 #include "ui/aura/window.h" 35 #include "ui/aura/window.h"
36 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/resource/resource_bundle.h"
29 38
30 #if defined(OS_CHROMEOS) 39 #if defined(OS_CHROMEOS)
31 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" 40 #include "chrome/browser/chromeos/drive/drive_file_system_util.h"
32 #include "chrome/browser/chromeos/login/user_manager.h" 41 #include "chrome/browser/chromeos/login/user_manager.h"
33 #endif 42 #endif
34 43
35 namespace { 44 namespace {
36 // How opaque should the layer that we flash onscreen to provide visual 45 // How opaque should the layer that we flash onscreen to provide visual
37 // feedback after the screenshot is taken be? 46 // feedback after the screenshot is taken be?
38 const float kVisualFeedbackLayerOpacity = 0.25f; 47 const float kVisualFeedbackLayerOpacity = 0.25f;
James Cook 2013/03/26 23:54:25 Is this still needed?
sschmitz 2013/03/27 14:58:49 no; removed
39 48
40 // How long should the visual feedback layer be displayed? 49 // How long should the visual feedback layer be displayed?
41 const int64 kVisualFeedbackLayerDisplayTimeMs = 100; 50 const int64 kVisualFeedbackLayerDisplayTimeMs = 100;
James Cook 2013/03/26 23:54:25 Ditto
sschmitz 2013/03/27 14:58:49 Done.
42 51
43 // The minimum interval between two screenshot commands. It has to be 52 // The minimum interval between two screenshot commands. It has to be
44 // more than 1000 to prevent the conflict of filenames. 53 // more than 1000 to prevent the conflict of filenames.
45 const int kScreenshotMinimumIntervalInMS = 1000; 54 const int kScreenshotMinimumIntervalInMS = 1000;
46 55
56 // Origin URL for notifications.
57 const GURL kNotificationOriginUrl("chrome://screenshot/");
47 58
48 void SaveScreenshotInternal(const base::FilePath& screenshot_path, 59 void PostNotification(base::WeakPtr<ScreenshotTaker> screenshot_taker,
60 bool success,
61 const base::FilePath& screenshot_path) {
62 #if defined(OS_CHROMEOS)
63 // Notifications only on Chrome OS.
64 content::BrowserThread::PostTask(
65 content::BrowserThread::UI,
66 FROM_HERE,
67 base::Bind(&ScreenshotTaker::ShowNotification,
68 screenshot_taker,
69 success,
70 screenshot_path));
71 #endif
72 }
73
74 void SaveScreenshotInternal(base::WeakPtr<ScreenshotTaker> screenshot_taker,
75 const base::FilePath& screenshot_path,
49 scoped_refptr<base::RefCountedBytes> png_data) { 76 scoped_refptr<base::RefCountedBytes> png_data) {
50 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 77 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
51 DCHECK(!screenshot_path.empty()); 78 DCHECK(!screenshot_path.empty());
79 bool success = true;
52 if (static_cast<size_t>(file_util::WriteFile( 80 if (static_cast<size_t>(file_util::WriteFile(
53 screenshot_path, 81 screenshot_path,
54 reinterpret_cast<char*>(&(png_data->data()[0])), 82 reinterpret_cast<char*>(&(png_data->data()[0])),
55 png_data->size())) != png_data->size()) { 83 png_data->size())) != png_data->size()) {
56 LOG(ERROR) << "Failed to save to " << screenshot_path.value(); 84 LOG(ERROR) << "Failed to save to " << screenshot_path.value();
85 success = false;
57 } 86 }
87 PostNotification(screenshot_taker, success, screenshot_path);
58 } 88 }
59 89
60 void SaveScreenshot(const base::FilePath& screenshot_path, 90 void SaveScreenshot(base::WeakPtr<ScreenshotTaker> screenshot_taker,
91 const base::FilePath& screenshot_path,
61 scoped_refptr<base::RefCountedBytes> png_data) { 92 scoped_refptr<base::RefCountedBytes> png_data) {
62 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 93 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
63 DCHECK(!screenshot_path.empty()); 94 DCHECK(!screenshot_path.empty());
64 95
65 if (!file_util::CreateDirectory(screenshot_path.DirName())) { 96 if (!file_util::CreateDirectory(screenshot_path.DirName())) {
66 LOG(ERROR) << "Failed to ensure the existence of " 97 LOG(ERROR) << "Failed to ensure the existence of "
67 << screenshot_path.DirName().value(); 98 << screenshot_path.DirName().value();
99 PostNotification(screenshot_taker, false, screenshot_path);
68 return; 100 return;
69 } 101 }
70 SaveScreenshotInternal(screenshot_path, png_data); 102 SaveScreenshotInternal(screenshot_taker, screenshot_path, png_data);
71 } 103 }
72 104
73 // TODO(kinaba): crbug.com/140425, remove this ungly #ifdef dispatch. 105 // TODO(kinaba): crbug.com/140425, remove this ungly #ifdef dispatch.
74 #if defined(OS_CHROMEOS) 106 #if defined(OS_CHROMEOS)
75 void SaveScreenshotToDrive(scoped_refptr<base::RefCountedBytes> png_data, 107 void SaveScreenshotToDrive(base::WeakPtr<ScreenshotTaker> screenshot_taker,
108 scoped_refptr<base::RefCountedBytes> png_data,
76 drive::DriveFileError error, 109 drive::DriveFileError error,
77 const base::FilePath& local_path) { 110 const base::FilePath& local_path) {
78 if (error != drive::DRIVE_FILE_OK) { 111 if (error != drive::DRIVE_FILE_OK) {
79 LOG(ERROR) << "Failed to write screenshot image to Google Drive: " << error; 112 LOG(ERROR) << "Failed to write screenshot image to Google Drive: " << error;
113 PostNotification(screenshot_taker, false, local_path);
80 return; 114 return;
81 } 115 }
82 SaveScreenshotInternal(local_path, png_data); 116 SaveScreenshotInternal(screenshot_taker, local_path, png_data);
83 } 117 }
84 118
85 void EnsureDirectoryExistsCallback( 119 void EnsureDirectoryExistsCallback(
120 base::WeakPtr<ScreenshotTaker> screenshot_taker,
86 Profile* profile, 121 Profile* profile,
87 const base::FilePath& screenshot_path, 122 const base::FilePath& screenshot_path,
88 scoped_refptr<base::RefCountedBytes> png_data, 123 scoped_refptr<base::RefCountedBytes> png_data,
89 drive::DriveFileError error) { 124 drive::DriveFileError error) {
90 // It is okay to fail with DRIVE_FILE_ERROR_EXISTS since anyway the directory 125 // It is okay to fail with DRIVE_FILE_ERROR_EXISTS since anyway the directory
91 // of the target file exists. 126 // of the target file exists.
92 if (error == drive::DRIVE_FILE_OK || 127 if (error == drive::DRIVE_FILE_OK ||
93 error == drive::DRIVE_FILE_ERROR_EXISTS) { 128 error == drive::DRIVE_FILE_ERROR_EXISTS) {
129 // Note: The last two arguments of SaveScreenshotToDrive are appended by
130 // PrepareWritableFileAndRun.
94 drive::util::PrepareWritableFileAndRun( 131 drive::util::PrepareWritableFileAndRun(
95 profile, 132 profile,
96 screenshot_path, 133 screenshot_path,
97 base::Bind(&SaveScreenshotToDrive, png_data)); 134 base::Bind(&SaveScreenshotToDrive, screenshot_taker, png_data));
98 } else { 135 } else {
99 LOG(ERROR) << "Failed to ensure the existence of the specified directory " 136 LOG(ERROR) << "Failed to ensure the existence of the specified directory "
100 << "in Google Drive: " << error; 137 << "in Google Drive: " << error;
138 PostNotification(screenshot_taker, false, screenshot_path);
101 } 139 }
102 } 140 }
103 141
104 void PostSaveScreenshotTask(const base::FilePath& screenshot_path, 142 void PostSaveScreenshotTask(base::WeakPtr<ScreenshotTaker> screenshot_taker,
143 const base::FilePath& screenshot_path,
105 scoped_refptr<base::RefCountedBytes> png_data) { 144 scoped_refptr<base::RefCountedBytes> png_data) {
106 if (drive::util::IsUnderDriveMountPoint(screenshot_path)) { 145 if (drive::util::IsUnderDriveMountPoint(screenshot_path)) {
107 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 146 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
108 if (profile) { 147 if (profile) {
148 // Note: The last argument of EnsureDirectoryExistsCallback is
149 // appended by EnsureDirectoryExists.
109 drive::util::EnsureDirectoryExists( 150 drive::util::EnsureDirectoryExists(
110 profile, 151 profile,
111 screenshot_path.DirName(), 152 screenshot_path.DirName(),
112 base::Bind(&EnsureDirectoryExistsCallback, 153 base::Bind(&EnsureDirectoryExistsCallback,
154 screenshot_taker,
113 profile, 155 profile,
114 screenshot_path, 156 screenshot_path,
115 png_data)); 157 png_data));
116 } 158 }
117 } else { 159 } else {
118 content::BrowserThread::GetBlockingPool()->PostTask( 160 content::BrowserThread::GetBlockingPool()->PostTask(
119 FROM_HERE, base::Bind(&SaveScreenshot, screenshot_path, png_data)); 161 FROM_HERE, base::Bind(&SaveScreenshot,
162 screenshot_taker,
163 screenshot_path,
164 png_data));
120 } 165 }
121 } 166 }
122 #else 167 #else
123 void PostSaveScreenshotTask(const base::FilePath& screenshot_path, 168 void PostSaveScreenshotTask(base::WeakPtr<ScreenshotTaker> screenshot_taker,
169 const base::FilePath& screenshot_path,
124 scoped_refptr<base::RefCountedBytes> png_data) { 170 scoped_refptr<base::RefCountedBytes> png_data) {
125 content::BrowserThread::GetBlockingPool()->PostTask( 171 content::BrowserThread::GetBlockingPool()->PostTask(
126 FROM_HERE, base::Bind(&SaveScreenshot, screenshot_path, png_data)); 172 FROM_HERE, base::Bind(&SaveScreenshot,
173 screenshot_taker,
174 screenshot_path,
175 png_data)):
176
127 } 177 }
128 #endif 178 #endif
129 179
130 bool GrabWindowSnapshot(aura::Window* window, 180 bool GrabWindowSnapshot(aura::Window* window,
131 const gfx::Rect& snapshot_bounds, 181 const gfx::Rect& snapshot_bounds,
132 std::vector<unsigned char>* png_data) { 182 std::vector<unsigned char>* png_data) {
133 #if defined(OS_LINUX) 183 #if defined(OS_LINUX)
134 // chrome::GrabWindowSnapshotForUser checks this too, but 184 // chrome::GrabWindowSnapshotForUser checks this too, but
135 // RootWindow::GrabSnapshot does not. 185 // RootWindow::GrabSnapshot does not.
136 if (ScreenshotSource::AreScreenshotsDisabled()) 186 if (ScreenshotSource::AreScreenshotsDisabled())
137 return false; 187 return false;
138 188
139 // We use XGetImage() for Linux/ChromeOS for performance reasons. 189 // We use XGetImage() for Linux/ChromeOS for performance reasons.
140 // See crbug.com/119492 190 // See crbug.com/119492
141 // TODO(mukai): remove this when the performance issue has been fixed. 191 // TODO(mukai): remove this when the performance issue has been fixed.
142 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data)) 192 if (window->GetRootWindow()->GrabSnapshot(snapshot_bounds, png_data))
143 return true; 193 return true;
144 #endif // OS_LINUX 194 #endif // OS_LINUX
145 195
146 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds); 196 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds);
147 } 197 }
148 198
149 } // namespace 199 } // namespace
150 200
151 ScreenshotTaker::ScreenshotTaker() { 201 ScreenshotTaker::ScreenshotTaker()
202 : ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)),
203 notification_id_(0) {
204 #if defined(OS_CHROMEOS)
205 // Notifications only on Chrome OS.
206 notification_icon_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
207 IDR_SCREENSHOT_NOTIFICATION_ICON);
208 notification_title_success_ =
209 l10n_util::GetStringUTF16(IDS_ASH_SCREENSHOT_NOTIFICATION_TITLE_SUCCESS);
210 notification_title_fail_ =
211 l10n_util::GetStringUTF16(IDS_ASH_SCREENSHOT_NOTIFICATION_TITLE_FAIL);
212 notification_text_success_ =
213 l10n_util::GetStringUTF16(IDS_ASH_SCREENSHOT_NOTIFICATION_TEXT_SUCCESS);
214 notification_text_fail_ =
215 l10n_util::GetStringUTF16(IDS_ASH_SCREENSHOT_NOTIFICATION_TEXT_FAIL);
216 #endif
152 } 217 }
153 218
154 ScreenshotTaker::~ScreenshotTaker() { 219 ScreenshotTaker::~ScreenshotTaker() {
155 } 220 }
156 221
157 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() { 222 void ScreenshotTaker::HandleTakeScreenshotForAllRootWindows() {
158 base::FilePath screenshot_directory; 223 base::FilePath screenshot_directory;
159 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory)) 224 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
160 return; 225 return;
161 226
162 std::string screenshot_basename = 227 std::string screenshot_basename =
163 ScreenshotSource::GetScreenshotBaseFilename(); 228 ScreenshotSource::GetScreenshotBaseFilename();
164 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows(); 229 ash::Shell::RootWindowList root_windows = ash::Shell::GetAllRootWindows();
165 // Reorder root_windows to take the primary root window's snapshot at first. 230 // Reorder root_windows to take the primary root window's snapshot at first.
166 aura::RootWindow* primary_root = ash::Shell::GetPrimaryRootWindow(); 231 aura::RootWindow* primary_root = ash::Shell::GetPrimaryRootWindow();
167 if (*(root_windows.begin()) != primary_root) { 232 if (*(root_windows.begin()) != primary_root) {
168 root_windows.erase(std::find( 233 root_windows.erase(std::find(
169 root_windows.begin(), root_windows.end(), primary_root)); 234 root_windows.begin(), root_windows.end(), primary_root));
170 root_windows.insert(root_windows.begin(), primary_root); 235 root_windows.insert(root_windows.begin(), primary_root);
171 } 236 }
172 for (size_t i = 0; i < root_windows.size(); ++i) { 237 for (size_t i = 0; i < root_windows.size(); ++i) {
173 aura::RootWindow* root_window = root_windows[i]; 238 aura::RootWindow* root_window = root_windows[i];
174 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 239 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
175 std::string basename = screenshot_basename; 240 std::string basename = screenshot_basename;
176 gfx::Rect rect = root_window->bounds(); 241 gfx::Rect rect = root_window->bounds();
177 if (root_windows.size() > 1) 242 if (root_windows.size() > 1)
178 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); 243 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1));
244 base::FilePath screenshot_path =
245 screenshot_directory.AppendASCII(basename + ".png");
179 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) { 246 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) {
180 DisplayVisualFeedback(rect); 247 PostSaveScreenshotTask(factory_.GetWeakPtr(), screenshot_path, png_data);
181 PostSaveScreenshotTask(
182 screenshot_directory.AppendASCII(basename + ".png"), png_data);
183 } else { 248 } else {
184 LOG(ERROR) << "Failed to grab the window screenshot for " << i; 249 LOG(ERROR) << "Failed to grab the window screenshot for " << i;
250 PostNotification(factory_.GetWeakPtr(), false, screenshot_path);
185 } 251 }
186 } 252 }
187 last_screenshot_timestamp_ = base::Time::Now(); 253 last_screenshot_timestamp_ = base::Time::Now();
188 } 254 }
189 255
190 void ScreenshotTaker::HandleTakePartialScreenshot( 256 void ScreenshotTaker::HandleTakePartialScreenshot(
191 aura::Window* window, const gfx::Rect& rect) { 257 aura::Window* window, const gfx::Rect& rect) {
192 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 258 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
193 259
194 base::FilePath screenshot_directory; 260 base::FilePath screenshot_directory;
195 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory)) 261 if (!ScreenshotSource::GetScreenshotDirectory(&screenshot_directory))
196 return; 262 return;
197 263
198 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); 264 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
199 265
266 base::FilePath screenshot_path =
267 screenshot_directory.AppendASCII(
268 ScreenshotSource::GetScreenshotBaseFilename() + ".png");
200 if (GrabWindowSnapshot(window, rect, &png_data->data())) { 269 if (GrabWindowSnapshot(window, rect, &png_data->data())) {
201 last_screenshot_timestamp_ = base::Time::Now(); 270 last_screenshot_timestamp_ = base::Time::Now();
202 DisplayVisualFeedback(rect); 271 PostSaveScreenshotTask(factory_.GetWeakPtr(), screenshot_path, png_data);
203 PostSaveScreenshotTask(
204 screenshot_directory.AppendASCII(
205 ScreenshotSource::GetScreenshotBaseFilename() + ".png"),
206 png_data);
207 } else { 272 } else {
208 LOG(ERROR) << "Failed to grab the window screenshot"; 273 LOG(ERROR) << "Failed to grab the window screenshot";
274 PostNotification(factory_.GetWeakPtr(), false, screenshot_path);
209 } 275 }
210 } 276 }
211 277
212 bool ScreenshotTaker::CanTakeScreenshot() { 278 bool ScreenshotTaker::CanTakeScreenshot() {
213 return last_screenshot_timestamp_.is_null() || 279 return last_screenshot_timestamp_.is_null() ||
214 base::Time::Now() - last_screenshot_timestamp_ > 280 base::Time::Now() - last_screenshot_timestamp_ >
215 base::TimeDelta::FromMilliseconds( 281 base::TimeDelta::FromMilliseconds(
216 kScreenshotMinimumIntervalInMS); 282 kScreenshotMinimumIntervalInMS);
217 } 283 }
218 284
219 void ScreenshotTaker::CloseVisualFeedbackLayer() { 285 namespace {
James Cook 2013/03/26 23:54:25 Anonymous namespace goes at top of file.
sschmitz 2013/03/27 14:58:49 Done.
220 visual_feedback_layer_.reset(); 286 class Delegate : public NotificationDelegate {
James Cook 2013/03/26 23:54:25 Call this something other than "Delegate", maybe S
sschmitz 2013/03/27 14:58:49 Done.
287 public:
288 Delegate(const std::string& id_text,
289 bool success,
290 const base::FilePath& screenshot_path)
291 : id_text_(id_text),
292 success_(success),
293 screenshot_path_(screenshot_path) {
294 }
295
296 virtual void Display() OVERRIDE {}
297
298 virtual void Error() OVERRIDE {}
299
300 virtual void Close(bool by_user) OVERRIDE {}
301
302 virtual void Click() OVERRIDE {
303 if (success_)
304 file_manager_util::ShowFileInFolder(screenshot_path_);
305 }
306
307 virtual std::string id() const OVERRIDE { return id_text_; }
308
309 virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
310 return NULL;
311 }
312
313 private:
314 virtual ~Delegate() {}
315
316 std::string id_text_;
317 bool success_;
318 base::FilePath screenshot_path_;
319
320 DISALLOW_COPY_AND_ASSIGN(Delegate);
321 };
322 } // namespace
323
324 void ScreenshotTaker::ShowNotification(
James Cook 2013/03/26 23:54:25 Could you pass all the data you need as parameters
sschmitz 2013/03/27 14:58:49 Good point. I found a similar solution. The more o
325 bool success, const base::FilePath& screenshot_path) {
326 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
327 std::string id_text =
328 base::StringPrintf("screenshot_%3.3d", ++notification_id_);
329 string16 notification_replace_id = UTF8ToUTF16(id_text);
330 Notification notification(
331 kNotificationOriginUrl,
332 notification_icon_,
333 success ? notification_title_success_ : notification_title_fail_,
334 success ? notification_text_success_ : notification_text_fail_,
335 WebKit::WebTextDirectionDefault,
336 string16(), // display_source
337 notification_replace_id,
338 new Delegate(id_text, success, screenshot_path));
339 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
340 DCHECK(profile);
341 DCHECK(g_browser_process);
342 g_browser_process->notification_ui_manager()->Add(notification, profile);
221 } 343 }
222
223 void ScreenshotTaker::DisplayVisualFeedback(const gfx::Rect& rect) {
224 visual_feedback_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
225 visual_feedback_layer_->SetColor(SK_ColorWHITE);
226 visual_feedback_layer_->SetOpacity(kVisualFeedbackLayerOpacity);
227 visual_feedback_layer_->SetBounds(rect);
228
229 ui::Layer* parent = ash::Shell::GetContainer(
230 ash::Shell::GetActiveRootWindow(),
231 ash::internal::kShellWindowId_OverlayContainer)->layer();
232 parent->Add(visual_feedback_layer_.get());
233 visual_feedback_layer_->SetVisible(true);
234
235 MessageLoopForUI::current()->PostDelayedTask(
236 FROM_HERE,
237 base::Bind(&ScreenshotTaker::CloseVisualFeedbackLayer,
238 base::Unretained(this)),
239 base::TimeDelta::FromMilliseconds(kVisualFeedbackLayerDisplayTimeMs));
240 }
OLDNEW
« chrome/browser/ui/ash/screenshot_taker.h ('K') | « chrome/browser/ui/ash/screenshot_taker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698