blob: 5820f4d0d4facef9c16faf68c06d4e1da2f4895a [file] [log] [blame]
Avi Drissman3a215d1e2022-09-07 19:43:091// Copyright 2020 The Chromium Authors
Alex Newcomer46bfe142020-07-10 20:28:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_
6#define ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_
7
Colin Kincaide6b16934742022-07-12 22:50:318#include <deque>
David Black381395a92020-07-30 00:42:419#include <list>
Alex Newcomer46bfe142020-07-10 20:28:5610
11#include "ash/ash_export.h"
Alex Newcomerf58dffe2020-08-20 21:59:2712#include "ash/clipboard/clipboard_history_item.h"
Alex Newcomer8aa90a92020-07-16 19:37:0213#include "base/memory/weak_ptr.h"
Alex Newcomerf58dffe2020-08-20 21:59:2714#include "base/observer_list.h"
Colin Kincaide6b16934742022-07-12 22:50:3115#include "base/token.h"
Alex Newcomer46bfe142020-07-10 20:28:5616#include "ui/base/clipboard/clipboard_data.h"
17#include "ui/base/clipboard/clipboard_observer.h"
18
19namespace ash {
Alex Newcomer104c2142020-11-19 02:06:3820class ScopedClipboardHistoryPauseImpl;
21
Colin Kincaid8e1f7b62022-08-27 05:09:5322namespace clipboard_history_util {
23enum class PauseBehavior;
24} // namespace clipboard_history_util
25
Andrew Xu16c53712020-08-12 16:30:5526// Keeps track of the last few things saved in the clipboard.
27class ASH_EXPORT ClipboardHistory : public ui::ClipboardObserver {
Alex Newcomer46bfe142020-07-10 20:28:5628 public:
Alex Newcomerf58dffe2020-08-20 21:59:2729 class ASH_EXPORT Observer : public base::CheckedObserver {
30 public:
31 // Called when a ClipboardHistoryItem has been added.
Matthew Mourgosfeb96c02020-12-11 00:47:3032 virtual void OnClipboardHistoryItemAdded(const ClipboardHistoryItem& item,
33 bool is_duplicate) {}
Andrew Xue57b31d62021-01-26 16:32:2034
Alex Newcomerf58dffe2020-08-20 21:59:2735 // Called when a ClipboardHistoryItem has been removed.
36 virtual void OnClipboardHistoryItemRemoved(
37 const ClipboardHistoryItem& item) {}
Andrew Xue57b31d62021-01-26 16:32:2038
Alex Newcomerf58dffe2020-08-20 21:59:2739 // Called when ClipboardHistory is Clear()-ed.
40 virtual void OnClipboardHistoryCleared() {}
Andrew Xue57b31d62021-01-26 16:32:2041
42 // Called when the operation on clipboard data is confirmed.
43 virtual void OnOperationConfirmed(bool copy) {}
Alex Newcomerf58dffe2020-08-20 21:59:2744 };
45
Alex Newcomer46bfe142020-07-10 20:28:5646 ClipboardHistory();
47 ClipboardHistory(const ClipboardHistory&) = delete;
48 ClipboardHistory& operator=(const ClipboardHistory&) = delete;
49 ~ClipboardHistory() override;
50
Alex Newcomerf58dffe2020-08-20 21:59:2751 void AddObserver(Observer* observer) const;
52 void RemoveObserver(Observer* observer) const;
53
Andrew Xu16c53712020-08-12 16:30:5554 // Returns the list of most recent items. The returned list is sorted by
55 // recency.
Alex Newcomerf58dffe2020-08-20 21:59:2756 const std::list<ClipboardHistoryItem>& GetItems() const;
Colin Kincaid53a2c64c2023-02-21 18:15:4857 std::list<ClipboardHistoryItem>& GetItems();
David Black381395a92020-07-30 00:42:4158
Andrew Xu16c53712020-08-12 16:30:5559 // Deletes clipboard history. Does not modify content stored in the clipboard.
David Black381395a92020-07-30 00:42:4160 void Clear();
Alex Newcomer46bfe142020-07-10 20:28:5661
Andrew Xu0188e452020-07-25 06:43:0162 // Returns whether the clipboard history of the active account is empty.
Alex Newcomer46bfe142020-07-10 20:28:5663 bool IsEmpty() const;
64
Andrew Xu8a988dfc2020-08-31 17:44:3065 // Remove the item specified by `id`. If the target item does not exist,
66 // do nothing.
67 void RemoveItemForId(const base::UnguessableToken& id);
68
Alex Newcomerb6de0c062021-01-12 00:51:2169 // ui::ClipboardObserver:
Alex Newcomer46bfe142020-07-10 20:28:5670 void OnClipboardDataChanged() override;
Alex Newcomerb6de0c062021-01-12 00:51:2171 void OnClipboardDataRead() override;
Alex Newcomer46bfe142020-07-10 20:28:5672
Alex Newcomer104c2142020-11-19 02:06:3873 base::WeakPtr<ClipboardHistory> GetWeakPtr();
74
Alex Newcomer46bfe142020-07-10 20:28:5675 private:
Colin Kincaid53a2c64c2023-02-21 18:15:4876 // Friended to allow `ScopedClipboardHistoryPauseImpl` to `Pause()` and
Alex Newcomer104c2142020-11-19 02:06:3877 // `Resume()`.
Colin Kincaid53a2c64c2023-02-21 18:15:4878 // TODO(b/269470292): Use a `PassKey` for this.
Alex Newcomer104c2142020-11-19 02:06:3879 friend class ScopedClipboardHistoryPauseImpl;
80
Colin Kincaid88a3e842022-06-16 00:07:1681 // Ensures that the clipboard buffer contains the same data as the item at the
82 // top of clipboard history. If clipboard history is empty, then the clipboard
83 // is cleared.
84 void SyncClipboardToClipboardHistory();
85
Colin Kincaidadbfb082022-05-26 03:30:3486 // Adds `data` to the top of the history list if `data` is supported by
87 // clipboard history. If `data` is not supported, this method no-ops. If
88 // `data` is already in the history list, `data` will be moved to the top of
89 // the list.
Colin Kincaidf13ac062022-07-13 21:08:4390 void MaybeCommitData(ui::ClipboardData data, bool is_reorder_on_paste);
Andrew Xu16c53712020-08-12 16:30:5591
Colin Kincaide6b16934742022-07-12 22:50:3192 // When `Pause()` is called, clipboard accesses will modify clipboard history
93 // according to `pause_behavior` until `Resume()` is called with that pause's
94 // `pause_id`. If `Pause()` is called while another pause is active, the
95 // newest pause's behavior will be respected. When the newest pause ends, the
96 // next newest pause's behavior will be restored.
Colin Kincaid8e1f7b62022-08-27 05:09:5397 const base::Token& Pause(
98 clipboard_history_util::PauseBehavior pause_behavior);
Colin Kincaide6b16934742022-07-12 22:50:3199 void Resume(const base::Token& pause_id);
100 struct PauseInfo {
101 base::Token pause_id;
Colin Kincaid8e1f7b62022-08-27 05:09:53102 clipboard_history_util::PauseBehavior pause_behavior;
Colin Kincaide6b16934742022-07-12 22:50:31103 };
Alex Newcomer46bfe142020-07-10 20:28:56104
Alex Newcomerb6de0c062021-01-12 00:51:21105 // Keeps track of consecutive clipboard operations and records metrics.
106 void OnClipboardOperation(bool copy);
107
Colin Kincaide6b16934742022-07-12 22:50:31108 // Active clipboard history pauses, stored in LIFO order so that the newest
109 // pause dictates behavior. Rather than a stack, we use a deque where the
110 // newest pause is added to and removed from the front. Not using a stack
111 // allows us to find and remove the correct pause in cases where pauses are
112 // not destroyed in LIFO order, and adding to the front of the deque rather
113 // than the back allows us to iterate forward when searching for the correct
114 // pause, simplifying removal logic.
115 std::deque<PauseInfo> pauses_;
Colin Kincaidadbfb082022-05-26 03:30:34116
Alex Newcomerb6de0c062021-01-12 00:51:21117 // The number of consecutive copies, reset after a paste.
118 int consecutive_copies_ = 0;
119
120 // The number of consecutive pastes, reset after a copy.
121 int consecutive_pastes_ = 0;
122
Andrew Xu16c53712020-08-12 16:30:55123 // The history of data copied to the Clipboard. Items of the list are sorted
124 // by recency.
Alex Newcomerf58dffe2020-08-20 21:59:27125 std::list<ClipboardHistoryItem> history_list_;
126
127 // Mutable to allow adding/removing from |observers_| through a const
128 // ClipboardHistory.
129 mutable base::ObserverList<Observer> observers_;
David Blacka6a0c3ba2020-07-30 18:31:33130
Alex Newcomerb6de0c062021-01-12 00:51:21131 // Factory to create WeakPtrs used to debounce calls to `CommitData()`.
David Blacka6a0c3ba2020-07-30 18:31:33132 base::WeakPtrFactory<ClipboardHistory> commit_data_weak_factory_{this};
Alex Newcomer104c2142020-11-19 02:06:38133
Alex Newcomerb6de0c062021-01-12 00:51:21134 // Factory to create WeakPtrs used to debounce calls to
135 // `OnClipboardOperation()`.
136 base::WeakPtrFactory<ClipboardHistory> clipboard_histogram_weak_factory_{
137 this};
138
Alex Newcomer104c2142020-11-19 02:06:38139 // Factory to create WeakPtrs for ClipboardHistory.
140 base::WeakPtrFactory<ClipboardHistory> weak_factory_{this};
Alex Newcomer46bfe142020-07-10 20:28:56141};
142
143} // namespace ash
144
Andrew Xu0188e452020-07-25 06:43:01145#endif // ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_