// Copyright 2020 The Chromium Authors. All rights reserved. // 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 #include #include "ash/ash_export.h" #include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_util.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; // 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. 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& GetItems() const; // Deletes clipboard history. Does not modify content stored in the clipboard. 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 GetWeakPtr(); private: // Friended to allow ScopedClipboardHistoryPauseImpl to `Pause()` and // `Resume()`. 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(ClipboardHistoryUtil::PauseBehavior pause_behavior); void Resume(const base::Token& pause_id); struct PauseInfo { base::Token pause_id; ClipboardHistoryUtil::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 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 history_list_; // Mutable to allow adding/removing from |observers_| through a const // ClipboardHistory. mutable base::ObserverList observers_; // Factory to create WeakPtrs used to debounce calls to `CommitData()`. base::WeakPtrFactory commit_data_weak_factory_{this}; // Factory to create WeakPtrs used to debounce calls to // `OnClipboardOperation()`. base::WeakPtrFactory clipboard_histogram_weak_factory_{ this}; // Factory to create WeakPtrs for ClipboardHistory. base::WeakPtrFactory weak_factory_{this}; }; } // namespace ash #endif // ASH_CLIPBOARD_CLIPBOARD_HISTORY_H_