OLD | NEW |
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 21 matching lines...) Expand all Loading... |
32 #include "grit/ash_strings.h" | 32 #include "grit/ash_strings.h" |
33 #include "grit/theme_resources.h" | 33 #include "grit/theme_resources.h" |
34 #include "grit/ui_strings.h" | 34 #include "grit/ui_strings.h" |
35 #include "ui/aura/root_window.h" | 35 #include "ui/aura/root_window.h" |
36 #include "ui/aura/window.h" | 36 #include "ui/aura/window.h" |
37 #include "ui/base/clipboard/clipboard.h" | 37 #include "ui/base/clipboard/clipboard.h" |
38 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 38 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
39 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
40 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
41 #include "ui/gfx/image/image.h" | 41 #include "ui/gfx/image/image.h" |
| 42 #include "ui/snapshot/snapshot.h" |
42 | 43 |
43 #if defined(USE_ASH) | 44 #if defined(USE_ASH) |
44 #include "ash/shell.h" | 45 #include "ash/shell.h" |
45 #include "ash/shell_delegate.h" | 46 #include "ash/shell_delegate.h" |
46 #endif | 47 #endif |
47 | 48 |
48 #if defined(OS_CHROMEOS) | 49 #if defined(OS_CHROMEOS) |
49 #include "chrome/browser/chromeos/drive/file_system_interface.h" | 50 #include "chrome/browser/chromeos/drive/file_system_interface.h" |
50 #include "chrome/browser/chromeos/drive/file_system_util.h" | 51 #include "chrome/browser/chromeos/drive/file_system_util.h" |
51 #include "chrome/browser/chromeos/file_manager/open_util.h" | 52 #include "chrome/browser/chromeos/file_manager/open_util.h" |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 const base::FilePath& screenshot_path, | 298 const base::FilePath& screenshot_path, |
298 scoped_refptr<base::RefCountedBytes> png_data) { | 299 scoped_refptr<base::RefCountedBytes> png_data) { |
299 content::BrowserThread::GetBlockingPool()->PostTask( | 300 content::BrowserThread::GetBlockingPool()->PostTask( |
300 FROM_HERE, base::Bind(&SaveScreenshot, | 301 FROM_HERE, base::Bind(&SaveScreenshot, |
301 callback, | 302 callback, |
302 screenshot_path, | 303 screenshot_path, |
303 png_data)); | 304 png_data)); |
304 } | 305 } |
305 #endif | 306 #endif |
306 | 307 |
307 bool GrabWindowSnapshot(aura::Window* window, | |
308 const gfx::Rect& snapshot_bounds, | |
309 std::vector<unsigned char>* png_data) { | |
310 return chrome::GrabWindowSnapshotForUser(window, png_data, snapshot_bounds); | |
311 } | |
312 | |
313 bool ShouldUse24HourClock() { | 308 bool ShouldUse24HourClock() { |
314 #if defined(OS_CHROMEOS) | 309 #if defined(OS_CHROMEOS) |
315 Profile* profile = ProfileManager::GetActiveUserProfile(); | 310 Profile* profile = ProfileManager::GetActiveUserProfile(); |
316 if (profile) { | 311 if (profile) { |
317 return profile->GetPrefs()->GetBoolean(prefs::kUse24HourClock); | 312 return profile->GetPrefs()->GetBoolean(prefs::kUse24HourClock); |
318 } | 313 } |
319 #endif | 314 #endif |
320 return base::GetHourClockType() == base::k24HourClock; | 315 return base::GetHourClockType() == base::k24HourClock; |
321 } | 316 } |
322 | 317 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); | 419 aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows(); |
425 // Reorder root_windows to take the primary root window's snapshot at first. | 420 // Reorder root_windows to take the primary root window's snapshot at first. |
426 aura::Window* primary_root = ash::Shell::GetPrimaryRootWindow(); | 421 aura::Window* primary_root = ash::Shell::GetPrimaryRootWindow(); |
427 if (*(root_windows.begin()) != primary_root) { | 422 if (*(root_windows.begin()) != primary_root) { |
428 root_windows.erase(std::find( | 423 root_windows.erase(std::find( |
429 root_windows.begin(), root_windows.end(), primary_root)); | 424 root_windows.begin(), root_windows.end(), primary_root)); |
430 root_windows.insert(root_windows.begin(), primary_root); | 425 root_windows.insert(root_windows.begin(), primary_root); |
431 } | 426 } |
432 for (size_t i = 0; i < root_windows.size(); ++i) { | 427 for (size_t i = 0; i < root_windows.size(); ++i) { |
433 aura::Window* root_window = root_windows[i]; | 428 aura::Window* root_window = root_windows[i]; |
434 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); | |
435 std::string basename = screenshot_basename; | 429 std::string basename = screenshot_basename; |
436 gfx::Rect rect = root_window->bounds(); | 430 gfx::Rect rect = root_window->bounds(); |
437 if (root_windows.size() > 1) | 431 if (root_windows.size() > 1) |
438 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); | 432 basename += base::StringPrintf(" - Display %d", static_cast<int>(i + 1)); |
439 base::FilePath screenshot_path = | 433 base::FilePath screenshot_path = |
440 screenshot_directory.AppendASCII(basename + ".png"); | 434 screenshot_directory.AppendASCII(basename + ".png"); |
441 if (GrabWindowSnapshot(root_window, rect, &png_data->data())) { | 435 GrabFullWindowSnapshotAsync( |
442 PostSaveScreenshotTask( | 436 root_window, rect, GetProfile(), screenshot_path, i); |
443 base::Bind(&ScreenshotTaker::ShowNotification, factory_.GetWeakPtr()), | |
444 GetProfile(), | |
445 screenshot_path, | |
446 png_data); | |
447 } else { | |
448 LOG(ERROR) << "Failed to grab the window screenshot for " << i; | |
449 ShowNotification( | |
450 ScreenshotTakerObserver::SCREENSHOT_GRABWINDOW_FULL_FAILED, | |
451 screenshot_path); | |
452 } | |
453 } | 437 } |
454 content::RecordAction(base::UserMetricsAction("Screenshot_TakeFull")); | 438 content::RecordAction(base::UserMetricsAction("Screenshot_TakeFull")); |
455 last_screenshot_timestamp_ = base::Time::Now(); | |
456 } | 439 } |
457 | 440 |
458 void ScreenshotTaker::HandleTakePartialScreenshot( | 441 void ScreenshotTaker::HandleTakePartialScreenshot( |
459 aura::Window* window, const gfx::Rect& rect) { | 442 aura::Window* window, const gfx::Rect& rect) { |
460 if (g_browser_process->local_state()-> | 443 if (g_browser_process->local_state()-> |
461 GetBoolean(prefs::kDisableScreenshots)) { | 444 GetBoolean(prefs::kDisableScreenshots)) { |
462 ShowNotification(ScreenshotTakerObserver::SCREENSHOTS_DISABLED, | 445 ShowNotification(ScreenshotTakerObserver::SCREENSHOTS_DISABLED, |
463 base::FilePath()); | 446 base::FilePath()); |
464 return; | 447 return; |
465 } | 448 } |
466 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 449 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
467 | 450 |
468 base::FilePath screenshot_directory; | 451 base::FilePath screenshot_directory; |
469 if (!screenshot_directory_for_test_.empty()) { | 452 if (!screenshot_directory_for_test_.empty()) { |
470 screenshot_directory = screenshot_directory_for_test_; | 453 screenshot_directory = screenshot_directory_for_test_; |
471 } else if (!GetScreenshotDirectory(&screenshot_directory)) { | 454 } else if (!GetScreenshotDirectory(&screenshot_directory)) { |
472 ShowNotification(ScreenshotTakerObserver::SCREENSHOT_GET_DIR_FAILED, | 455 ShowNotification(ScreenshotTakerObserver::SCREENSHOT_GET_DIR_FAILED, |
473 base::FilePath()); | 456 base::FilePath()); |
474 return; | 457 return; |
475 } | 458 } |
476 | 459 |
477 scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); | |
478 | |
479 std::string screenshot_basename = !screenshot_basename_for_test_.empty() ? | 460 std::string screenshot_basename = !screenshot_basename_for_test_.empty() ? |
480 screenshot_basename_for_test_ : GetScreenshotBaseFilename(); | 461 screenshot_basename_for_test_ : GetScreenshotBaseFilename(); |
481 base::FilePath screenshot_path = | 462 base::FilePath screenshot_path = |
482 screenshot_directory.AppendASCII(screenshot_basename + ".png"); | 463 screenshot_directory.AppendASCII(screenshot_basename + ".png"); |
483 if (GrabWindowSnapshot(window, rect, &png_data->data())) { | 464 GrabPartialWindowSnapshotAsync(window, rect, GetProfile(), screenshot_path); |
484 last_screenshot_timestamp_ = base::Time::Now(); | |
485 PostSaveScreenshotTask( | |
486 base::Bind(&ScreenshotTaker::ShowNotification, factory_.GetWeakPtr()), | |
487 GetProfile(), | |
488 screenshot_path, | |
489 png_data); | |
490 } else { | |
491 LOG(ERROR) << "Failed to grab the window screenshot"; | |
492 ShowNotification( | |
493 ScreenshotTakerObserver::SCREENSHOT_GRABWINDOW_PARTIAL_FAILED, | |
494 screenshot_path); | |
495 } | |
496 content::RecordAction(base::UserMetricsAction("Screenshot_TakePartial")); | 465 content::RecordAction(base::UserMetricsAction("Screenshot_TakePartial")); |
497 } | 466 } |
498 | 467 |
499 bool ScreenshotTaker::CanTakeScreenshot() { | 468 bool ScreenshotTaker::CanTakeScreenshot() { |
500 return last_screenshot_timestamp_.is_null() || | 469 return last_screenshot_timestamp_.is_null() || |
501 base::Time::Now() - last_screenshot_timestamp_ > | 470 base::Time::Now() - last_screenshot_timestamp_ > |
502 base::TimeDelta::FromMilliseconds( | 471 base::TimeDelta::FromMilliseconds( |
503 kScreenshotMinimumIntervalInMS); | 472 kScreenshotMinimumIntervalInMS); |
504 } | 473 } |
505 | 474 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 } | 540 } |
572 | 541 |
573 void ScreenshotTaker::RemoveObserver(ScreenshotTakerObserver* observer) { | 542 void ScreenshotTaker::RemoveObserver(ScreenshotTakerObserver* observer) { |
574 observers_.RemoveObserver(observer); | 543 observers_.RemoveObserver(observer); |
575 } | 544 } |
576 | 545 |
577 bool ScreenshotTaker::HasObserver(ScreenshotTakerObserver* observer) const { | 546 bool ScreenshotTaker::HasObserver(ScreenshotTakerObserver* observer) const { |
578 return observers_.HasObserver(observer); | 547 return observers_.HasObserver(observer); |
579 } | 548 } |
580 | 549 |
| 550 void ScreenshotTaker::GrabWindowSnapshotAsyncCallback( |
| 551 base::FilePath screenshot_path, |
| 552 bool is_partial, |
| 553 int window_idx, |
| 554 scoped_refptr<base::RefCountedBytes> png_data) { |
| 555 if (!png_data) { |
| 556 if (is_partial) { |
| 557 LOG(ERROR) << "Failed to grab the window screenshot"; |
| 558 ShowNotification( |
| 559 ScreenshotTakerObserver::SCREENSHOT_GRABWINDOW_PARTIAL_FAILED, |
| 560 screenshot_path); |
| 561 } else { |
| 562 LOG(ERROR) << "Failed to grab the window screenshot for " << window_idx; |
| 563 ShowNotification( |
| 564 ScreenshotTakerObserver::SCREENSHOT_GRABWINDOW_FULL_FAILED, |
| 565 screenshot_path); |
| 566 } |
| 567 return; |
| 568 } |
| 569 |
| 570 PostSaveScreenshotTask( |
| 571 base::Bind(&ScreenshotTaker::ShowNotification, factory_.GetWeakPtr()), |
| 572 GetProfile(), |
| 573 screenshot_path, |
| 574 png_data); |
| 575 } |
| 576 |
| 577 void ScreenshotTaker::GrabPartialWindowSnapshotAsync( |
| 578 aura::Window* window, |
| 579 const gfx::Rect& snapshot_bounds, |
| 580 Profile* profile, |
| 581 base::FilePath screenshot_path) { |
| 582 last_screenshot_timestamp_ = base::Time::Now(); |
| 583 |
| 584 bool is_partial = true; |
| 585 int window_idx = -1; // unused |
| 586 ui::GrabWindowSnapshotAsync( |
| 587 window, |
| 588 snapshot_bounds, |
| 589 content::BrowserThread::GetBlockingPool(), |
| 590 base::Bind(&ScreenshotTaker::GrabWindowSnapshotAsyncCallback, |
| 591 factory_.GetWeakPtr(), |
| 592 screenshot_path, |
| 593 is_partial, |
| 594 window_idx)); |
| 595 } |
| 596 |
| 597 void ScreenshotTaker::GrabFullWindowSnapshotAsync( |
| 598 aura::Window* window, |
| 599 const gfx::Rect& snapshot_bounds, |
| 600 Profile* profile, |
| 601 base::FilePath screenshot_path, |
| 602 int window_idx) { |
| 603 last_screenshot_timestamp_ = base::Time::Now(); |
| 604 |
| 605 bool is_partial = false; |
| 606 ui::GrabWindowSnapshotAsync( |
| 607 window, |
| 608 snapshot_bounds, |
| 609 content::BrowserThread::GetBlockingPool(), |
| 610 base::Bind(&ScreenshotTaker::GrabWindowSnapshotAsyncCallback, |
| 611 factory_.GetWeakPtr(), |
| 612 screenshot_path, |
| 613 is_partial, |
| 614 window_idx)); |
| 615 } |
| 616 |
581 Profile* ScreenshotTaker::GetProfile() { | 617 Profile* ScreenshotTaker::GetProfile() { |
582 if (profile_for_test_) | 618 if (profile_for_test_) |
583 return profile_for_test_; | 619 return profile_for_test_; |
584 return ProfileManager::GetActiveUserProfile(); | 620 return ProfileManager::GetActiveUserProfile(); |
585 } | 621 } |
586 | 622 |
587 void ScreenshotTaker::SetScreenshotDirectoryForTest( | 623 void ScreenshotTaker::SetScreenshotDirectoryForTest( |
588 const base::FilePath& directory) { | 624 const base::FilePath& directory) { |
589 screenshot_directory_for_test_ = directory; | 625 screenshot_directory_for_test_ = directory; |
590 } | 626 } |
591 | 627 |
592 void ScreenshotTaker::SetScreenshotBasenameForTest( | 628 void ScreenshotTaker::SetScreenshotBasenameForTest( |
593 const std::string& basename) { | 629 const std::string& basename) { |
594 screenshot_basename_for_test_ = basename; | 630 screenshot_basename_for_test_ = basename; |
595 } | 631 } |
596 | 632 |
597 void ScreenshotTaker::SetScreenshotProfileForTest(Profile* profile) { | 633 void ScreenshotTaker::SetScreenshotProfileForTest(Profile* profile) { |
598 profile_for_test_ = profile; | 634 profile_for_test_ = profile; |
599 } | 635 } |
OLD | NEW |