// Copyright (c) 2011 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/webui/screenshot_source.h" #include "base/file_util.h" #include "base/memory/ref_counted_memory.h" #include "base/path_service.h" #include "base/synchronization/waitable_event.h" #include "base/task.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" static const char kCurrentScreenshot[] = "current"; #if defined(OS_CHROMEOS) static const char kSavedScreenshots[] = "saved/"; #endif static const char kScreenshotsRelativePath[] = "/Screenshots/"; #if defined(OS_CHROMEOS) // Read the file from the screenshots directory into the read_bytes vector. void ReadScreenshot(const std::string& filename, std::vector* read_bytes, base::WaitableEvent* read_complete) { read_bytes->clear(); FilePath fileshelf_path; if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &fileshelf_path)) { read_complete->Signal(); return; } FilePath file(fileshelf_path.value() + std::string(kScreenshotsRelativePath) + filename); int64 file_size = 0; if (!file_util::GetFileSize(file, &file_size)) { read_complete->Signal(); return; } // expand vector to file size read_bytes->resize(file_size); // read file into the vector int bytes_read = 0; if (!(bytes_read = file_util::ReadFile(file, reinterpret_cast( &read_bytes->front()), static_cast(file_size)))) read_bytes->clear(); // We're done, if successful, read_bytes will have the data // otherwise, it'll be empty. read_complete->Signal(); } // Get a saved screenshot - read on the FILE thread. std::vector GetSavedScreenshot(std::string filename) { base::WaitableEvent read_complete(true, false); std::vector bytes; BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, NewRunnableFunction(&ReadScreenshot, filename, &bytes, &read_complete)); read_complete.Wait(); return bytes; } #endif std::vector ScreenshotSource::GetScreenshot( const std::string& full_path) { // Strip the query param value - we only use it as a hack to ensure our // image gets reloaded instead of being pulled from the browser cache std::string path = full_path.substr(0, full_path.find_first_of("?")); if (path == kCurrentScreenshot) { return current_screenshot_; #if defined(OS_CHROMEOS) } else if (path.compare(0, strlen(kSavedScreenshots), kSavedScreenshots) == 0) { // Split the saved screenshot filename from the path std::string filename = path.substr(strlen(kSavedScreenshots)); return GetSavedScreenshot(filename); #endif } else { std::vector ret; // TODO(rkc): Weird vc bug, return std::vector() causes // the object assigned to the return value of this function magically // change it's address 0x0; look into this eventually. return ret; } } ScreenshotSource::ScreenshotSource( std::vector* current_screenshot) : DataSource(chrome::kChromeUIScreenshotPath, MessageLoop::current()) { // Setup the last screenshot taken. if (current_screenshot) current_screenshot_ = *current_screenshot; else current_screenshot_.clear(); } ScreenshotSource::~ScreenshotSource() {} void ScreenshotSource::StartDataRequest(const std::string& path, bool is_incognito, int request_id) { SendResponse(request_id, new RefCountedBytes(GetScreenshot(path))); } std::string ScreenshotSource::GetMimeType(const std::string&) const { // We need to explicitly return a mime type, otherwise if the user tries to // drag the image they get no extension. return "image/png"; }