13240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
33240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// found in the LICENSE file.
43240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
53240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/ui/webui/screenshot_source.h"
63240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
73240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/bind.h"
83240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/callback.h"
93240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/file_util.h"
103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/files/file_path.h"
113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/i18n/time_formatting.h"
123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/memory/ref_counted_memory.h"
133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/message_loop/message_loop.h"
143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/path_service.h"
153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/prefs/pref_service.h"
163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/strings/string16.h"
173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/strings/string_util.h"
183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/strings/stringprintf.h"
193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/browser_process.h"
203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/download/download_prefs.h"
213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/profiles/profile.h"
223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/profiles/profile_manager.h"
233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/common/chrome_paths.h"
243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/common/pref_names.h"
253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/common/url_constants.h"
263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "url/url_canon.h"
273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "url/url_util.h"
283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(USE_ASH)
303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "ash/shell.h"
313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "ash/shell_delegate.h"
323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/chromeos/drive/drive_integration_service.h"
363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/chromeos/drive/file_system_interface.h"
373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/chromeos/drive/file_system_util.h"
383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chromeos/login/login_state.h"
393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "content/public/browser/browser_thread.h"
403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ScreenshotSource::kScreenshotUrlRoot[] = "chrome://screenshots/";
443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ScreenshotSource::kScreenshotCurrent[] = "current";
463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ScreenshotSource::kScreenshotSaved[] = "saved/";
483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ScreenshotSource::kScreenshotPrefix[] = "Screenshot ";
513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char ScreenshotSource::kScreenshotSuffix[] = ".png";
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool ShouldUse24HourClock() {
563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (profile) {
593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return profile->GetPrefs()->GetBoolean(prefs::kUse24HourClock);
603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return base::GetHourClockType() == base::k24HourClock;
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochScreenshotSource::ScreenshotSource(
663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::vector<unsigned char>* current_screenshot,
673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    Profile* profile)
683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    : profile_(profile) {
693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Setup the last screenshot taken.
703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (current_screenshot)
713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    current_screenshot_.reset(new ScreenshotData(*current_screenshot));
723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  else
733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    current_screenshot_.reset(new ScreenshotData());
743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochScreenshotSource::~ScreenshotSource() {}
773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string ScreenshotSource::GetScreenshotBaseFilename() {
803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::Time::Exploded now;
813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::Time::Now().LocalExplode(&now);
823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // We don't use base/i18n/time_formatting.h here because it doesn't
843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // support our format.  Don't use ICU either to avoid i18n file names
853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // for non-English locales.
863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // TODO(mukai): integrate this logic somewhere time_formatting.h
873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string file_name = base::StringPrintf(
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      "Screenshot %d-%02d-%02d at ", now.year, now.month, now.day_of_month);
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (ShouldUse24HourClock()) {
913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    file_name.append(base::StringPrintf(
923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        "%02d.%02d.%02d", now.hour, now.minute, now.second));
933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } else {
943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    int hour = now.hour;
953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (hour > 12) {
963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      hour -= 12;
973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    } else if (hour == 0) {
983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      hour = 12;
993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
1003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    file_name.append(base::StringPrintf(
1013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        "%d.%02d.%02d ", hour, now.minute, now.second));
1023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    file_name.append((now.hour >= 12) ? "PM" : "AM");
1033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
1043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return file_name;
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(USE_ASH)
1093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool ScreenshotSource::AreScreenshotsDisabled() {
1123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return g_browser_process->local_state()->GetBoolean(
1133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      prefs::kDisableScreenshots);
1143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// static
1173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool ScreenshotSource::GetScreenshotDirectory(base::FilePath* directory) {
1183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (ScreenshotSource::AreScreenshotsDisabled())
1193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return false;
1203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  bool is_logged_in = true;
1223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
1243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  is_logged_in = chromeos::LoginState::Get()->IsUserLoggedIn();
1253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
1263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (is_logged_in) {
1283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(
1293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext());
1303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    *directory = download_prefs->DownloadPath();
1313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } else  {
1323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (!file_util::GetTempDir(directory)) {
1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      LOG(ERROR) << "Failed to find temporary directory.";
1343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return false;
1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
1363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return true;
1383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
1413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string ScreenshotSource::GetSource() const {
1433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return chrome::kChromeUIScreenshotPath;
1443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ScreenshotSource::StartDataRequest(
1473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const std::string& path,
1483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  int render_process_id,
1493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  int render_view_id,
1503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const content::URLDataSource::GotDataCallback& callback) {
1513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SendScreenshot(path, callback);
1523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::string ScreenshotSource::GetMimeType(const std::string&) const {
1553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // We need to explicitly return a mime type, otherwise if the user tries to
1563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // drag the image they get no extension.
1573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return "image/png";
1583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochScreenshotDataPtr ScreenshotSource::GetCachedScreenshot(
1613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& screenshot_path) {
1623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::map<std::string, ScreenshotDataPtr>::iterator pos;
1633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string path = screenshot_path.substr(
1643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      0, screenshot_path.find_first_of("?"));
1653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if ((pos = cached_screenshots_.find(path)) != cached_screenshots_.end()) {
1663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return pos->second;
1673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } else {
1683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return ScreenshotDataPtr(new ScreenshotData);
1693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
1703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ScreenshotSource::SendScreenshot(
1733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& screenshot_path,
1743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const content::URLDataSource::GotDataCallback& callback) {
1753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Strip the query param value - we only use it as a hack to ensure our
1763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // image gets reloaded instead of being pulled from the browser cache
1773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string path = screenshot_path.substr(
1783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      0, screenshot_path.find_first_of("?"));
1793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (path == ScreenshotSource::kScreenshotCurrent) {
1803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    CacheAndSendScreenshot(path, callback, current_screenshot_);
1813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
1823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } else if (path.compare(0, strlen(ScreenshotSource::kScreenshotSaved),
1833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch             ScreenshotSource::kScreenshotSaved) == 0) {
1843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    using content::BrowserThread;
1853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string filename =
1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        path.substr(strlen(ScreenshotSource::kScreenshotSaved));
1883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    url_canon::RawCanonOutputT<char16> decoded;
1903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    url_util::DecodeURLEscapeSequences(
1913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        filename.data(), filename.size(), &decoded);
1923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // Screenshot filenames don't use non-ascii characters.
1933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    std::string decoded_filename = UTF16ToASCII(string16(
1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        decoded.data(), decoded.length()));
1953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    base::FilePath download_path;
1973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    GetScreenshotDirectory(&download_path);
1983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (drive::util::IsUnderDriveMountPoint(download_path)) {
1993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      drive::FileSystemInterface* file_system =
2003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          drive::DriveIntegrationServiceFactory::GetForProfile(
2013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch              profile_)->file_system();
2023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      file_system->GetFileByPath(
2033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          drive::util::ExtractDrivePath(download_path).Append(decoded_filename),
2043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          base::Bind(&ScreenshotSource::GetSavedScreenshotCallback,
2053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                     base::Unretained(this), screenshot_path, callback));
2063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    } else {
2073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      BrowserThread::PostTask(
2083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          BrowserThread::FILE, FROM_HERE,
2093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          base::Bind(&ScreenshotSource::SendSavedScreenshot,
2103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                     base::Unretained(this),
2113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                     screenshot_path,
2123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                     callback, download_path.Append(decoded_filename)));
2133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
2143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
2153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  } else {
2163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    CacheAndSendScreenshot(
2173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        path, callback, ScreenshotDataPtr(new ScreenshotData()));
2183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if defined(OS_CHROMEOS)
2223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ScreenshotSource::SendSavedScreenshot(
2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& screenshot_path,
2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const content::URLDataSource::GotDataCallback& callback,
2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const base::FilePath& file) {
2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ScreenshotDataPtr read_bytes(new ScreenshotData);
2273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  int64 file_size = 0;
2283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!file_util::GetFileSize(file, &file_size)) {
2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    CacheAndSendScreenshot(screenshot_path, callback, read_bytes);
2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  read_bytes->resize(file_size);
2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!file_util::ReadFile(file, reinterpret_cast<char*>(&read_bytes->front()),
2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           static_cast<int>(file_size)))
2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    read_bytes->clear();
2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  CacheAndSendScreenshot(screenshot_path, callback, read_bytes);
2403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ScreenshotSource::GetSavedScreenshotCallback(
2433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& screenshot_path,
2443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const content::URLDataSource::GotDataCallback& callback,
2453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    drive::FileError error,
2463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const base::FilePath& file,
2473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    scoped_ptr<drive::ResourceEntry> entry) {
2483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (error != drive::FILE_ERROR_OK) {
2493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    ScreenshotDataPtr read_bytes(new ScreenshotData);
2503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    CacheAndSendScreenshot(screenshot_path, callback, read_bytes);
2513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  content::BrowserThread::PostTask(
2553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      content::BrowserThread::FILE, FROM_HERE,
2563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      base::Bind(&ScreenshotSource::SendSavedScreenshot,
2573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                 base::Unretained(this), screenshot_path, callback, file));
2583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#endif
2603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid ScreenshotSource::CacheAndSendScreenshot(
2623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& screenshot_path,
2633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const content::URLDataSource::GotDataCallback& callback,
2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    ScreenshotDataPtr bytes) {
2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Strip the query from the screenshot path.
2663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string path = screenshot_path.substr(
2673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      0, screenshot_path.find_first_of("?"));
2683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cached_screenshots_[path] = bytes;
2693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  callback.Run(new base::RefCountedBytes(*bytes));
2703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
271