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() {
ui::DataTransferEndpoint data_dst(ui::EndpointType::kClipboardHistory);
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
// debounce the case where multiple copies are programmatically performed.
......
......@@ -7,7 +7,6 @@
#include <memory>
#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_resource_manager.h"
#include "ash/clipboard/clipboard_history_util.h"
......@@ -194,9 +193,13 @@ ClipboardHistoryControllerImpl::ClipboardHistoryControllerImpl()
menu_delegate_(std::make_unique<MenuDelegate>(this)),
nudge_controller_(
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 {
observers_.AddObserver(observer);
......@@ -259,6 +262,16 @@ bool ClipboardHistoryControllerImpl::CanShowMenu() const {
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) {
DCHECK(IsMenuShowing());
......
......@@ -9,6 +9,7 @@
#include <vector>
#include "ash/ash_export.h"
#include "ash/clipboard/clipboard_history.h"
#include "ash/clipboard/clipboard_history_item.h"
#include "ash/public/cpp/clipboard_history_controller.h"
#include "base/memory/weak_ptr.h"
......@@ -24,7 +25,6 @@ class Rect;
namespace ash {
class ClipboardHistory;
class ClipboardHistoryMenuModelAdapter;
class ClipboardHistoryResourceManager;
class ClipboardNudgeController;
......@@ -32,7 +32,8 @@ class ClipboardNudgeController;
// Shows a menu with the last few things saved in the clipboard when the
// keyboard shortcut is pressed.
class ASH_EXPORT ClipboardHistoryControllerImpl
: public ClipboardHistoryController {
: public ClipboardHistoryController,
public ClipboardHistory::Observer {
public:
class Observer : public base::CheckedObserver {
public:
......@@ -88,6 +89,9 @@ class ASH_EXPORT ClipboardHistoryControllerImpl
ui::MenuSourceType source_type) override;
bool CanShowMenu() const override;
// ClipboardHistory::Observer:
void OnClipboardHistoryCleared() override;
void ExecuteSelectedMenuItem(int event_flags);
// Executes the command specified by `command_id` with the given event flags.
......
......@@ -262,4 +262,38 @@ TEST_F(ClipboardHistoryControllerTest, VThenSearchDoesNotShowLauncher) {
/*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
......@@ -17,6 +17,7 @@
#include "chromeos/constants/chromeos_features.h"
#include "testing/gtest/include/gtest/gtest.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/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
......@@ -222,6 +223,36 @@ TEST_F(ClipboardHistoryTest, ClearHistoryBasic) {
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.
TEST_F(ClipboardHistoryTest, HistoryLimit) {
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