File: clipboard_history.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (148 lines) | stat: -rw-r--r-- 5,634 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_
#define ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_

#include <deque>
#include <list>

#include "ash/ash_export.h"
#include "ash/clipboard/clipboard_history_item.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/token.h"
#include "ui/base/clipboard/clipboard_data.h"
#include "ui/base/clipboard/clipboard_observer.h"

namespace ash {
class ScopedClipboardHistoryPauseImpl;

namespace clipboard_history_util {
enum class PauseBehavior;
}  // namespace clipboard_history_util

// Keeps track of the last few things saved in the clipboard.
class ASH_EXPORT ClipboardHistory : public ui::ClipboardObserver {
 public:
  class ASH_EXPORT Observer : public base::CheckedObserver {
   public:
    // Called when a `ClipboardHistoryItem` has been added. `is_duplicate` is
    // true if `item` is already in clipboard history when adding.
    virtual void OnClipboardHistoryItemAdded(const ClipboardHistoryItem& item,
                                             bool is_duplicate) {}

    // Called when a ClipboardHistoryItem has been removed.
    virtual void OnClipboardHistoryItemRemoved(
        const ClipboardHistoryItem& item) {}

    // Called when ClipboardHistory is Clear()-ed.
    virtual void OnClipboardHistoryCleared() {}

    // Called when the operation on clipboard data is confirmed.
    virtual void OnOperationConfirmed(bool copy) {}
  };

  ClipboardHistory();
  ClipboardHistory(const ClipboardHistory&) = delete;
  ClipboardHistory& operator=(const ClipboardHistory&) = delete;
  ~ClipboardHistory() override;

  void AddObserver(Observer* observer) const;
  void RemoveObserver(Observer* observer) const;

  // Returns the list of most recent items. The returned list is sorted by
  // recency.
  const std::list<ClipboardHistoryItem>& GetItems() const;
  std::list<ClipboardHistoryItem>& GetItems();

  // Deletes every item in the clipboard history. The clipboard is cleared as
  // well to ensure that its contents stay in sync with the first item in the
  // clipboard history.
  void Clear();

  // Returns whether the clipboard history of the active account is empty.
  bool IsEmpty() const;

  // Remove the item specified by `id`. If the target item does not exist,
  // do nothing.
  void RemoveItemForId(const base::UnguessableToken& id);

  // ui::ClipboardObserver:
  void OnClipboardDataChanged() override;
  void OnClipboardDataRead() override;

  base::WeakPtr<ClipboardHistory> GetWeakPtr();

 private:
  // Friended to allow `ScopedClipboardHistoryPauseImpl` to `Pause()` and
  // `Resume()`.
  // TODO(b/269470292): Use a `PassKey` for this.
  friend class ScopedClipboardHistoryPauseImpl;

  // Ensures that the clipboard buffer contains the same data as the item at the
  // top of clipboard history. If clipboard history is empty, then the clipboard
  // is cleared.
  void SyncClipboardToClipboardHistory();

  // Adds `data` to the top of the history list if `data` is supported by
  // clipboard history. If `data` is not supported, this method no-ops. If
  // `data` is already in the history list, `data` will be moved to the top of
  // the list.
  void MaybeCommitData(ui::ClipboardData data, bool is_reorder_on_paste);

  // When `Pause()` is called, clipboard accesses will modify clipboard history
  // according to `pause_behavior` until `Resume()` is called with that pause's
  // `pause_id`. If `Pause()` is called while another pause is active, the
  // newest pause's behavior will be respected. When the newest pause ends, the
  // next newest pause's behavior will be restored.
  const base::Token& Pause(
      clipboard_history_util::PauseBehavior pause_behavior);
  void Resume(const base::Token& pause_id);
  struct PauseInfo {
    base::Token pause_id;
    clipboard_history_util::PauseBehavior pause_behavior;
  };

  // Keeps track of consecutive clipboard operations and records metrics.
  void OnClipboardOperation(bool copy);

  // Active clipboard history pauses, stored in LIFO order so that the newest
  // pause dictates behavior. Rather than a stack, we use a deque where the
  // newest pause is added to and removed from the front. Not using a stack
  // allows us to find and remove the correct pause in cases where pauses are
  // not destroyed in LIFO order, and adding to the front of the deque rather
  // than the back allows us to iterate forward when searching for the correct
  // pause, simplifying removal logic.
  std::deque<PauseInfo> pauses_;

  // The number of consecutive copies, reset after a paste.
  int consecutive_copies_ = 0;

  // The number of consecutive pastes, reset after a copy.
  int consecutive_pastes_ = 0;

  // The history of data copied to the Clipboard. Items of the list are sorted
  // by recency.
  std::list<ClipboardHistoryItem> history_list_;

  // Mutable to allow adding/removing from |observers_| through a const
  // ClipboardHistory.
  mutable base::ObserverList<Observer> observers_;

  // Factory to create WeakPtrs used to debounce calls to `CommitData()`.
  base::WeakPtrFactory<ClipboardHistory> commit_data_weak_factory_{this};

  // Factory to create WeakPtrs used to debounce calls to
  // `OnClipboardOperation()`.
  base::WeakPtrFactory<ClipboardHistory> clipboard_histogram_weak_factory_{
      this};

  // Factory to create WeakPtrs for ClipboardHistory.
  base::WeakPtrFactory<ClipboardHistory> weak_factory_{this};
};

}  // namespace ash

#endif  // ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_