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 |