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