clipboard_history_controller_impl.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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_CONTROLLER_IMPL_H_
  5. #define ASH_CLIPBOARD_CLIPBOARD_HISTORY_CONTROLLER_IMPL_H_
  6. #include <map>
  7. #include <memory>
  8. #include <set>
  9. #include <vector>
  10. #include "ash/ash_export.h"
  11. #include "ash/clipboard/clipboard_history.h"
  12. #include "ash/clipboard/clipboard_history_item.h"
  13. #include "ash/clipboard/clipboard_history_resource_manager.h"
  14. #include "ash/public/cpp/clipboard_history_controller.h"
  15. #include "base/callback.h"
  16. #include "base/callback_forward.h"
  17. #include "base/memory/weak_ptr.h"
  18. #include "base/observer_list.h"
  19. #include "base/one_shot_event.h"
  20. #include "base/time/time.h"
  21. #include "base/timer/timer.h"
  22. #include "base/unguessable_token.h"
  23. #include "base/values.h"
  24. #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
  25. namespace aura {
  26. class Window;
  27. } // namespace aura
  28. namespace gfx {
  29. class Rect;
  30. } // namespace gfx
  31. namespace ash {
  32. class ClipboardHistoryMenuModelAdapter;
  33. class ClipboardHistoryResourceManager;
  34. class ClipboardNudgeController;
  35. class ScopedClipboardHistoryPause;
  36. // Shows a menu with the last few things saved in the clipboard when the
  37. // keyboard shortcut is pressed.
  38. class ASH_EXPORT ClipboardHistoryControllerImpl
  39. : public ClipboardHistoryController,
  40. public ClipboardHistory::Observer,
  41. public ClipboardHistoryResourceManager::Observer {
  42. public:
  43. // Source and plain vs. rich text info for each paste. These values are used
  44. // in the Ash.ClipboardHistory.PasteType histogram and therefore cannot be
  45. // reordered. New types may be appended to the end of this enumeration.
  46. enum class ClipboardHistoryPasteType {
  47. kPlainTextAccelerator = 0, // Plain text paste triggered by accelerator
  48. kRichTextAccelerator = 1, // Rich text paste triggered by accelerator
  49. kPlainTextKeystroke = 2, // Plain text paste triggered by keystroke
  50. kRichTextKeystroke = 3, // Rich text paste triggered by keystroke
  51. kPlainTextMouse = 4, // Plain text paste triggered by mouse click
  52. kRichTextMouse = 5, // Rich text paste triggered by mouse click
  53. kPlainTextTouch = 6, // Plain text paste triggered by gesture tap
  54. kRichTextTouch = 7, // Rich text paste triggered by gesture tap
  55. kPlainTextVirtualKeyboard = 8, // Plain text paste triggered by VK request
  56. kRichTextVirtualKeyboard = 9, // Rich text paste triggered by VK request
  57. kMaxValue = 9
  58. };
  59. ClipboardHistoryControllerImpl();
  60. ClipboardHistoryControllerImpl(const ClipboardHistoryControllerImpl&) =
  61. delete;
  62. ClipboardHistoryControllerImpl& operator=(
  63. const ClipboardHistoryControllerImpl&) = delete;
  64. ~ClipboardHistoryControllerImpl() override;
  65. // Clean up the child widgets prior to destruction.
  66. void Shutdown();
  67. // Returns if the contextual menu is currently showing.
  68. bool IsMenuShowing() const;
  69. // Shows or hides the clipboard history menu through the keyboard accelerator.
  70. // If the menu was already shown, pastes the selected menu item before hiding.
  71. void ToggleMenuShownByAccelerator();
  72. // ClipboardHistoryController:
  73. void AddObserver(ClipboardHistoryController::Observer* observer) override;
  74. void RemoveObserver(ClipboardHistoryController::Observer* observer) override;
  75. void ShowMenu(const gfx::Rect& anchor_rect,
  76. ui::MenuSourceType source_type,
  77. crosapi::mojom::ClipboardHistoryControllerShowSource
  78. show_source) override;
  79. // Returns bounds for the contextual menu in screen coordinates.
  80. gfx::Rect GetMenuBoundsInScreenForTest() const;
  81. void GetHistoryValuesForTest(GetHistoryValuesCallback callback) const;
  82. // Used to delay the post-encoding step of `GetHistoryValues()` until the
  83. // completion of some work that needs to happen after history values have been
  84. // requested and before the values are returned.
  85. void BlockGetHistoryValuesForTest();
  86. void ResumeGetHistoryValuesForTest();
  87. // Whether the ClipboardHistory has items.
  88. bool IsEmpty() const;
  89. // Returns the history which tracks what is being copied to the clipboard.
  90. const ClipboardHistory* history() const { return clipboard_history_.get(); }
  91. // Returns the resource manager which gets labels and images for items copied
  92. // to the clipboard.
  93. const ClipboardHistoryResourceManager* resource_manager() const {
  94. return resource_manager_.get();
  95. }
  96. ClipboardNudgeController* nudge_controller() const {
  97. return nudge_controller_.get();
  98. }
  99. ClipboardHistoryMenuModelAdapter* context_menu_for_test() {
  100. return context_menu_.get();
  101. }
  102. void set_buffer_restoration_delay_for_test(
  103. absl::optional<base::TimeDelta> delay) {
  104. buffer_restoration_delay_for_test_ = delay;
  105. }
  106. void set_initial_item_selected_callback_for_test(
  107. base::RepeatingClosure new_callback) {
  108. initial_item_selected_callback_for_test_ = new_callback;
  109. }
  110. void set_confirmed_operation_callback_for_test(
  111. base::RepeatingCallback<void(bool)> new_callback) {
  112. confirmed_operation_callback_for_test_ = new_callback;
  113. }
  114. void set_new_bitmap_to_write_while_encoding_for_test(const SkBitmap& bitmap) {
  115. new_bitmap_to_write_while_encoding_for_test_ = bitmap;
  116. }
  117. private:
  118. class AcceleratorTarget;
  119. class MenuDelegate;
  120. // ClipboardHistoryController:
  121. bool CanShowMenu() const override;
  122. bool ShouldShowNewFeatureBadge() const override;
  123. void MarkNewFeatureBadgeShown() override;
  124. void OnScreenshotNotificationCreated() override;
  125. std::unique_ptr<ScopedClipboardHistoryPause> CreateScopedPause() override;
  126. void GetHistoryValues(const std::set<std::string>& item_id_filter,
  127. GetHistoryValuesCallback callback) const override;
  128. std::vector<std::string> GetHistoryItemIds() const override;
  129. bool PasteClipboardItemById(const std::string& item_id) override;
  130. bool DeleteClipboardItemById(const std::string& item_id) override;
  131. // ClipboardHistory::Observer:
  132. void OnClipboardHistoryItemAdded(const ClipboardHistoryItem& item,
  133. bool is_duplicate) override;
  134. void OnClipboardHistoryItemRemoved(const ClipboardHistoryItem& item) override;
  135. void OnClipboardHistoryCleared() override;
  136. void OnOperationConfirmed(bool copy) override;
  137. // ClipboardHistoryResourceManager:
  138. void OnCachedImageModelUpdated(
  139. const std::vector<base::UnguessableToken>& menu_item_ids) override;
  140. // Invoked by `GetHistoryValues()` once all clipboard instances with images
  141. // have been encoded into PNGs. Calls `callback` with the clipboard history
  142. // list, which tracks what has been copied to the clipboard. Only the items
  143. // listed in `item_id_filter` are returned. If `item_id_filter` is empty, then
  144. // all items in the history are returned. If clipboard history is disabled in
  145. // the current mode, `callback` will be called with an empty history list.
  146. void GetHistoryValuesWithEncodedPNGs(
  147. const std::set<std::string>& item_id_filter,
  148. GetHistoryValuesCallback callback,
  149. std::unique_ptr<std::map<base::UnguessableToken, std::vector<uint8_t>>>
  150. encoded_pngs);
  151. // Executes the command specified by `command_id` with the given
  152. // `event_flags`.
  153. void ExecuteCommand(int command_id, int event_flags);
  154. // Paste the clipboard data of the menu item specified by `command_id`.
  155. void PasteMenuItemData(int command_id, ClipboardHistoryPasteType paste_type);
  156. // Pastes the specified clipboard history item, if |intended_window| matches
  157. // the active window. `paste_type` indicates the source of the paste for
  158. // metrics tracking as well as whether plain text should be pasted instead of
  159. // the full, rich-text clipboard data.
  160. void PasteClipboardHistoryItem(aura::Window* intended_window,
  161. ClipboardHistoryItem item,
  162. ClipboardHistoryPasteType paste_type);
  163. // Delete the menu item being selected and its corresponding data. If no item
  164. // is selected, do nothing.
  165. void DeleteSelectedMenuItemIfAny();
  166. // Delete the menu item specified by `command_id` and its corresponding data.
  167. void DeleteItemWithCommandId(int command_id);
  168. // Deletes the specified clipboard history item.
  169. void DeleteClipboardHistoryItem(const ClipboardHistoryItem& item);
  170. // Advances the pseudo focus (backward if `reverse` is true).
  171. void AdvancePseudoFocus(bool reverse);
  172. // Calculates the anchor rect for the ClipboardHistory menu.
  173. gfx::Rect CalculateAnchorRect() const;
  174. // Called when the contextual menu is closed.
  175. void OnMenuClosed();
  176. // Observers notified when clipboard history is shown, used, or updated.
  177. base::ObserverList<ClipboardHistoryController::Observer> observers_;
  178. // The menu being shown.
  179. std::unique_ptr<ClipboardHistoryMenuModelAdapter> context_menu_;
  180. // Used to keep track of what is being copied to the clipboard.
  181. std::unique_ptr<ClipboardHistory> clipboard_history_;
  182. // Manages resources for clipboard history.
  183. std::unique_ptr<ClipboardHistoryResourceManager> resource_manager_;
  184. // Detects the search+v key combo.
  185. std::unique_ptr<AcceleratorTarget> accelerator_target_;
  186. // Handles events on the contextual menu.
  187. std::unique_ptr<MenuDelegate> menu_delegate_;
  188. // Controller that shows contextual nudges for multipaste.
  189. std::unique_ptr<ClipboardNudgeController> nudge_controller_;
  190. // Whether a paste is currently being performed.
  191. bool currently_pasting_ = false;
  192. // Used to post asynchronous tasks when opening or closing the clipboard
  193. // history menu. Note that those tasks have data races between each other.
  194. // The timer can guarantee that at most one task is alive.
  195. base::OneShotTimer menu_task_timer_;
  196. // Indicates the count of pastes which are triggered through the clipboard
  197. // history menu and are waiting for the confirmations from `ClipboardHistory`.
  198. int pastes_to_be_confirmed_ = 0;
  199. // Created when a test requests that `GetHistoryValues()` wait for some work
  200. // to be done before encoding finishes. Reset and recreated if the same test
  201. // makes the request to pause `GetHistoryValues()` again.
  202. std::unique_ptr<base::OneShotEvent> get_history_values_blocker_for_test_;
  203. // The delay interval for restoring the clipboard buffer to its original
  204. // state following a paste event.
  205. absl::optional<base::TimeDelta> buffer_restoration_delay_for_test_;
  206. // Called when the first item view is selected after the clipboard history
  207. // menu opens.
  208. base::RepeatingClosure initial_item_selected_callback_for_test_;
  209. // Called when a copy or paste finishes. Accepts the operation's success as an
  210. // argument.
  211. base::RepeatingCallback<void(bool)> confirmed_operation_callback_for_test_;
  212. // A new bitmap to be written to the clipboard while existing images are being
  213. // encoded during `GetHistoryValues()`, which will force `GetHistoryValues()`
  214. // to re-run in order to encode this new bitmap. This member is marked mutable
  215. // so it can be cleared once it has been written to the clipboard.
  216. mutable SkBitmap new_bitmap_to_write_while_encoding_for_test_;
  217. base::WeakPtrFactory<ClipboardHistoryControllerImpl> weak_ptr_factory_{this};
  218. };
  219. } // namespace ash
  220. #endif // ASH_CLIPBOARD_CLIPBOARD_HISTORY_CONTROLLER_IMPL_H_