| 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 |