Commit 1b03fdb7 authored by Alex Newcomer's avatar Alex Newcomer Committed by Commit Bot

cros: Clear ClipboardHistory when Clipboard is cleared

We clear the clipboard when entering LockedFullscreen.
LockedFullscreen is a state entered to start a secure test or poll.

We clear the clipboard in these cases to prevent cheating,
so it also makes sense to clear ClipboardHistory.

In the future we would like to create a new ClipboardHistory and
restore the old one  after leaving LockedFullscreen, but for now we
will just clear ClipboardHistory.

Bug: 1145651
Change-Id: Id5583567375384f2b2bc877f77acf6c054825977
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521230
Commit-Queue: Alex Newcomer <newcomer@chromium.org>
Reviewed-by: default avatarDavid Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#824930}
parent 86728711
...@@ -84,7 +84,14 @@ void ClipboardHistory::OnClipboardDataChanged() { ...@@ -84,7 +84,14 @@ void ClipboardHistory::OnClipboardDataChanged() {
ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory); ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory);
const auto* clipboard_data = clipboard->GetClipboardData(&data_dst); const auto* clipboard_data = clipboard->GetClipboardData(&data_dst);
CHECK(clipboard_data); if (!clipboard_data) {
// |clipboard_data| is only empty when the Clipboard is cleared. This is
// done to prevent data leakage into or from locked forms(Locked Fullscreen
// state). Clear ClipboardHistory.
commit_data_weak_factory_.InvalidateWeakPtrs();
Clear();
return;
}
// We post commit |clipboard_data| at the end of the current task sequence to // We post commit |clipboard_data| at the end of the current task sequence to
// debounce the case where multiple copies are programmatically performed. // debounce the case where multiple copies are programmatically performed.
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <memory> #include <memory>
#include "ash/accelerators/accelerator_controller_impl.h" #include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/clipboard/clipboard_history.h"
#include "ash/clipboard/clipboard_history_menu_model_adapter.h" #include "ash/clipboard/clipboard_history_menu_model_adapter.h"
#include "ash/clipboard/clipboard_history_resource_manager.h" #include "ash/clipboard/clipboard_history_resource_manager.h"
#include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_history_util.h"
...@@ -194,9 +193,13 @@ ClipboardHistoryControllerImpl::ClipboardHistoryControllerImpl() ...@@ -194,9 +193,13 @@ ClipboardHistoryControllerImpl::ClipboardHistoryControllerImpl()
menu_delegate_(std::make_unique<MenuDelegate>(this)), menu_delegate_(std::make_unique<MenuDelegate>(this)),
nudge_controller_( nudge_controller_(
std::make_unique<ClipboardNudgeController>(clipboard_history_.get(), std::make_unique<ClipboardNudgeController>(clipboard_history_.get(),
this)) {} this)) {
clipboard_history_->AddObserver(this);
}
ClipboardHistoryControllerImpl::~ClipboardHistoryControllerImpl() = default; ClipboardHistoryControllerImpl::~ClipboardHistoryControllerImpl() {
clipboard_history_->RemoveObserver(this);
}
void ClipboardHistoryControllerImpl::AddObserver(Observer* observer) const { void ClipboardHistoryControllerImpl::AddObserver(Observer* observer) const {
observers_.AddObserver(observer); observers_.AddObserver(observer);
...@@ -259,6 +262,16 @@ bool ClipboardHistoryControllerImpl::CanShowMenu() const { ...@@ -259,6 +262,16 @@ bool ClipboardHistoryControllerImpl::CanShowMenu() const {
clipboard_history_->IsEnabledInCurrentMode(); clipboard_history_->IsEnabledInCurrentMode();
} }
void ClipboardHistoryControllerImpl::OnClipboardHistoryCleared() {
// Prevent clipboard contents getting restored if the Clipboard is cleared
// soon after a `PasteMenuItemData()`.
weak_ptr_factory_.InvalidateWeakPtrs();
if (!IsMenuShowing())
return;
context_menu_->Cancel();
context_menu_.reset();
}
void ClipboardHistoryControllerImpl::ExecuteSelectedMenuItem(int event_flags) { void ClipboardHistoryControllerImpl::ExecuteSelectedMenuItem(int event_flags) {
DCHECK(IsMenuShowing()); DCHECK(IsMenuShowing());
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/clipboard/clipboard_history.h"
#include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_item.h"
#include "ash/public/cpp/clipboard_history_controller.h" #include "ash/public/cpp/clipboard_history_controller.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -24,7 +25,6 @@ class Rect; ...@@ -24,7 +25,6 @@ class Rect;
namespace ash { namespace ash {
class ClipboardHistory;
class ClipboardHistoryMenuModelAdapter; class ClipboardHistoryMenuModelAdapter;
class ClipboardHistoryResourceManager; class ClipboardHistoryResourceManager;
class ClipboardNudgeController; class ClipboardNudgeController;
...@@ -32,7 +32,8 @@ class ClipboardNudgeController; ...@@ -32,7 +32,8 @@ class ClipboardNudgeController;
// Shows a menu with the last few things saved in the clipboard when the // Shows a menu with the last few things saved in the clipboard when the
// keyboard shortcut is pressed. // keyboard shortcut is pressed.
class ASH_EXPORT ClipboardHistoryControllerImpl class ASH_EXPORT ClipboardHistoryControllerImpl
: public ClipboardHistoryController { : public ClipboardHistoryController,
public ClipboardHistory::Observer {
public: public:
class Observer : public base::CheckedObserver { class Observer : public base::CheckedObserver {
public: public:
...@@ -88,6 +89,9 @@ class ASH_EXPORT ClipboardHistoryControllerImpl ...@@ -88,6 +89,9 @@ class ASH_EXPORT ClipboardHistoryControllerImpl
ui::MenuSourceType source_type) override; ui::MenuSourceType source_type) override;
bool CanShowMenu() const override; bool CanShowMenu() const override;
// ClipboardHistory::Observer:
void OnClipboardHistoryCleared() override;
void ExecuteSelectedMenuItem(int event_flags); void ExecuteSelectedMenuItem(int event_flags);
// Executes the command specified by `command_id` with the given event flags. // Executes the command specified by `command_id` with the given event flags.
......
...@@ -262,4 +262,38 @@ TEST_F(ClipboardHistoryControllerTest, VThenSearchDoesNotShowLauncher) { ...@@ -262,4 +262,38 @@ TEST_F(ClipboardHistoryControllerTest, VThenSearchDoesNotShowLauncher) {
/*display_id=*/base::nullopt)); /*display_id=*/base::nullopt));
} }
// Tests that clearing the clipboard clears ClipboardHistory
TEST_F(ClipboardHistoryControllerTest, ClearClipboardClearsHistory) {
// Write a single item to ClipboardHistory.
WriteToClipboard("test");
// Clear the clipboard.
ui::Clipboard::GetForCurrentThread()->Clear(ui::ClipboardBuffer::kCopyPaste);
FlushMessageLoop();
// History should also be cleared.
const std::list<ClipboardHistoryItem>& items =
Shell::Get()->clipboard_history_controller()->history()->GetItems();
EXPECT_EQ(0u, items.size());
ShowMenu();
EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
}
// Tests that clearing the clipboard closes the ClipboardHistory menu.
TEST_F(ClipboardHistoryControllerTest,
ClearingClipboardClosesClipboardHistory) {
// Write a single item to ClipboardHistory.
WriteToClipboard("test");
ShowMenu();
EXPECT_TRUE(GetClipboardHistoryController()->IsMenuShowing());
ui::Clipboard::GetForCurrentThread()->Clear(ui::ClipboardBuffer::kCopyPaste);
FlushMessageLoop();
EXPECT_FALSE(GetClipboardHistoryController()->IsMenuShowing());
}
} // namespace ash } // namespace ash
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_buffer.h" #include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/clipboard/scoped_clipboard_writer.h"
...@@ -222,6 +223,36 @@ TEST_F(ClipboardHistoryTest, ClearHistoryBasic) { ...@@ -222,6 +223,36 @@ TEST_F(ClipboardHistoryTest, ClearHistoryBasic) {
EnsureTextHistory(expected_strings); EnsureTextHistory(expected_strings);
} }
// Tests that there is no crash when an empty clipboard is cleared with empty
// clipboard history.
TEST_F(ClipboardHistoryTest, ClearHistoryFromClipboardNoHistory) {
ui::Clipboard::GetForCurrentThread()->Clear(ui::ClipboardBuffer::kCopyPaste);
}
// Tests that clipboard history is cleared when the clipboard is cleared.
TEST_F(ClipboardHistoryTest, ClearHistoryFromClipboardWithHistory) {
std::vector<base::string16> input_strings{base::UTF8ToUTF16("test1"),
base::UTF8ToUTF16("test2")};
std::vector<base::string16> expected_strings_before_clear{
base::UTF8ToUTF16("test2"), base::UTF8ToUTF16("test1")};
std::vector<base::string16> expected_strings_after_clear{};
for (const auto& input_string : input_strings) {
{
ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
scw.WriteText(input_string);
}
base::RunLoop().RunUntilIdle();
}
EnsureTextHistory(expected_strings_before_clear);
ui::Clipboard::GetForCurrentThread()->Clear(ui::ClipboardBuffer::kCopyPaste);
EnsureTextHistory(expected_strings_after_clear);
}
// Tests that the limit of clipboard history is respected. // Tests that the limit of clipboard history is respected.
TEST_F(ClipboardHistoryTest, HistoryLimit) { TEST_F(ClipboardHistoryTest, HistoryLimit) {
std::vector<base::string16> input_strings{ std::vector<base::string16> input_strings{
......
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