summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views/aura/screenshot_taker.cc
blob: 9985d3589b66debe6373418e3d05e2ee5e903ee6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/aura/screenshot_taker.h"

#include <string>

#include "base/bind.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/stringprintf.h"
#include "base/time.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/ui/window_snapshot/window_snapshot.h"
#include "content/public/browser/browser_thread.h"
#include "ui/aura/window.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
#endif

namespace {
std::string GetScreenshotFileName() {
  base::Time::Exploded now;
  base::Time::Now().LocalExplode(&now);

  return base::StringPrintf("screenshot-%d%02d%02d-%02d%02d%02d.png",
                            now.year, now.month, now.day_of_month,
                            now.hour, now.minute, now.second);
}

// |is_logged_in| is used only for ChromeOS.  Otherwise it is always true.
void SaveScreenshot(bool is_logged_in,
                    scoped_refptr<RefCountedBytes> png_data) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));

  std::string screenshot_filename = GetScreenshotFileName();
  FilePath screenshot_path;
  if (is_logged_in) {
    screenshot_path = download_util::GetDefaultDownloadDirectory().AppendASCII(
        screenshot_filename);
  } else {
    file_util::CreateTemporaryFile(&screenshot_path);
  }

  if (static_cast<size_t>(file_util::WriteFile(
          screenshot_path,
          reinterpret_cast<char*>(&(png_data->data()[0])),
          png_data->size())) == png_data->size()) {
    if (!is_logged_in) {
      // We created a temporary file without .png suffix.  Rename it
      // here.
      FilePath real_path = screenshot_path.DirName().AppendASCII(
          screenshot_filename);
      if (!file_util::ReplaceFile(screenshot_path, real_path)) {
        LOG(ERROR) << "Failed to rename the file to " << real_path.value();
      }
    }
  } else {
    LOG(ERROR) << "Failed to save to " << screenshot_path.value();
  }
}

}  // namespace

ScreenshotTaker::ScreenshotTaker() {
}

void ScreenshotTaker::HandleTakeScreenshot(aura::Window* window) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  scoped_refptr<RefCountedBytes> png_data(new RefCountedBytes);

  bool is_logged_in = true;
#if defined(OS_CHROMEOS)
  is_logged_in = chromeos::UserManager::Get()->user_is_logged_in();
#endif

  if (browser::GrabWindowSnapshot(
          window, &png_data->data(), window->bounds())) {
    content::BrowserThread::PostTask(
        content::BrowserThread::FILE, FROM_HERE,
        base::Bind(&SaveScreenshot, is_logged_in, png_data));
  } else {
    LOG(ERROR) << "Failed to grab the window screenshot";
  }
}