Commit 685b3cd4 authored by Elliot Glaysher's avatar Elliot Glaysher Committed by Commit Bot

Remove file handling from ScreenshotGrabber.

This is the first patch in a series to make screenshots work in
mash. This first step is simplifying ui::ScreenshotGrabber into a
component that can be used without the filesystem. This moves file
writing to the chrome layer, switches to callbacks, and starts
separating ChromeScreenshotGrabber into the part that initiates a
screenshot (will be replaced with an ash side delegate that communicates
over mojo) and the part that accepts the data and writes it to the
filesystem (which will continue to exist and stay in chrome).

Change-Id: Ic2370e0d4426f51ffd09af8920304b98b8ebde0e
Bug: 706246
Reviewed-on: https://chromium-review.googlesource.com/894882Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Elliot Glaysher <erg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533848}
parent e6454017
...@@ -217,6 +217,7 @@ ...@@ -217,6 +217,7 @@
#include "chrome/browser/chromeos/system/timezone_resolver_manager.h" #include "chrome/browser/chromeos/system/timezone_resolver_manager.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber_test_observer.h"
#include "chromeos/audio/cras_audio_handler.h" #include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/chromeos_switches.h" #include "chromeos/chromeos_switches.h"
#include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/cryptohome/cryptohome_parameters.h"
...@@ -699,10 +700,11 @@ class PolicyTest : public InProcessBrowserTest { ...@@ -699,10 +700,11 @@ class PolicyTest : public InProcessBrowserTest {
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
class QuitMessageLoopAfterScreenshot : public ui::ScreenshotGrabberObserver { class QuitMessageLoopAfterScreenshot
: public ChromeScreenshotGrabberTestObserver {
public: public:
void OnScreenshotCompleted( void OnScreenshotCompleted(
ScreenshotGrabberObserver::Result screenshot_result, ui::ScreenshotResult screenshot_result,
const base::FilePath& screenshot_path) override { const base::FilePath& screenshot_path) override {
BrowserThread::PostTaskAndReply(BrowserThread::IO, FROM_HERE, BrowserThread::PostTaskAndReply(BrowserThread::IO, FROM_HERE,
base::Bind(base::DoNothing), base::Bind(base::DoNothing),
...@@ -716,11 +718,11 @@ class PolicyTest : public InProcessBrowserTest { ...@@ -716,11 +718,11 @@ class PolicyTest : public InProcessBrowserTest {
// ScreenshotGrabber doesn't own this observer, so the observer's lifetime // ScreenshotGrabber doesn't own this observer, so the observer's lifetime
// is tied to the test instead. // is tied to the test instead.
ChromeScreenshotGrabber* grabber = ChromeScreenshotGrabber::Get(); ChromeScreenshotGrabber* grabber = ChromeScreenshotGrabber::Get();
grabber->screenshot_grabber()->AddObserver(&observer_); grabber->test_observer_ = &observer_;
SetScreenshotPolicy(enabled); SetScreenshotPolicy(enabled);
grabber->HandleTakeScreenshotForAllRootWindows(); grabber->HandleTakeScreenshotForAllRootWindows();
content::RunMessageLoop(); content::RunMessageLoop();
grabber->screenshot_grabber()->RemoveObserver(&observer_); grabber->test_observer_ = nullptr;
} }
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
......
...@@ -1803,6 +1803,7 @@ split_static_library("ui") { ...@@ -1803,6 +1803,7 @@ split_static_library("ui") {
"ash/chrome_new_window_client.h", "ash/chrome_new_window_client.h",
"ash/chrome_screenshot_grabber.cc", "ash/chrome_screenshot_grabber.cc",
"ash/chrome_screenshot_grabber.h", "ash/chrome_screenshot_grabber.h",
"ash/chrome_screenshot_grabber_test_observer.h",
"ash/chrome_shell_content_state.cc", "ash/chrome_shell_content_state.cc",
"ash/chrome_shell_content_state.h", "ash/chrome_shell_content_state.h",
"ash/chrome_shell_content_state_chromeos.cc", "ash/chrome_shell_content_state_chromeos.cc",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ash/screenshot_delegate.h" #include "ash/screenshot_delegate.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/drive/chromeos/file_system_interface.h" #include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/drive.pb.h" #include "components/drive/drive.pb.h"
...@@ -23,10 +24,28 @@ namespace ash { ...@@ -23,10 +24,28 @@ namespace ash {
class ChromeScreenshotGrabberTest; class ChromeScreenshotGrabberTest;
} // namespace ash } // namespace ash
class ChromeScreenshotGrabber : public ash::ScreenshotDelegate, namespace policy {
public ui::ScreenshotGrabberDelegate, class PolicyTest;
public ui::ScreenshotGrabberObserver { } // namespace policy
class ChromeScreenshotGrabberBrowserTest;
class ChromeScreenshotGrabberTestObserver;
// Result of asynchronous file operations.
enum class ScreenshotFileResult {
SUCCESS,
CHECK_DIR_FAILED,
CREATE_DIR_FAILED,
CREATE_FAILED
};
class ChromeScreenshotGrabber : public ash::ScreenshotDelegate {
public: public:
// Callback called with the |result| of trying to create a local writable
// |path| for the possibly remote path.
using FileCallback = base::Callback<void(ScreenshotFileResult result,
const base::FilePath& path)>;
ChromeScreenshotGrabber(); ChromeScreenshotGrabber();
~ChromeScreenshotGrabber() override; ~ChromeScreenshotGrabber() override;
...@@ -43,17 +62,28 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate, ...@@ -43,17 +62,28 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate,
void HandleTakeWindowScreenshot(aura::Window* window) override; void HandleTakeWindowScreenshot(aura::Window* window) override;
bool CanTakeScreenshot() override; bool CanTakeScreenshot() override;
// ui::ScreenshotGrabberDelegate: // TODO(erg): This is the endpoint for a new interface which will be added in
void PrepareFileAndRunOnBlockingPool( // a future patch. It is intended to be both mojo proxyable, and usable as a
const base::FilePath& path, // callback from ScreenshotGrabber.
const FileCallback& callback_on_blocking_pool) override; void OnTookScreenshot(const base::Time& screenshot_time,
const base::Optional<int>& display_num,
// ui::ScreenshotGrabberObserver: ui::ScreenshotResult result,
void OnScreenshotCompleted(ui::ScreenshotGrabberObserver::Result result, scoped_refptr<base::RefCountedMemory> png_data);
const base::FilePath& screenshot_path) override;
private: private:
friend class ash::ChromeScreenshotGrabberTest; friend class ash::ChromeScreenshotGrabberTest;
friend class ChromeScreenshotGrabberBrowserTest;
friend class policy::PolicyTest;
// Prepares a writable file for |path|. If |path| is a non-local path (i.e.
// Google drive) and it is supported this will create a local cached copy of
// the remote file and call the callback with the local path.
void PrepareFileAndRunOnBlockingPool(const base::FilePath& path,
const FileCallback& callback);
// Called once all file writing is completed, or on error.
void OnScreenshotCompleted(ui::ScreenshotResult result,
const base::FilePath& screenshot_path);
// Callback method of FileSystemInterface::GetFile(). // Callback method of FileSystemInterface::GetFile().
// Runs ReadScreenshotFileForPreviewLocal if successful. Otherwise, runs // Runs ReadScreenshotFileForPreviewLocal if successful. Otherwise, runs
...@@ -107,7 +137,7 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate, ...@@ -107,7 +137,7 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate,
// notification is clicked. // notification is clicked.
// |image| is a preview image attached to the notification. It can be empty. // |image| is a preview image attached to the notification. It can be empty.
void OnReadScreenshotFileForPreviewCompleted( void OnReadScreenshotFileForPreviewCompleted(
ui::ScreenshotGrabberObserver::Result result, ui::ScreenshotResult result,
const base::FilePath& screenshot_path, const base::FilePath& screenshot_path,
gfx::Image image); gfx::Image image);
...@@ -115,6 +145,9 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate, ...@@ -115,6 +145,9 @@ class ChromeScreenshotGrabber : public ash::ScreenshotDelegate,
std::unique_ptr<ui::ScreenshotGrabber> screenshot_grabber_; std::unique_ptr<ui::ScreenshotGrabber> screenshot_grabber_;
// Forwards OnScreenshotCompleted() events to a test.
ChromeScreenshotGrabberTestObserver* test_observer_ = nullptr;
base::WeakPtrFactory<ChromeScreenshotGrabber> weak_factory_; base::WeakPtrFactory<ChromeScreenshotGrabber> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ChromeScreenshotGrabber); DISALLOW_COPY_AND_ASSIGN(ChromeScreenshotGrabber);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/notifications/notification_display_service_tester.h" #include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h"
#include "chrome/browser/ui/ash/chrome_screenshot_grabber_test_observer.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "components/session_manager/core/session_manager.h" #include "components/session_manager/core/session_manager.h"
...@@ -22,7 +23,7 @@ ...@@ -22,7 +23,7 @@
class ChromeScreenshotGrabberBrowserTest class ChromeScreenshotGrabberBrowserTest
: public InProcessBrowserTest, : public InProcessBrowserTest,
public ui::ScreenshotGrabberObserver, public ChromeScreenshotGrabberTestObserver,
public ui::ClipboardObserver { public ui::ClipboardObserver {
public: public:
ChromeScreenshotGrabberBrowserTest() = default; ChromeScreenshotGrabberBrowserTest() = default;
...@@ -36,9 +37,14 @@ class ChromeScreenshotGrabberBrowserTest ...@@ -36,9 +37,14 @@ class ChromeScreenshotGrabberBrowserTest
base::Unretained(this))); base::Unretained(this)));
} }
void SetTestObserver(ChromeScreenshotGrabber* chrome_screenshot_grabber,
ChromeScreenshotGrabberTestObserver* observer) {
chrome_screenshot_grabber->test_observer_ = observer;
}
// Overridden from ui::ScreenshotGrabberObserver // Overridden from ui::ScreenshotGrabberObserver
void OnScreenshotCompleted( void OnScreenshotCompleted(
ScreenshotGrabberObserver::Result screenshot_result, ui::ScreenshotResult screenshot_result,
const base::FilePath& screenshot_path) override { const base::FilePath& screenshot_path) override {
screenshot_result_ = screenshot_result; screenshot_result_ = screenshot_result;
screenshot_path_ = screenshot_path; screenshot_path_ = screenshot_path;
...@@ -68,7 +74,7 @@ class ChromeScreenshotGrabberBrowserTest ...@@ -68,7 +74,7 @@ class ChromeScreenshotGrabberBrowserTest
scoped_refptr<content::MessageLoopRunner> message_loop_runner_; scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
std::unique_ptr<NotificationDisplayServiceTester> display_service_; std::unique_ptr<NotificationDisplayServiceTester> display_service_;
ScreenshotGrabberObserver::Result screenshot_result_; ui::ScreenshotResult screenshot_result_;
base::FilePath screenshot_path_; base::FilePath screenshot_path_;
bool notification_added_ = false; bool notification_added_ = false;
bool clipboard_changed_ = false; bool clipboard_changed_ = false;
...@@ -80,25 +86,24 @@ class ChromeScreenshotGrabberBrowserTest ...@@ -80,25 +86,24 @@ class ChromeScreenshotGrabberBrowserTest
IN_PROC_BROWSER_TEST_F(ChromeScreenshotGrabberBrowserTest, TakeScreenshot) { IN_PROC_BROWSER_TEST_F(ChromeScreenshotGrabberBrowserTest, TakeScreenshot) {
ChromeScreenshotGrabber* chrome_screenshot_grabber = ChromeScreenshotGrabber* chrome_screenshot_grabber =
ChromeScreenshotGrabber::Get(); ChromeScreenshotGrabber::Get();
chrome_screenshot_grabber->screenshot_grabber()->AddObserver(this); SetTestObserver(chrome_screenshot_grabber, this);
base::ScopedTempDir directory; base::ScopedTempDir directory;
ASSERT_TRUE(directory.CreateUniqueTempDir()); ASSERT_TRUE(directory.CreateUniqueTempDir());
EXPECT_TRUE(chrome_screenshot_grabber->CanTakeScreenshot()); EXPECT_TRUE(chrome_screenshot_grabber->CanTakeScreenshot());
chrome_screenshot_grabber->screenshot_grabber()->TakeScreenshot( chrome_screenshot_grabber->HandleTakeWindowScreenshot(
ash::Shell::GetPrimaryRootWindow(), gfx::Rect(0, 0, 100, 100), ash::Shell::GetPrimaryRootWindow());
directory.GetPath().AppendASCII("Screenshot.png"));
EXPECT_FALSE( EXPECT_FALSE(
chrome_screenshot_grabber->screenshot_grabber()->CanTakeScreenshot()); chrome_screenshot_grabber->screenshot_grabber()->CanTakeScreenshot());
RunLoop(); RunLoop();
chrome_screenshot_grabber->screenshot_grabber()->RemoveObserver(this); SetTestObserver(chrome_screenshot_grabber, nullptr);
EXPECT_TRUE(notification_added_); EXPECT_TRUE(notification_added_);
EXPECT_TRUE(display_service_->GetNotification(std::string("screenshot"))); EXPECT_TRUE(display_service_->GetNotification(std::string("screenshot")));
EXPECT_EQ(ScreenshotGrabberObserver::SCREENSHOT_SUCCESS, screenshot_result_); EXPECT_EQ(ui::ScreenshotResult::SUCCESS, screenshot_result_);
EXPECT_TRUE(base::PathExists(screenshot_path_)); EXPECT_TRUE(base::PathExists(screenshot_path_));
EXPECT_FALSE(IsImageClipboardAvailable()); EXPECT_FALSE(IsImageClipboardAvailable());
......
// Copyright 2018 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.
#ifndef CHROME_BROWSER_UI_ASH_CHROME_SCREENSHOT_GRABBER_TEST_OBSERVER_H_
#define CHROME_BROWSER_UI_ASH_CHROME_SCREENSHOT_GRABBER_TEST_OBSERVER_H_
#include "ui/snapshot/screenshot_grabber.h"
// Testing interface to ChromeScreenshotGrabber.
class ChromeScreenshotGrabberTestObserver {
public:
// Dispatched after attempting to take a screenshot with the |result| and
// |screenshot_path| of the taken screenshot (if successful).
virtual void OnScreenshotCompleted(ui::ScreenshotResult screenshot_result,
const base::FilePath& screenshot_path) = 0;
protected:
virtual ~ChromeScreenshotGrabberTestObserver() {}
};
#endif // CHROME_BROWSER_UI_ASH_CHROME_SCREENSHOT_GRABBER_TEST_OBSERVER_H_
...@@ -10,7 +10,6 @@ jumbo_component("snapshot") { ...@@ -10,7 +10,6 @@ jumbo_component("snapshot") {
sources = [ sources = [
"screenshot_grabber.cc", "screenshot_grabber.cc",
"screenshot_grabber.h", "screenshot_grabber.h",
"screenshot_grabber_observer.h",
"snapshot.cc", "snapshot.cc",
"snapshot.h", "snapshot.h",
"snapshot_android.cc", "snapshot_android.cc",
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include <climits> #include <climits>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file_util.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "base/task_scheduler/post_task.h" #include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "ui/gfx/image/image.h"
#include "ui/snapshot/snapshot.h" #include "ui/snapshot/snapshot.h"
#if defined(USE_AURA) #if defined(USE_AURA)
...@@ -35,80 +34,8 @@ namespace { ...@@ -35,80 +34,8 @@ namespace {
// more than 1000 to prevent the conflict of filenames. // more than 1000 to prevent the conflict of filenames.
const int kScreenshotMinimumIntervalInMS = 1000; const int kScreenshotMinimumIntervalInMS = 1000;
using ShowNotificationCallback =
base::Callback<void(ScreenshotGrabberObserver::Result screenshot_result,
const base::FilePath& screenshot_path)>;
void SaveScreenshot(scoped_refptr<base::TaskRunner> ui_task_runner,
const ShowNotificationCallback& callback,
const base::FilePath& screenshot_path,
scoped_refptr<base::RefCountedMemory> png_data,
ScreenshotGrabberDelegate::FileResult result,
const base::FilePath& local_path) {
DCHECK(!base::MessageLoopForUI::IsCurrent());
DCHECK(!screenshot_path.empty());
// Convert FileResult into ScreenshotGrabberObserver::Result.
ScreenshotGrabberObserver::Result screenshot_result =
ScreenshotGrabberObserver::SCREENSHOT_SUCCESS;
switch (result) {
case ScreenshotGrabberDelegate::FILE_SUCCESS:
// Successfully got a local file to write to, write png data.
DCHECK_GT(static_cast<int>(png_data->size()), 0);
if (static_cast<size_t>(base::WriteFile(
local_path, reinterpret_cast<const char*>(png_data->front()),
static_cast<int>(png_data->size()))) != png_data->size()) {
LOG(ERROR) << "Failed to save to " << local_path.value();
screenshot_result =
ScreenshotGrabberObserver::SCREENSHOT_WRITE_FILE_FAILED;
}
break;
case ScreenshotGrabberDelegate::FILE_CHECK_DIR_FAILED:
screenshot_result =
ScreenshotGrabberObserver::SCREENSHOT_CHECK_DIR_FAILED;
break;
case ScreenshotGrabberDelegate::FILE_CREATE_DIR_FAILED:
screenshot_result =
ScreenshotGrabberObserver::SCREENSHOT_CREATE_DIR_FAILED;
break;
case ScreenshotGrabberDelegate::FILE_CREATE_FAILED:
screenshot_result =
ScreenshotGrabberObserver::SCREENSHOT_CREATE_FILE_FAILED;
break;
}
// Report the result on the UI thread.
ui_task_runner->PostTask(
FROM_HERE, base::Bind(callback, screenshot_result, screenshot_path));
}
void EnsureLocalDirectoryExists(
const base::FilePath& path,
ScreenshotGrabberDelegate::FileCallback callback) {
DCHECK(!base::MessageLoopForUI::IsCurrent());
DCHECK(!path.empty());
if (!base::CreateDirectory(path.DirName())) {
LOG(ERROR) << "Failed to ensure the existence of "
<< path.DirName().value();
callback.Run(ScreenshotGrabberDelegate::FILE_CREATE_DIR_FAILED, path);
return;
}
callback.Run(ScreenshotGrabberDelegate::FILE_SUCCESS, path);
}
} // namespace } // namespace
void ScreenshotGrabberDelegate::PrepareFileAndRunOnBlockingPool(
const base::FilePath& path,
const FileCallback& callback_on_blocking_pool) {
base::PostTaskWithTraits(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::Bind(EnsureLocalDirectoryExists, path, callback_on_blocking_pool));
}
#if defined(USE_AURA) #if defined(USE_AURA)
class ScreenshotGrabber::ScopedCursorHider { class ScreenshotGrabber::ScopedCursorHider {
public: public:
...@@ -138,15 +65,14 @@ class ScreenshotGrabber::ScopedCursorHider { ...@@ -138,15 +65,14 @@ class ScreenshotGrabber::ScopedCursorHider {
}; };
#endif #endif
ScreenshotGrabber::ScreenshotGrabber(ScreenshotGrabberDelegate* client) ScreenshotGrabber::ScreenshotGrabber() : factory_(this) {}
: client_(client), factory_(this) {}
ScreenshotGrabber::~ScreenshotGrabber() { ScreenshotGrabber::~ScreenshotGrabber() {
} }
void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window, void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window,
const gfx::Rect& rect, const gfx::Rect& rect,
const base::FilePath& screenshot_path) { ScreenshotCallback callback) {
DCHECK(base::MessageLoopForUI::IsCurrent()); DCHECK(base::MessageLoopForUI::IsCurrent());
last_screenshot_timestamp_ = base::TimeTicks::Now(); last_screenshot_timestamp_ = base::TimeTicks::Now();
...@@ -165,8 +91,8 @@ void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window, ...@@ -165,8 +91,8 @@ void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window,
ui::GrabWindowSnapshotAsyncPNG( ui::GrabWindowSnapshotAsyncPNG(
window, rect, window, rect,
base::Bind(&ScreenshotGrabber::GrabWindowSnapshotAsyncCallback, base::Bind(&ScreenshotGrabber::GrabWindowSnapshotAsyncCallback,
factory_.GetWeakPtr(), window_identifier, screenshot_path, factory_.GetWeakPtr(), window_identifier, is_partial,
is_partial)); base::Passed(&callback)));
} }
bool ScreenshotGrabber::CanTakeScreenshot() { bool ScreenshotGrabber::CanTakeScreenshot() {
...@@ -175,58 +101,32 @@ bool ScreenshotGrabber::CanTakeScreenshot() { ...@@ -175,58 +101,32 @@ bool ScreenshotGrabber::CanTakeScreenshot() {
base::TimeDelta::FromMilliseconds(kScreenshotMinimumIntervalInMS); base::TimeDelta::FromMilliseconds(kScreenshotMinimumIntervalInMS);
} }
void ScreenshotGrabber::NotifyScreenshotCompleted(
ScreenshotGrabberObserver::Result screenshot_result,
const base::FilePath& screenshot_path) {
DCHECK(base::MessageLoopForUI::IsCurrent());
#if defined(USE_AURA)
cursor_hider_.reset();
#endif
for (ScreenshotGrabberObserver& observer : observers_)
observer.OnScreenshotCompleted(screenshot_result, screenshot_path);
}
void ScreenshotGrabber::AddObserver(ScreenshotGrabberObserver* observer) {
observers_.AddObserver(observer);
}
void ScreenshotGrabber::RemoveObserver(ScreenshotGrabberObserver* observer) {
observers_.RemoveObserver(observer);
}
bool ScreenshotGrabber::HasObserver(
const ScreenshotGrabberObserver* observer) const {
return observers_.HasObserver(observer);
}
void ScreenshotGrabber::GrabWindowSnapshotAsyncCallback( void ScreenshotGrabber::GrabWindowSnapshotAsyncCallback(
const std::string& window_identifier, const std::string& window_identifier,
base::FilePath screenshot_path,
bool is_partial, bool is_partial,
ScreenshotCallback callback,
scoped_refptr<base::RefCountedMemory> png_data) { scoped_refptr<base::RefCountedMemory> png_data) {
DCHECK(base::MessageLoopForUI::IsCurrent()); DCHECK(base::MessageLoopForUI::IsCurrent());
#if defined(USE_AURA)
cursor_hider_.reset();
#endif
if (!png_data.get()) { if (!png_data.get()) {
if (is_partial) { if (is_partial) {
LOG(ERROR) << "Failed to grab the window screenshot"; LOG(ERROR) << "Failed to grab the window screenshot";
NotifyScreenshotCompleted( std::move(callback).Run(ScreenshotResult::GRABWINDOW_PARTIAL_FAILED,
ScreenshotGrabberObserver::SCREENSHOT_GRABWINDOW_PARTIAL_FAILED, nullptr);
screenshot_path);
} else { } else {
LOG(ERROR) << "Failed to grab the window screenshot for " LOG(ERROR) << "Failed to grab the window screenshot for "
<< window_identifier; << window_identifier;
NotifyScreenshotCompleted( std::move(callback).Run(ScreenshotResult::GRABWINDOW_FULL_FAILED,
ScreenshotGrabberObserver::SCREENSHOT_GRABWINDOW_FULL_FAILED, nullptr);
screenshot_path);
} }
return; return;
} }
ShowNotificationCallback notification_callback(base::Bind( std::move(callback).Run(ScreenshotResult::SUCCESS, std::move(png_data));
&ScreenshotGrabber::NotifyScreenshotCompleted, factory_.GetWeakPtr()));
client_->PrepareFileAndRunOnBlockingPool(
screenshot_path,
base::Bind(&SaveScreenshot, base::ThreadTaskRunnerHandle::Get(),
notification_callback, screenshot_path, png_data));
} }
} // namespace ui } // namespace ui
...@@ -14,61 +14,44 @@ ...@@ -14,61 +14,44 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h" #include "ui/gfx/native_widget_types.h"
#include "ui/snapshot/screenshot_grabber_observer.h"
#include "ui/snapshot/snapshot_export.h" #include "ui/snapshot/snapshot_export.h"
namespace ui { namespace ui {
// TODO(flackr): Componentize google drive so that we don't need the // Result of the entire screenshotting attempt. This enum is fat for various
// ScreenshotGrabberDelegate. // file operations which could happen in the chrome layer.
class SNAPSHOT_EXPORT ScreenshotGrabberDelegate { enum class ScreenshotResult {
public: SUCCESS,
enum FileResult { GRABWINDOW_PARTIAL_FAILED,
FILE_SUCCESS, GRABWINDOW_FULL_FAILED,
FILE_CHECK_DIR_FAILED, CREATE_DIR_FAILED,
FILE_CREATE_DIR_FAILED, GET_DIR_FAILED,
FILE_CREATE_FAILED CHECK_DIR_FAILED,
}; CREATE_FILE_FAILED,
WRITE_FILE_FAILED,
// Callback called with the |result| of trying to create a local writable DISABLED
// |path| for the possibly remote path.
using FileCallback =
base::Callback<void(FileResult result, const base::FilePath& path)>;
ScreenshotGrabberDelegate() {}
virtual ~ScreenshotGrabberDelegate() {}
// Prepares a writable file for |path|. If |path| is a non-local path (i.e.
// Google drive) and it is supported this will create a local cached copy of
// the remote file and call the callback with the local path.
virtual void PrepareFileAndRunOnBlockingPool(
const base::FilePath& path,
const FileCallback& callback_on_blocking_pool);
}; };
class SNAPSHOT_EXPORT ScreenshotGrabber { class SNAPSHOT_EXPORT ScreenshotGrabber {
public: public:
explicit ScreenshotGrabber(ScreenshotGrabberDelegate* client); ScreenshotGrabber();
~ScreenshotGrabber(); ~ScreenshotGrabber();
// Callback for the new system, which ignores the observer crud.
using ScreenshotCallback =
base::OnceCallback<void(ui::ScreenshotResult screenshot_result,
scoped_refptr<base::RefCountedMemory> png_data)>;
// Takes a screenshot of |rect| in |window| in that window's coordinate space // Takes a screenshot of |rect| in |window| in that window's coordinate space
// saving the result to |screenshot_path|. // and return it to |callback|.
void TakeScreenshot(gfx::NativeWindow window, void TakeScreenshot(gfx::NativeWindow window,
const gfx::Rect& rect, const gfx::Rect& rect,
const base::FilePath& screenshot_path); ScreenshotCallback callback);
bool CanTakeScreenshot();
void NotifyScreenshotCompleted( bool CanTakeScreenshot();
ScreenshotGrabberObserver::Result screenshot_result,
const base::FilePath& screenshot_path);
void AddObserver(ScreenshotGrabberObserver* observer);
void RemoveObserver(ScreenshotGrabberObserver* observer);
bool HasObserver(const ScreenshotGrabberObserver* observer) const;
private: private:
#if defined(USE_AURA) #if defined(USE_AURA)
...@@ -77,13 +60,10 @@ class SNAPSHOT_EXPORT ScreenshotGrabber { ...@@ -77,13 +60,10 @@ class SNAPSHOT_EXPORT ScreenshotGrabber {
void GrabWindowSnapshotAsyncCallback( void GrabWindowSnapshotAsyncCallback(
const std::string& window_identifier, const std::string& window_identifier,
base::FilePath screenshot_path,
bool is_partial, bool is_partial,
ScreenshotCallback callback,
scoped_refptr<base::RefCountedMemory> png_data); scoped_refptr<base::RefCountedMemory> png_data);
// A weak pointer to the screenshot taker client.
ScreenshotGrabberDelegate* client_;
// The timestamp when the screenshot task was issued last time. // The timestamp when the screenshot task was issued last time.
base::TimeTicks last_screenshot_timestamp_; base::TimeTicks last_screenshot_timestamp_;
...@@ -92,7 +72,6 @@ class SNAPSHOT_EXPORT ScreenshotGrabber { ...@@ -92,7 +72,6 @@ class SNAPSHOT_EXPORT ScreenshotGrabber {
std::unique_ptr<ScopedCursorHider> cursor_hider_; std::unique_ptr<ScopedCursorHider> cursor_hider_;
#endif #endif
base::ObserverList<ScreenshotGrabberObserver> observers_;
base::WeakPtrFactory<ScreenshotGrabber> factory_; base::WeakPtrFactory<ScreenshotGrabber> factory_;
DISALLOW_COPY_AND_ASSIGN(ScreenshotGrabber); DISALLOW_COPY_AND_ASSIGN(ScreenshotGrabber);
......
// Copyright 2014 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.
#ifndef UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
#define UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
#include "base/files/file_path.h"
#include "ui/snapshot/snapshot_export.h"
namespace ui {
class SNAPSHOT_EXPORT ScreenshotGrabberObserver {
public:
enum Result {
SCREENSHOT_SUCCESS = 0,
SCREENSHOT_GRABWINDOW_PARTIAL_FAILED,
SCREENSHOT_GRABWINDOW_FULL_FAILED,
SCREENSHOT_CREATE_DIR_FAILED,
SCREENSHOT_GET_DIR_FAILED,
SCREENSHOT_CHECK_DIR_FAILED,
SCREENSHOT_CREATE_FILE_FAILED,
SCREENSHOT_WRITE_FILE_FAILED,
SCREENSHOTS_DISABLED,
SCREENSHOT_RESULT_COUNT
};
// Dispatched after attempting to take a screenshot with the |result| and
// |screenshot_path| of the taken screenshot (if successful).
virtual void OnScreenshotCompleted(Result screenshot_result,
const base::FilePath& screenshot_path) = 0;
protected:
virtual ~ScreenshotGrabberObserver() {}
};
} // namespace ui
#endif // UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment