clipboard_nudge_controller_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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. #include "ash/clipboard/clipboard_nudge_controller.h"
  5. #include "ash/clipboard/clipboard_history.h"
  6. #include "ash/clipboard/clipboard_history_controller_impl.h"
  7. #include "ash/clipboard/clipboard_nudge.h"
  8. #include "ash/clipboard/clipboard_nudge_constants.h"
  9. #include "ash/constants/ash_features.h"
  10. #include "ash/session/session_controller_impl.h"
  11. #include "ash/shell.h"
  12. #include "ash/test/ash_test_base.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/test/metrics/histogram_tester.h"
  15. #include "base/test/scoped_feature_list.h"
  16. #include "base/test/simple_test_clock.h"
  17. #include "chromeos/crosapi/mojom/clipboard_history.mojom.h"
  18. #include "ui/base/clipboard/clipboard_data.h"
  19. #include "ui/base/clipboard/clipboard_non_backed.h"
  20. #include "ui/compositor/layer.h"
  21. #include "ui/compositor/layer_animator.h"
  22. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  23. #include "ui/views/widget/widget_observer.h"
  24. namespace ash {
  25. class ClipboardNudgeControllerTest : public AshTestBase {
  26. public:
  27. ClipboardNudgeControllerTest() = default;
  28. ClipboardNudgeControllerTest(const ClipboardNudgeControllerTest&) = delete;
  29. ClipboardNudgeControllerTest& operator=(const ClipboardNudgeControllerTest&) =
  30. delete;
  31. ~ClipboardNudgeControllerTest() override = default;
  32. base::SimpleTestClock* clock() { return &test_clock_; }
  33. // AshTestBase:
  34. void SetUp() override {
  35. scoped_feature_list_.InitAndEnableFeature(
  36. chromeos::features::kClipboardHistoryContextMenuNudge);
  37. AshTestBase::SetUp();
  38. nudge_controller_ =
  39. Shell::Get()->clipboard_history_controller()->nudge_controller();
  40. nudge_controller_->OverrideClockForTesting(&test_clock_);
  41. test_clock_.Advance(base::Seconds(360));
  42. }
  43. void TearDown() override {
  44. nudge_controller_->ClearClockOverrideForTesting();
  45. AshTestBase::TearDown();
  46. }
  47. // Owned by ClipboardHistoryController.
  48. ClipboardNudgeController* nudge_controller_;
  49. void ShowNudgeForType(ClipboardNudgeType nudge_type) {
  50. switch (nudge_type) {
  51. case ClipboardNudgeType::kOnboardingNudge:
  52. case ClipboardNudgeType::kZeroStateNudge:
  53. nudge_controller_->ShowNudge(nudge_type);
  54. return;
  55. case ClipboardNudgeType::kNewFeatureBadge:
  56. nudge_controller_->MarkNewFeatureBadgeShown();
  57. return;
  58. case ClipboardNudgeType::kScreenshotNotificationNudge:
  59. nudge_controller_->MarkScreenshotNotificationShown();
  60. return;
  61. }
  62. }
  63. base::HistogramTester& histograms() { return histograms_; }
  64. private:
  65. base::test::ScopedFeatureList scoped_feature_list_;
  66. base::SimpleTestClock test_clock_;
  67. // Histogram value verifier.
  68. base::HistogramTester histograms_;
  69. };
  70. // Checks that clipboard state advances after the nudge controller is fed the
  71. // right event type.
  72. TEST_F(ClipboardNudgeControllerTest, ShouldShowNudgeAfterCorrectSequence) {
  73. EXPECT_EQ(ClipboardState::kInit,
  74. nudge_controller_->GetClipboardStateForTesting());
  75. // Checks that the first copy advances state as expected.
  76. nudge_controller_->OnClipboardHistoryItemAdded(
  77. ClipboardHistoryItem(ui::ClipboardData()));
  78. EXPECT_EQ(ClipboardState::kFirstCopy,
  79. nudge_controller_->GetClipboardStateForTesting());
  80. // Checks that the first paste advances state as expected.
  81. nudge_controller_->OnClipboardDataRead();
  82. EXPECT_EQ(ClipboardState::kFirstPaste,
  83. nudge_controller_->GetClipboardStateForTesting());
  84. // Checks that the second copy advances state as expected.
  85. nudge_controller_->OnClipboardHistoryItemAdded(
  86. ClipboardHistoryItem(ui::ClipboardData()));
  87. EXPECT_EQ(ClipboardState::kSecondCopy,
  88. nudge_controller_->GetClipboardStateForTesting());
  89. // Check that clipbaord nudge has not yet been created.
  90. EXPECT_FALSE(nudge_controller_->GetSystemNudgeForTesting());
  91. // Checks that the second paste resets state as expected.
  92. nudge_controller_->OnClipboardDataRead();
  93. EXPECT_EQ(ClipboardState::kInit,
  94. nudge_controller_->GetClipboardStateForTesting());
  95. // Check that clipbaord nudge has been created.
  96. EXPECT_TRUE(nudge_controller_->GetSystemNudgeForTesting());
  97. }
  98. // Checks that the clipboard state does not advace if too much time passes
  99. // during the copy paste sequence.
  100. TEST_F(ClipboardNudgeControllerTest, NudgeTimeOut) {
  101. // Perform copy -> paste -> copy sequence.
  102. nudge_controller_->OnClipboardHistoryItemAdded(
  103. ClipboardHistoryItem(ui::ClipboardData()));
  104. nudge_controller_->OnClipboardDataRead();
  105. nudge_controller_->OnClipboardHistoryItemAdded(
  106. ClipboardHistoryItem(ui::ClipboardData()));
  107. // Advance time to cause the nudge timer to time out.
  108. clock()->Advance(kMaxTimeBetweenPaste);
  109. nudge_controller_->OnClipboardDataRead();
  110. // Paste event should reset clipboard state to |kFirstPaste| instead of to
  111. // |kShouldShowNudge|.
  112. EXPECT_NE(ClipboardState::kShouldShowNudge,
  113. nudge_controller_->GetClipboardStateForTesting());
  114. EXPECT_EQ(ClipboardState::kFirstPaste,
  115. nudge_controller_->GetClipboardStateForTesting());
  116. }
  117. // Checks that multiple pastes refreshes the |kMaxTimeBetweenPaste| timer that
  118. // determines whether too much time has passed to show the nudge.
  119. TEST_F(ClipboardNudgeControllerTest, NudgeDoesNotTimeOutWithSparsePastes) {
  120. nudge_controller_->OnClipboardHistoryItemAdded(
  121. ClipboardHistoryItem(ui::ClipboardData()));
  122. nudge_controller_->OnClipboardDataRead();
  123. EXPECT_EQ(ClipboardState::kFirstPaste,
  124. nudge_controller_->GetClipboardStateForTesting());
  125. // Perform 5 pastes over 2.5*|kMaxTimeBetweenPaste|.
  126. for (int paste_cycle = 0; paste_cycle < 5; paste_cycle++) {
  127. SCOPED_TRACE("paste cycle " + base::NumberToString(paste_cycle));
  128. clock()->Advance(kMaxTimeBetweenPaste / 2);
  129. nudge_controller_->OnClipboardDataRead();
  130. EXPECT_EQ(ClipboardState::kFirstPaste,
  131. nudge_controller_->GetClipboardStateForTesting());
  132. }
  133. // Check that clipbaord nudge has not yet been created.
  134. EXPECT_FALSE(nudge_controller_->GetSystemNudgeForTesting());
  135. // Check that HandleClipboardChanged() will advance nudge_controller's
  136. // ClipboardState.
  137. nudge_controller_->OnClipboardHistoryItemAdded(
  138. ClipboardHistoryItem(ui::ClipboardData()));
  139. EXPECT_EQ(ClipboardState::kSecondCopy,
  140. nudge_controller_->GetClipboardStateForTesting());
  141. nudge_controller_->OnClipboardDataRead();
  142. EXPECT_EQ(ClipboardState::kInit,
  143. nudge_controller_->GetClipboardStateForTesting());
  144. // Check that clipbaord nudge has been created.
  145. EXPECT_TRUE(nudge_controller_->GetSystemNudgeForTesting());
  146. }
  147. // Checks that consecutive copy events does not advance the clipboard state.
  148. TEST_F(ClipboardNudgeControllerTest, RepeatedCopyDoesNotAdvanceState) {
  149. nudge_controller_->OnClipboardHistoryItemAdded(
  150. ClipboardHistoryItem(ui::ClipboardData()));
  151. EXPECT_EQ(ClipboardState::kFirstCopy,
  152. nudge_controller_->GetClipboardStateForTesting());
  153. nudge_controller_->OnClipboardHistoryItemAdded(
  154. ClipboardHistoryItem(ui::ClipboardData()));
  155. EXPECT_EQ(ClipboardState::kFirstCopy,
  156. nudge_controller_->GetClipboardStateForTesting());
  157. }
  158. // Checks that consecutive paste events does not advance the clipboard state.
  159. TEST_F(ClipboardNudgeControllerTest, RepeatedPasteDoesNotAdvanceState) {
  160. nudge_controller_->OnClipboardHistoryItemAdded(
  161. ClipboardHistoryItem(ui::ClipboardData()));
  162. EXPECT_EQ(ClipboardState::kFirstCopy,
  163. nudge_controller_->GetClipboardStateForTesting());
  164. nudge_controller_->OnClipboardDataRead();
  165. EXPECT_EQ(ClipboardState::kFirstPaste,
  166. nudge_controller_->GetClipboardStateForTesting());
  167. nudge_controller_->OnClipboardDataRead();
  168. EXPECT_EQ(ClipboardState::kFirstPaste,
  169. nudge_controller_->GetClipboardStateForTesting());
  170. }
  171. // Verifies that administrative events does not advance clipboard state.
  172. TEST_F(ClipboardNudgeControllerTest, AdminWriteDoesNotAdvanceState) {
  173. nudge_controller_->OnClipboardHistoryItemAdded(
  174. ClipboardHistoryItem(ui::ClipboardData()));
  175. nudge_controller_->OnClipboardDataRead();
  176. EXPECT_EQ(ClipboardState::kFirstPaste,
  177. nudge_controller_->GetClipboardStateForTesting());
  178. auto data = std::make_unique<ui::ClipboardData>();
  179. data->set_text("test");
  180. // Write the data to the clipboard, clipboard state should not advance.
  181. ui::ClipboardNonBacked::GetForCurrentThread()->WriteClipboardData(
  182. std::move(data));
  183. EXPECT_EQ(ClipboardState::kFirstPaste,
  184. nudge_controller_->GetClipboardStateForTesting());
  185. }
  186. // Verifies that the context menu new feature badge for the clipboard option
  187. // only shows |kContextMenuBadgeShowLimit| times.
  188. TEST_F(ClipboardNudgeControllerTest, ShowNewFeatureNudge) {
  189. ASSERT_TRUE(nudge_controller_->ShouldShowNewFeatureBadge());
  190. // Mark the badge shown |kContextMenuBadgeShowLimit| - 1 times.
  191. // Should expect to keep showing the badge
  192. for (int i = 0; i < kContextMenuBadgeShowLimit - 1; ++i) {
  193. nudge_controller_->MarkNewFeatureBadgeShown();
  194. EXPECT_TRUE(nudge_controller_->ShouldShowNewFeatureBadge());
  195. }
  196. // Marking the badge as shown |kContextMenuBadgeShowLimit| times should not
  197. // expect to show the badge the next time.
  198. nudge_controller_->MarkNewFeatureBadgeShown();
  199. EXPECT_FALSE(nudge_controller_->ShouldShowNewFeatureBadge());
  200. }
  201. // Verifies that controller cleans up and closes an old nudge before displaying
  202. // another one.
  203. TEST_F(ClipboardNudgeControllerTest, ShowZeroStateNudgeAfterOngoingNudge) {
  204. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  205. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  206. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  207. ClipboardNudge* nudge = static_cast<ClipboardNudge*>(
  208. nudge_controller_->GetSystemNudgeForTesting());
  209. views::Widget* nudge_widget = nudge->widget();
  210. ASSERT_TRUE(nudge_widget->GetLayer()->GetAnimator()->is_animating());
  211. EXPECT_FALSE(nudge_widget->IsClosed());
  212. EXPECT_EQ(ClipboardNudgeType::kOnboardingNudge, nudge->nudge_type());
  213. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  214. // Verify the old nudge widget was closed.
  215. EXPECT_TRUE(nudge_widget->IsClosed());
  216. nudge = static_cast<ClipboardNudge*>(
  217. nudge_controller_->GetSystemNudgeForTesting());
  218. EXPECT_FALSE(nudge->widget()->IsClosed());
  219. EXPECT_EQ(ClipboardNudgeType::kZeroStateNudge, nudge->nudge_type());
  220. }
  221. // Verifies that the nudge cleans up properly during shutdown while it is
  222. // animating to hide.
  223. TEST_F(ClipboardNudgeControllerTest, NudgeClosingDuringShutdown) {
  224. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  225. ClipboardNudge* nudge = static_cast<ClipboardNudge*>(
  226. nudge_controller_->GetSystemNudgeForTesting());
  227. views::Widget* nudge_widget = nudge->widget();
  228. EXPECT_FALSE(nudge_widget->IsClosed());
  229. EXPECT_EQ(ClipboardNudgeType::kOnboardingNudge, nudge->nudge_type());
  230. // Slow down the duration of the nudge
  231. ui::ScopedAnimationDurationScaleMode test_duration_mode(
  232. ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
  233. nudge_controller_->FireHideNudgeTimerForTesting();
  234. ASSERT_TRUE(nudge_widget->GetLayer()->GetAnimator()->is_animating());
  235. }
  236. // Assert that all nudge metric related histograms start at 0.
  237. TEST_F(ClipboardNudgeControllerTest, NudgeMetrics_StartAtZero) {
  238. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 0);
  239. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 0);
  240. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 0);
  241. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 0);
  242. histograms().ExpectTotalCount(kNewBadge_OpenTime, 0);
  243. histograms().ExpectTotalCount(kNewBadge_PasteTime, 0);
  244. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 0);
  245. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 0);
  246. }
  247. // Test that opening the clipboard history after showing the nudges logs only
  248. // the metrics for the open time histograms. For this test, we only verify the
  249. // number of emits, but not the timing mechanism.
  250. TEST_F(ClipboardNudgeControllerTest, ShowMenuAfterNudges_LogsOpenNudgeMetrics) {
  251. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  252. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  253. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  254. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  255. nudge_controller_->OnClipboardHistoryMenuShown(
  256. crosapi::mojom::ClipboardHistoryControllerShowSource::
  257. kRenderViewContextMenu);
  258. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 1);
  259. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 1);
  260. histograms().ExpectTotalCount(kNewBadge_OpenTime, 1);
  261. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 1);
  262. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 0);
  263. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 0);
  264. histograms().ExpectTotalCount(kNewBadge_PasteTime, 0);
  265. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 0);
  266. }
  267. // Test that pasting something from the clipboard history after showing the
  268. // nudges only the metrics for the paste time histograms. For this test, we only
  269. // verify the number of emits, but not the timing mechanism.
  270. TEST_F(ClipboardNudgeControllerTest, PasteAfterNudges_LogsPasteNudgeMetrics) {
  271. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  272. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  273. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  274. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  275. nudge_controller_->OnClipboardHistoryMenuShown(
  276. crosapi::mojom::ClipboardHistoryControllerShowSource::
  277. kRenderViewContextMenu);
  278. nudge_controller_->OnClipboardHistoryPasted();
  279. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 1);
  280. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 1);
  281. histograms().ExpectTotalCount(kNewBadge_OpenTime, 1);
  282. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 1);
  283. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 1);
  284. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 1);
  285. histograms().ExpectTotalCount(kNewBadge_PasteTime, 1);
  286. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 1);
  287. }
  288. // Test that the onboarding nudge being shown only logs the metrics for the
  289. // onboarding nudge histograms,
  290. TEST_F(ClipboardNudgeControllerTest, OnboardingNudge_DoesNotLogOtherMetrics) {
  291. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  292. nudge_controller_->OnClipboardHistoryMenuShown(
  293. crosapi::mojom::ClipboardHistoryControllerShowSource::
  294. kRenderViewContextMenu);
  295. nudge_controller_->OnClipboardHistoryPasted();
  296. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 1);
  297. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 0);
  298. histograms().ExpectTotalCount(kNewBadge_OpenTime, 0);
  299. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 0);
  300. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 1);
  301. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 0);
  302. histograms().ExpectTotalCount(kNewBadge_PasteTime, 0);
  303. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 0);
  304. }
  305. // Test that the zero state nudge being shown only logs the metrics for the zero
  306. // state nudge histograms,
  307. TEST_F(ClipboardNudgeControllerTest, ZeroStateNudge_DoesNotLogOtherMetrics) {
  308. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  309. nudge_controller_->OnClipboardHistoryMenuShown(
  310. crosapi::mojom::ClipboardHistoryControllerShowSource::
  311. kRenderViewContextMenu);
  312. nudge_controller_->OnClipboardHistoryPasted();
  313. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 0);
  314. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 1);
  315. histograms().ExpectTotalCount(kNewBadge_OpenTime, 0);
  316. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 0);
  317. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 0);
  318. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 1);
  319. histograms().ExpectTotalCount(kNewBadge_PasteTime, 0);
  320. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 0);
  321. }
  322. // Test that the new feature badge being shown only logs the metrics for the new
  323. // feature badge histograms,
  324. TEST_F(ClipboardNudgeControllerTest, NewFeatureBadge_DoesNotLogOtherMetrics) {
  325. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  326. nudge_controller_->OnClipboardHistoryMenuShown(
  327. crosapi::mojom::ClipboardHistoryControllerShowSource::
  328. kRenderViewContextMenu);
  329. nudge_controller_->OnClipboardHistoryPasted();
  330. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 0);
  331. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 0);
  332. histograms().ExpectTotalCount(kNewBadge_OpenTime, 1);
  333. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 0);
  334. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 0);
  335. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 0);
  336. histograms().ExpectTotalCount(kNewBadge_PasteTime, 1);
  337. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 0);
  338. }
  339. // Test that the screenshot notification nudge being shown only logs the metrics
  340. // for the screenshot notification nudge histograms,
  341. TEST_F(ClipboardNudgeControllerTest,
  342. ScreenshotNotification_DoesNotLogOtherMetrics) {
  343. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  344. nudge_controller_->OnClipboardHistoryMenuShown(
  345. crosapi::mojom::ClipboardHistoryControllerShowSource::
  346. kRenderViewContextMenu);
  347. nudge_controller_->OnClipboardHistoryPasted();
  348. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 0);
  349. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 0);
  350. histograms().ExpectTotalCount(kNewBadge_OpenTime, 0);
  351. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 1);
  352. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 0);
  353. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 0);
  354. histograms().ExpectTotalCount(kNewBadge_PasteTime, 0);
  355. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 1);
  356. }
  357. // Test that nudge metrics will not log multiple times if the nudges are not
  358. // shown before.
  359. TEST_F(ClipboardNudgeControllerTest, SecondTimeAction_DoesNotLogNudgeMetrics) {
  360. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  361. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  362. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  363. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  364. nudge_controller_->OnClipboardHistoryMenuShown(
  365. crosapi::mojom::ClipboardHistoryControllerShowSource::
  366. kRenderViewContextMenu);
  367. nudge_controller_->OnClipboardHistoryPasted();
  368. nudge_controller_->OnClipboardHistoryMenuShown(
  369. crosapi::mojom::ClipboardHistoryControllerShowSource::
  370. kRenderViewContextMenu);
  371. nudge_controller_->OnClipboardHistoryPasted();
  372. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 1);
  373. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 1);
  374. histograms().ExpectTotalCount(kNewBadge_OpenTime, 1);
  375. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 1);
  376. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 1);
  377. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 1);
  378. histograms().ExpectTotalCount(kNewBadge_PasteTime, 1);
  379. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 1);
  380. }
  381. // Test that nudge metrics can log more times as the nudges are shown before.
  382. TEST_F(ClipboardNudgeControllerTest, ShowNudgeTwice_LogsMetricsTwoTimes) {
  383. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  384. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  385. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  386. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  387. nudge_controller_->OnClipboardHistoryMenuShown(
  388. crosapi::mojom::ClipboardHistoryControllerShowSource::
  389. kRenderViewContextMenu);
  390. nudge_controller_->OnClipboardHistoryPasted();
  391. ShowNudgeForType(ClipboardNudgeType::kOnboardingNudge);
  392. ShowNudgeForType(ClipboardNudgeType::kZeroStateNudge);
  393. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  394. ShowNudgeForType(ClipboardNudgeType::kScreenshotNotificationNudge);
  395. nudge_controller_->OnClipboardHistoryMenuShown(
  396. crosapi::mojom::ClipboardHistoryControllerShowSource::
  397. kRenderViewContextMenu);
  398. nudge_controller_->OnClipboardHistoryPasted();
  399. histograms().ExpectTotalCount(kOnboardingNudge_OpenTime, 2);
  400. histograms().ExpectTotalCount(kZeroStateNudge_OpenTime, 2);
  401. histograms().ExpectTotalCount(kNewBadge_OpenTime, 2);
  402. histograms().ExpectTotalCount(kScreenshotNotification_OpenTime, 2);
  403. histograms().ExpectTotalCount(kOnboardingNudge_PasteTime, 2);
  404. histograms().ExpectTotalCount(kZeroStateNudge_PasteTime, 2);
  405. histograms().ExpectTotalCount(kNewBadge_PasteTime, 2);
  406. histograms().ExpectTotalCount(kScreenshotNotification_PasteTime, 2);
  407. }
  408. // For the new feature badge, metrics should only log for opening a menu by a
  409. // context menu source.
  410. TEST_F(ClipboardNudgeControllerTest,
  411. NewFeatureBadgeOpen_LogsByWithContextMenuSource) {
  412. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  413. nudge_controller_->OnClipboardHistoryMenuShown(
  414. crosapi::mojom::ClipboardHistoryControllerShowSource::
  415. kRenderViewContextMenu);
  416. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  417. nudge_controller_->OnClipboardHistoryMenuShown(
  418. crosapi::mojom::ClipboardHistoryControllerShowSource::
  419. kTextfieldContextMenu);
  420. histograms().ExpectTotalCount(kNewBadge_OpenTime, 2);
  421. }
  422. TEST_F(ClipboardNudgeControllerTest,
  423. NewFeatureBadgeOpen_DoesNotLogsWithNotContextMenuSource) {
  424. ShowNudgeForType(ClipboardNudgeType::kNewFeatureBadge);
  425. nudge_controller_->OnClipboardHistoryMenuShown(
  426. crosapi::mojom::ClipboardHistoryControllerShowSource::kAccelerator);
  427. nudge_controller_->OnClipboardHistoryMenuShown(
  428. crosapi::mojom::ClipboardHistoryControllerShowSource::kVirtualKeyboard);
  429. histograms().ExpectTotalCount(kNewBadge_OpenTime, 0);
  430. }
  431. } // namespace ash