clipboard_history.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_
  5. #define ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_
  6. #include <deque>
  7. #include <list>
  8. #include "ash/ash_export.h"
  9. #include "ash/clipboard/clipboard_history_item.h"
  10. #include "ash/clipboard/clipboard_history_util.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/observer_list.h"
  13. #include "base/token.h"
  14. #include "ui/base/clipboard/clipboard_data.h"
  15. #include "ui/base/clipboard/clipboard_observer.h"
  16. namespace ash {
  17. class ScopedClipboardHistoryPauseImpl;
  18. // Keeps track of the last few things saved in the clipboard.
  19. class ASH_EXPORT ClipboardHistory : public ui::ClipboardObserver {
  20. public:
  21. class ASH_EXPORT Observer : public base::CheckedObserver {
  22. public:
  23. // Called when a ClipboardHistoryItem has been added.
  24. virtual void OnClipboardHistoryItemAdded(const ClipboardHistoryItem& item,
  25. bool is_duplicate) {}
  26. // Called when a ClipboardHistoryItem has been removed.
  27. virtual void OnClipboardHistoryItemRemoved(
  28. const ClipboardHistoryItem& item) {}
  29. // Called when ClipboardHistory is Clear()-ed.
  30. virtual void OnClipboardHistoryCleared() {}
  31. // Called when the operation on clipboard data is confirmed.
  32. virtual void OnOperationConfirmed(bool copy) {}
  33. };
  34. ClipboardHistory();
  35. ClipboardHistory(const ClipboardHistory&) = delete;
  36. ClipboardHistory& operator=(const ClipboardHistory&) = delete;
  37. ~ClipboardHistory() override;
  38. void AddObserver(Observer* observer) const;
  39. void RemoveObserver(Observer* observer) const;
  40. // Returns the list of most recent items. The returned list is sorted by
  41. // recency.
  42. const std::list<ClipboardHistoryItem>& GetItems() const;
  43. // Deletes clipboard history. Does not modify content stored in the clipboard.
  44. void Clear();
  45. // Returns whether the clipboard history of the active account is empty.
  46. bool IsEmpty() const;
  47. // Remove the item specified by `id`. If the target item does not exist,
  48. // do nothing.
  49. void RemoveItemForId(const base::UnguessableToken& id);
  50. // ui::ClipboardObserver:
  51. void OnClipboardDataChanged() override;
  52. void OnClipboardDataRead() override;
  53. base::WeakPtr<ClipboardHistory> GetWeakPtr();
  54. private:
  55. // Friended to allow ScopedClipboardHistoryPauseImpl to `Pause()` and
  56. // `Resume()`.
  57. friend class ScopedClipboardHistoryPauseImpl;
  58. // Ensures that the clipboard buffer contains the same data as the item at the
  59. // top of clipboard history. If clipboard history is empty, then the clipboard
  60. // is cleared.
  61. void SyncClipboardToClipboardHistory();
  62. // Adds `data` to the top of the history list if `data` is supported by
  63. // clipboard history. If `data` is not supported, this method no-ops. If
  64. // `data` is already in the history list, `data` will be moved to the top of
  65. // the list.
  66. void MaybeCommitData(ui::ClipboardData data, bool is_reorder_on_paste);
  67. // When `Pause()` is called, clipboard accesses will modify clipboard history
  68. // according to `pause_behavior` until `Resume()` is called with that pause's
  69. // `pause_id`. If `Pause()` is called while another pause is active, the
  70. // newest pause's behavior will be respected. When the newest pause ends, the
  71. // next newest pause's behavior will be restored.
  72. const base::Token& Pause(ClipboardHistoryUtil::PauseBehavior pause_behavior);
  73. void Resume(const base::Token& pause_id);
  74. struct PauseInfo {
  75. base::Token pause_id;
  76. ClipboardHistoryUtil::PauseBehavior pause_behavior;
  77. };
  78. // Keeps track of consecutive clipboard operations and records metrics.
  79. void OnClipboardOperation(bool copy);
  80. // Active clipboard history pauses, stored in LIFO order so that the newest
  81. // pause dictates behavior. Rather than a stack, we use a deque where the
  82. // newest pause is added to and removed from the front. Not using a stack
  83. // allows us to find and remove the correct pause in cases where pauses are
  84. // not destroyed in LIFO order, and adding to the front of the deque rather
  85. // than the back allows us to iterate forward when searching for the correct
  86. // pause, simplifying removal logic.
  87. std::deque<PauseInfo> pauses_;
  88. // The number of consecutive copies, reset after a paste.
  89. int consecutive_copies_ = 0;
  90. // The number of consecutive pastes, reset after a copy.
  91. int consecutive_pastes_ = 0;
  92. // The history of data copied to the Clipboard. Items of the list are sorted
  93. // by recency.
  94. std::list<ClipboardHistoryItem> history_list_;
  95. // Mutable to allow adding/removing from |observers_| through a const
  96. // ClipboardHistory.
  97. mutable base::ObserverList<Observer> observers_;
  98. // Factory to create WeakPtrs used to debounce calls to `CommitData()`.
  99. base::WeakPtrFactory<ClipboardHistory> commit_data_weak_factory_{this};
  100. // Factory to create WeakPtrs used to debounce calls to
  101. // `OnClipboardOperation()`.
  102. base::WeakPtrFactory<ClipboardHistory> clipboard_histogram_weak_factory_{
  103. this};
  104. // Factory to create WeakPtrs for ClipboardHistory.
  105. base::WeakPtrFactory<ClipboardHistory> weak_factory_{this};
  106. };
  107. } // namespace ash
  108. #endif // ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_