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 
5 #ifndef ASH_CLIPBOARD_CLIPBOARD_NUDGE_CONTROLLER_H_
6 #define ASH_CLIPBOARD_CLIPBOARD_NUDGE_CONTROLLER_H_
7 
8 #include "ash/ash_export.h"
9 #include "ash/clipboard/clipboard_history.h"
10 #include "ash/clipboard/clipboard_history_controller_impl.h"
11 #include "ash/public/cpp/session/session_observer.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/time/clock.h"
14 #include "base/timer/timer.h"
15 #include "ui/base/clipboard/clipboard_observer.h"
16 
17 class PrefService;
18 class PrefRegistrySimple;
19 class ClipboardHistoryItem;
20 
21 namespace ash {
22 class ClipboardNudge;
23 
24 // The clipboard contextual nudge will be shown after 4 user actions that must
25 // happen in sequence. The user must perform copy, paste, copy and paste in
26 // sequence to activate the nudge.
27 enum class ClipboardState {
28   kInit = 0,
29   kFirstCopy = 1,
30   kFirstPaste = 2,
31   kSecondCopy = 3,
32   kShouldShowNudge = 4,
33 };
34 
35 class ASH_EXPORT ClipboardNudgeController
36     : public ClipboardHistory::Observer,
37       public ui::ClipboardObserver,
38       public SessionObserver,
39       public ClipboardHistoryControllerImpl::Observer {
40  public:
41   ClipboardNudgeController(
42       ClipboardHistory* clipboard_history,
43       ClipboardHistoryControllerImpl* clipboard_history_controller);
44   ClipboardNudgeController(const ClipboardNudgeController&) = delete;
45   ClipboardNudgeController& operator=(const ClipboardNudgeController&) = delete;
46   ~ClipboardNudgeController() override;
47 
48   // Registers profile prefs.
49   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
50 
51   // ui::ClipboardHistory::Observer:
52   void OnClipboardHistoryItemAdded(const ClipboardHistoryItem& item) override;
53 
54   // ui::ClipboardObserver:
55   void OnClipboardDataRead() override;
56 
57   // SessionObserver:
58   void OnActiveUserPrefServiceChanged(PrefService* prefs) override;
59 
60   // Resets nudge state and show nudge timer.
61   void HandleNudgeShown();
62 
63   // ClipboardHistoryControllerImpl:
64   void OnClipboardHistoryMenuShown() override;
65   void OnClipboardHistoryPasted() override;
66 
67   // Test methods for overriding and resetting the clock used by GetTime.
68   void OverrideClockForTesting(base::Clock* test_clock);
69   void ClearClockOverrideForTesting();
70 
71   const ClipboardState& GetClipboardStateForTesting();
GetClipboardNudgeForTesting()72   ClipboardNudge* GetClipboardNudgeForTesting() { return nudge_.get(); }
73 
74  private:
75   // Gets the number of times the nudge has been shown.
76   int GetShownCount(PrefService* prefs);
77   // Gets the last time the nudge was shown.
78   base::Time GetLastShownTime(PrefService* prefs);
79   // Checks whether another nudge can be shown.
80   bool ShouldShowNudge(PrefService* prefs);
81   // Gets the current time. Can be overridden for testing.
82   base::Time GetTime();
83 
84   // Shows the nudge widget.
85   void ShowNudge();
86 
87   // Hides the nudge widget.
88   void HideNudge();
89 
90   // Begins the animation for fading in or fading out the clipboard nudge.
91   void StartFadeAnimation(bool show);
92 
93   // Time the nudge was last shown.
94   base::Time last_shown_time_;
95 
96   // Owned by ClipboardHistoryController.
97   const ClipboardHistory* clipboard_history_;
98 
99   // Owned by ash/Shell.
100   const ClipboardHistoryControllerImpl* const clipboard_history_controller_;
101 
102   // Current clipboard state.
103   ClipboardState clipboard_state_ = ClipboardState::kInit;
104   // The timestamp of the most recent paste.
105   base::Time last_paste_timestamp_;
106   // Clock that can be overridden for testing.
107   base::Clock* g_clock_override = nullptr;
108 
109   // Contextual nudge which shows a view to inform the user on multipaste usage.
110   std::unique_ptr<ClipboardNudge> nudge_;
111 
112   // Timer to hide the clipboard nudge.
113   base::OneShotTimer hide_nudge_timer_;
114 
115   base::WeakPtrFactory<ClipboardNudgeController> weak_ptr_factory_{this};
116 };
117 
118 }  // namespace ash
119 
120 #endif  // ASH_CLIPBOARD_CLIPBOARD_NUDGE_CONTROLLER_H_
121