palette_tray_unittest.cc 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. // Copyright 2017 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/system/palette/palette_tray.h"
  5. #include <memory>
  6. #include <string>
  7. #include "ash/assistant/assistant_controller_impl.h"
  8. #include "ash/assistant/test/test_assistant_service.h"
  9. #include "ash/assistant/util/assistant_util.h"
  10. #include "ash/constants/ash_pref_names.h"
  11. #include "ash/constants/ash_switches.h"
  12. #include "ash/highlighter/highlighter_controller.h"
  13. #include "ash/highlighter/highlighter_controller_test_api.h"
  14. #include "ash/projector/model/projector_session_impl.h"
  15. #include "ash/projector/projector_controller_impl.h"
  16. #include "ash/public/cpp/assistant/assistant_state.h"
  17. #include "ash/public/cpp/stylus_utils.h"
  18. #include "ash/root_window_controller.h"
  19. #include "ash/session/session_controller_impl.h"
  20. #include "ash/session/test_session_controller_client.h"
  21. #include "ash/shell.h"
  22. #include "ash/system/palette/palette_tray_test_api.h"
  23. #include "ash/system/palette/palette_utils.h"
  24. #include "ash/system/palette/palette_welcome_bubble.h"
  25. #include "ash/system/status_area_widget.h"
  26. #include "ash/system/status_area_widget_test_helper.h"
  27. #include "ash/test/ash_test_base.h"
  28. #include "ash/test_shell_delegate.h"
  29. #include "base/command_line.h"
  30. #include "base/memory/ptr_util.h"
  31. #include "base/run_loop.h"
  32. #include "base/test/scoped_feature_list.h"
  33. #include "base/test/simple_test_tick_clock.h"
  34. #include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h"
  35. #include "chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h"
  36. #include "components/prefs/pref_service.h"
  37. #include "components/session_manager/session_manager_types.h"
  38. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  39. #include "ui/display/test/display_manager_test_api.h"
  40. #include "ui/events/base_event_utils.h"
  41. #include "ui/events/devices/device_data_manager.h"
  42. #include "ui/events/devices/device_data_manager_test_api.h"
  43. #include "ui/events/devices/stylus_state.h"
  44. #include "ui/events/event.h"
  45. #include "ui/events/test/event_generator.h"
  46. namespace ash {
  47. class PaletteTrayTest : public AshTestBase {
  48. public:
  49. PaletteTrayTest() = default;
  50. PaletteTrayTest(const PaletteTrayTest&) = delete;
  51. PaletteTrayTest& operator=(const PaletteTrayTest&) = delete;
  52. ~PaletteTrayTest() override = default;
  53. // Performs a tap on the palette tray button.
  54. void PerformTap() {
  55. ui::GestureEvent tap(0, 0, 0, base::TimeTicks(),
  56. ui::GestureEventDetails(ui::ET_GESTURE_TAP));
  57. palette_tray_->PerformAction(tap);
  58. }
  59. // Fake a stylus ejection.
  60. void EjectStylus() {
  61. test_api_->OnStylusStateChanged(ui::StylusState::REMOVED);
  62. }
  63. // Fake a stylus insertion.
  64. void InsertStylus() {
  65. test_api_->OnStylusStateChanged(ui::StylusState::INSERTED);
  66. }
  67. // AshTestBase:
  68. void SetUp() override {
  69. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  70. switches::kAshEnablePaletteOnAllDisplays);
  71. stylus_utils::SetHasStylusInputForTesting();
  72. AshTestBase::SetUp();
  73. palette_tray_ =
  74. StatusAreaWidgetTestHelper::GetStatusAreaWidget()->palette_tray();
  75. test_api_ = std::make_unique<PaletteTrayTestApi>(palette_tray_);
  76. display::test::DisplayManagerTestApi(display_manager())
  77. .SetFirstDisplayAsInternalDisplay();
  78. }
  79. PrefService* prefs() {
  80. return Shell::Get()->session_controller()->GetPrimaryUserPrefService();
  81. }
  82. protected:
  83. PrefService* active_user_pref_service() {
  84. return Shell::Get()->session_controller()->GetActivePrefService();
  85. }
  86. PaletteTray* palette_tray_ = nullptr; // not owned
  87. std::unique_ptr<PaletteTrayTestApi> test_api_;
  88. };
  89. // Verify the palette tray button exists and but is not visible initially.
  90. TEST_F(PaletteTrayTest, PaletteTrayIsInvisible) {
  91. ASSERT_TRUE(palette_tray_);
  92. EXPECT_FALSE(palette_tray_->GetVisible());
  93. }
  94. // Verify if the has seen stylus pref is not set initially, the palette tray
  95. // should become visible after seeing a stylus event.
  96. TEST_F(PaletteTrayTest, PaletteTrayVisibleAfterStylusSeen) {
  97. ASSERT_FALSE(palette_tray_->GetVisible());
  98. ASSERT_FALSE(local_state()->GetBoolean(prefs::kHasSeenStylus));
  99. // Send a stylus event.
  100. ui::test::EventGenerator* generator = GetEventGenerator();
  101. generator->EnterPenPointerMode();
  102. generator->PressTouch();
  103. generator->ReleaseTouch();
  104. generator->ExitPenPointerMode();
  105. EXPECT_TRUE(palette_tray_->GetVisible());
  106. }
  107. // Verify if the has seen stylus pref is initially set, the palette tray is
  108. // visible.
  109. TEST_F(PaletteTrayTest, StylusSeenPrefInitiallySet) {
  110. ASSERT_FALSE(palette_tray_->GetVisible());
  111. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  112. local_state()->SetBoolean(prefs::kHasSeenStylus, true);
  113. EXPECT_TRUE(palette_tray_->GetVisible());
  114. }
  115. // Verify if the kEnableStylusTools pref was never set the stylus
  116. // should become visible after a stylus event. Even if kHasSeenStylus
  117. // has been previously set.
  118. TEST_F(PaletteTrayTest, PaletteTrayVisibleIfEnableStylusToolsNotSet) {
  119. local_state()->SetBoolean(prefs::kHasSeenStylus, true);
  120. ASSERT_FALSE(palette_tray_->GetVisible());
  121. // Send a stylus event.
  122. ui::test::EventGenerator* generator = GetEventGenerator();
  123. generator->EnterPenPointerMode();
  124. generator->PressTouch();
  125. generator->ReleaseTouch();
  126. generator->ExitPenPointerMode();
  127. EXPECT_TRUE(palette_tray_->GetVisible());
  128. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, false);
  129. EXPECT_FALSE(palette_tray_->GetVisible());
  130. // Send a stylus event.
  131. generator->EnterPenPointerMode();
  132. generator->PressTouch();
  133. generator->ReleaseTouch();
  134. generator->ExitPenPointerMode();
  135. EXPECT_FALSE(palette_tray_->GetVisible());
  136. }
  137. // Verify taps on the palette tray button results in expected behaviour.
  138. TEST_F(PaletteTrayTest, PaletteTrayWorkflow) {
  139. // Verify the palette tray button is not active, and the palette tray bubble
  140. // is not shown initially.
  141. EXPECT_FALSE(palette_tray_->is_active());
  142. EXPECT_FALSE(test_api_->tray_bubble_wrapper());
  143. // Verify that by tapping the palette tray button, the button will become
  144. // active and the palette tray bubble will be open.
  145. PerformTap();
  146. EXPECT_TRUE(palette_tray_->is_active());
  147. EXPECT_TRUE(test_api_->tray_bubble_wrapper());
  148. // Verify that activating a mode tool will close the palette tray bubble, but
  149. // leave the palette tray button active.
  150. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::LASER_POINTER);
  151. EXPECT_TRUE(test_api_->palette_tool_manager()->IsToolActive(
  152. PaletteToolId::LASER_POINTER));
  153. EXPECT_TRUE(palette_tray_->is_active());
  154. EXPECT_FALSE(test_api_->tray_bubble_wrapper());
  155. // Verify that tapping the palette tray while a tool is active will deactivate
  156. // the tool, and the palette tray button will not be active.
  157. PerformTap();
  158. EXPECT_FALSE(palette_tray_->is_active());
  159. EXPECT_FALSE(test_api_->palette_tool_manager()->IsToolActive(
  160. PaletteToolId::LASER_POINTER));
  161. // Verify that activating a action tool will close the palette tray bubble and
  162. // the palette tray button is will not be active.
  163. PerformTap();
  164. ASSERT_TRUE(test_api_->tray_bubble_wrapper());
  165. const auto capture_tool_id = PaletteToolId::ENTER_CAPTURE_MODE;
  166. test_api_->palette_tool_manager()->ActivateTool(capture_tool_id);
  167. EXPECT_FALSE(
  168. test_api_->palette_tool_manager()->IsToolActive(capture_tool_id));
  169. // Wait for the tray bubble widget to close.
  170. base::RunLoop().RunUntilIdle();
  171. EXPECT_FALSE(test_api_->tray_bubble_wrapper());
  172. EXPECT_FALSE(palette_tray_->is_active());
  173. }
  174. // Verify that the palette tray button and bubble are as expected when modes
  175. // that can be deactivated without pressing the palette tray button (such as
  176. // capture region) are deactivated.
  177. TEST_F(PaletteTrayTest, ModeToolDeactivatedAutomatically) {
  178. // Open the palette tray with a tap.
  179. PerformTap();
  180. ASSERT_TRUE(palette_tray_->is_active());
  181. ASSERT_TRUE(test_api_->tray_bubble_wrapper());
  182. // Activate and deactivate the laser pointer tool.
  183. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::LASER_POINTER);
  184. ASSERT_TRUE(test_api_->palette_tool_manager()->IsToolActive(
  185. PaletteToolId::LASER_POINTER));
  186. test_api_->palette_tool_manager()->DeactivateTool(
  187. PaletteToolId::LASER_POINTER);
  188. // Verify the bubble is hidden and the button is inactive after deactivating
  189. // the capture region tool.
  190. EXPECT_FALSE(test_api_->tray_bubble_wrapper());
  191. EXPECT_FALSE(palette_tray_->is_active());
  192. }
  193. TEST_F(PaletteTrayTest, EnableStylusPref) {
  194. local_state()->SetBoolean(prefs::kHasSeenStylus, true);
  195. // kEnableStylusTools is false by default
  196. ASSERT_FALSE(
  197. active_user_pref_service()->GetBoolean(prefs::kEnableStylusTools));
  198. EXPECT_FALSE(palette_tray_->GetVisible());
  199. // Setting the pref again shows the palette tray.
  200. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  201. EXPECT_TRUE(palette_tray_->GetVisible());
  202. // Resetting the pref hides the palette tray.
  203. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, false);
  204. EXPECT_FALSE(palette_tray_->GetVisible());
  205. }
  206. // Verify that the kEnableStylusTools pref is switched to true automatically
  207. // when a stylus is detected for the first time.
  208. TEST_F(PaletteTrayTest, EnableStylusPrefSwitchedOnStylusEvent) {
  209. ASSERT_FALSE(
  210. active_user_pref_service()->GetBoolean(prefs::kEnableStylusTools));
  211. ui::test::EventGenerator* generator = GetEventGenerator();
  212. generator->EnterPenPointerMode();
  213. generator->PressTouch();
  214. generator->ReleaseTouch();
  215. EXPECT_TRUE(
  216. active_user_pref_service()->GetBoolean(prefs::kEnableStylusTools));
  217. }
  218. TEST_F(PaletteTrayTest, WelcomeBubbleVisibility) {
  219. ASSERT_FALSE(active_user_pref_service()->GetBoolean(
  220. prefs::kShownPaletteWelcomeBubble));
  221. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  222. // Verify that the welcome bubble does not shown up after tapping the screen
  223. // with a finger.
  224. ui::test::EventGenerator* generator = GetEventGenerator();
  225. generator->PressTouch();
  226. generator->ReleaseTouch();
  227. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  228. // Verify that the welcome bubble shows up after tapping the screen with a
  229. // stylus for the first time.
  230. generator->EnterPenPointerMode();
  231. generator->PressTouch();
  232. generator->ReleaseTouch();
  233. EXPECT_TRUE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  234. }
  235. // Base class for tests that rely on Assistant enabled.
  236. class PaletteTrayTestWithAssistant : public PaletteTrayTest {
  237. public:
  238. PaletteTrayTestWithAssistant() = default;
  239. PaletteTrayTestWithAssistant(const PaletteTrayTestWithAssistant&) = delete;
  240. PaletteTrayTestWithAssistant& operator=(const PaletteTrayTestWithAssistant&) =
  241. delete;
  242. ~PaletteTrayTestWithAssistant() override = default;
  243. // PaletteTrayTest:
  244. void SetUp() override {
  245. assistant::util::OverrideIsGoogleDeviceForTesting(true);
  246. PaletteTrayTest::SetUp();
  247. // Instantiate EventGenerator now so that its constructor does not overwrite
  248. // the simulated clock that is being installed below.
  249. GetEventGenerator();
  250. // Tests fail if event time is ever 0.
  251. simulated_clock_.Advance(base::Milliseconds(10));
  252. ui::SetEventTickClockForTesting(&simulated_clock_);
  253. highlighter_test_api_ = std::make_unique<HighlighterControllerTestApi>(
  254. Shell::Get()->highlighter_controller());
  255. }
  256. void TearDown() override {
  257. assistant::util::OverrideIsGoogleDeviceForTesting(false);
  258. ui::SetEventTickClockForTesting(nullptr);
  259. // This needs to be called first to reset the controller state before the
  260. // shell instance gets torn down.
  261. highlighter_test_api_.reset();
  262. PaletteTrayTest::TearDown();
  263. }
  264. protected:
  265. bool metalayer_enabled() const {
  266. return test_api_->palette_tool_manager()->IsToolActive(
  267. PaletteToolId::METALAYER);
  268. }
  269. bool highlighter_showing() const {
  270. return highlighter_test_api_->IsShowingHighlighter();
  271. }
  272. AssistantState* assistant_state() const { return AssistantState::Get(); }
  273. void DragAndAssertMetalayer(const std::string& context,
  274. const gfx::Point& origin,
  275. int event_flags,
  276. bool expected,
  277. bool expected_on_press) {
  278. SCOPED_TRACE(context);
  279. ui::test::EventGenerator* generator = GetEventGenerator();
  280. gfx::Point pos = origin;
  281. generator->MoveTouch(pos);
  282. generator->set_flags(event_flags);
  283. generator->PressTouch();
  284. // If this gesture is supposed to enable the tool, it should have done it by
  285. // now.
  286. EXPECT_EQ(expected, metalayer_enabled());
  287. // Unlike the tool, the highlighter might become visible only after the
  288. // first move, hence a separate parameter to check against.
  289. EXPECT_EQ(expected_on_press, highlighter_showing());
  290. pos += gfx::Vector2d(1, 1);
  291. generator->MoveTouch(pos);
  292. // If this gesture is supposed to show the highlighter, it should have done
  293. // it by now.
  294. EXPECT_EQ(expected, highlighter_showing());
  295. EXPECT_EQ(expected, metalayer_enabled());
  296. generator->set_flags(ui::EF_NONE);
  297. pos += gfx::Vector2d(1, 1);
  298. generator->MoveTouch(pos);
  299. EXPECT_EQ(expected, highlighter_showing());
  300. EXPECT_EQ(expected, metalayer_enabled());
  301. generator->ReleaseTouch();
  302. // If the tool is not enabled, the gesture may open a context menu instead.
  303. // Press escape to close the menu.
  304. generator->PressKey(ui::VKEY_ESCAPE, ui::EF_NONE);
  305. }
  306. void WaitDragAndAssertMetalayer(const std::string& context,
  307. const gfx::Point& origin,
  308. int event_flags,
  309. bool expected,
  310. bool expected_on_press) {
  311. const int kStrokeGap = 1000;
  312. simulated_clock_.Advance(base::Milliseconds(kStrokeGap));
  313. DragAndAssertMetalayer(context, origin, event_flags, expected,
  314. expected_on_press);
  315. }
  316. std::unique_ptr<HighlighterControllerTestApi> highlighter_test_api_;
  317. private:
  318. base::SimpleTestTickClock simulated_clock_;
  319. assistant::ScopedAssistantBrowserDelegate delegate_;
  320. };
  321. TEST_F(PaletteTrayTestWithAssistant, MetalayerToolViewCreated) {
  322. EXPECT_TRUE(
  323. test_api_->palette_tool_manager()->HasTool(PaletteToolId::METALAYER));
  324. }
  325. TEST_F(PaletteTrayTestWithAssistant, MetalayerToolActivatesHighlighter) {
  326. ui::ScopedAnimationDurationScaleMode animation_duration_mode(
  327. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  328. assistant_state()->NotifyFeatureAllowed(
  329. assistant::AssistantAllowedState::ALLOWED);
  330. assistant_state()->NotifyStatusChanged(assistant::AssistantStatus::READY);
  331. prefs()->SetBoolean(assistant::prefs::kAssistantEnabled, true);
  332. prefs()->SetBoolean(assistant::prefs::kAssistantContextEnabled, true);
  333. ui::test::EventGenerator* generator = GetEventGenerator();
  334. generator->EnterPenPointerMode();
  335. const gfx::Point origin(1, 1);
  336. const gfx::Vector2d step(1, 1);
  337. EXPECT_FALSE(palette_utils::PaletteContainsPointInScreen(origin + step));
  338. EXPECT_FALSE(
  339. palette_utils::PaletteContainsPointInScreen(origin + step + step));
  340. // Press/drag does not activate the highlighter unless the palette tool is
  341. // activated.
  342. DragAndAssertMetalayer("tool disabled", origin, ui::EF_NONE,
  343. false /* no metalayer */,
  344. false /* no highlighter on press */);
  345. // Activate the palette tool, still no highlighter.
  346. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::METALAYER);
  347. EXPECT_FALSE(highlighter_showing());
  348. // Press/drag over a regular (non-palette) location. This should activate the
  349. // highlighter. Note that a diagonal stroke does not create a valid selection.
  350. highlighter_test_api_->ResetSelection();
  351. DragAndAssertMetalayer("tool enabled", origin, ui::EF_NONE,
  352. true /* metalayer stays enabled after the press */,
  353. true /* highlighter shown on press */);
  354. // When metalayer is entered normally (not via stylus button), a failed
  355. // selection should not exit the mode.
  356. EXPECT_FALSE(highlighter_test_api_->HandleSelectionCalled());
  357. EXPECT_TRUE(metalayer_enabled());
  358. // A successfull selection should exit the metalayer mode.
  359. SCOPED_TRACE("horizontal stroke");
  360. highlighter_test_api_->ResetSelection();
  361. generator->MoveTouch(gfx::Point(100, 100));
  362. generator->PressTouch();
  363. EXPECT_TRUE(metalayer_enabled());
  364. generator->MoveTouch(gfx::Point(300, 100));
  365. generator->ReleaseTouch();
  366. EXPECT_TRUE(highlighter_test_api_->HandleSelectionCalled());
  367. EXPECT_FALSE(metalayer_enabled());
  368. SCOPED_TRACE("drag over palette");
  369. highlighter_test_api_->DestroyPointerView();
  370. // Press/drag over the palette button. This should not activate the
  371. // highlighter, but should disable the palette tool instead.
  372. gfx::Point palette_point = palette_tray_->GetBoundsInScreen().CenterPoint();
  373. EXPECT_TRUE(palette_utils::PaletteContainsPointInScreen(palette_point));
  374. generator->MoveTouch(palette_point);
  375. generator->PressTouch();
  376. EXPECT_FALSE(highlighter_showing());
  377. palette_point += gfx::Vector2d(1, 1);
  378. EXPECT_TRUE(palette_utils::PaletteContainsPointInScreen(palette_point));
  379. generator->MoveTouch(palette_point);
  380. EXPECT_FALSE(highlighter_showing());
  381. generator->ReleaseTouch();
  382. EXPECT_FALSE(metalayer_enabled());
  383. // Disabling metalayer support in the delegate should disable the palette
  384. // tool.
  385. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::METALAYER);
  386. prefs()->SetBoolean(assistant::prefs::kAssistantContextEnabled, false);
  387. EXPECT_FALSE(metalayer_enabled());
  388. // With the metalayer disabled again, press/drag does not activate the
  389. // highlighter.
  390. DragAndAssertMetalayer("tool disabled again", origin, ui::EF_NONE,
  391. false /* no metalayer */,
  392. false /* no highlighter on press */);
  393. }
  394. TEST_F(PaletteTrayTestWithAssistant, StylusBarrelButtonActivatesHighlighter) {
  395. ui::ScopedAnimationDurationScaleMode animation_duration_mode(
  396. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  397. assistant_state()->NotifyStatusChanged(assistant::AssistantStatus::NOT_READY);
  398. prefs()->SetBoolean(assistant::prefs::kAssistantEnabled, false);
  399. prefs()->SetBoolean(assistant::prefs::kAssistantContextEnabled, false);
  400. ui::test::EventGenerator* generator = GetEventGenerator();
  401. generator->EnterPenPointerMode();
  402. const gfx::Point origin(1, 1);
  403. const gfx::Vector2d step(1, 1);
  404. EXPECT_FALSE(palette_utils::PaletteContainsPointInScreen(origin));
  405. EXPECT_FALSE(palette_utils::PaletteContainsPointInScreen(origin + step));
  406. EXPECT_FALSE(
  407. palette_utils::PaletteContainsPointInScreen(origin + step + step));
  408. // Press and drag while holding down the stylus button, no highlighter unless
  409. // the metalayer support is fully enabled and the the framework is ready.
  410. WaitDragAndAssertMetalayer("nothing enabled", origin,
  411. ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */,
  412. false /* no highlighter on press */);
  413. // Enable one of the two user prefs, should not be sufficient.
  414. prefs()->SetBoolean(assistant::prefs::kAssistantContextEnabled, true);
  415. WaitDragAndAssertMetalayer("one pref enabled", origin,
  416. ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */,
  417. false /* no highlighter on press */);
  418. // Enable the other user pref, still not sufficient.
  419. prefs()->SetBoolean(assistant::prefs::kAssistantEnabled, true);
  420. WaitDragAndAssertMetalayer("two prefs enabled", origin,
  421. ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */,
  422. false /* no highlighter on press */);
  423. // Once the service is ready, the button should start working.
  424. assistant_state()->NotifyStatusChanged(assistant::AssistantStatus::READY);
  425. // Press and drag with no button, still no highlighter.
  426. WaitDragAndAssertMetalayer("all enabled, no button ", origin, ui::EF_NONE,
  427. false /* no metalayer */,
  428. false /* no highlighter on press */);
  429. // Press/drag with while holding down the stylus button, but over the palette
  430. // tray. This should activate neither the palette tool nor the highlighter.
  431. gfx::Point palette_point = palette_tray_->GetBoundsInScreen().CenterPoint();
  432. EXPECT_TRUE(palette_utils::PaletteContainsPointInScreen(palette_point));
  433. EXPECT_TRUE(
  434. palette_utils::PaletteContainsPointInScreen(palette_point + step));
  435. EXPECT_TRUE(
  436. palette_utils::PaletteContainsPointInScreen(palette_point + step + step));
  437. WaitDragAndAssertMetalayer("drag over palette", palette_point,
  438. ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */,
  439. false /* no highlighter on press */);
  440. // Perform a regular stroke (no button), followed by a button-down stroke
  441. // without a pause. This should not trigger metalayer.
  442. DragAndAssertMetalayer("writing, no button", origin, ui::EF_NONE,
  443. false /* no metalayer */,
  444. false /* no highlighter on press */);
  445. DragAndAssertMetalayer("writing, with button ", origin,
  446. ui::EF_LEFT_MOUSE_BUTTON, false /* no metalayer */,
  447. false /* no highlighter on press */);
  448. // Wait, then press/drag while holding down the stylus button over a regular
  449. // location. This should activate the palette tool and the highlighter.
  450. WaitDragAndAssertMetalayer("with button", origin, ui::EF_LEFT_MOUSE_BUTTON,
  451. true /* enables metalayer */,
  452. false /* no highlighter on press */);
  453. // Metalayer mode entered via the stylus button should not be sticky.
  454. EXPECT_FALSE(metalayer_enabled());
  455. // Repeat the previous step without a pause, make sure that the palette tool
  456. // is not toggled, and the highlighter is enabled immediately.
  457. DragAndAssertMetalayer("with button, again", origin, ui::EF_LEFT_MOUSE_BUTTON,
  458. true /* enables metalayer */,
  459. true /* highlighter shown on press */);
  460. // Same after a pause.
  461. WaitDragAndAssertMetalayer(
  462. "with button, after a pause", origin, ui::EF_LEFT_MOUSE_BUTTON,
  463. true /* enables metalayer */, true /* highlighter shown on press */);
  464. // The barrel button should not work on the lock screen.
  465. highlighter_test_api_->DestroyPointerView();
  466. GetSessionControllerClient()->LockScreen();
  467. EXPECT_FALSE(test_api_->palette_tool_manager()->IsToolActive(
  468. PaletteToolId::METALAYER));
  469. WaitDragAndAssertMetalayer("screen locked", origin, ui::EF_LEFT_MOUSE_BUTTON,
  470. false /* no metalayer */,
  471. false /* no highlighter on press */);
  472. // Unlock the screen, the barrel button should work again.
  473. GetSessionControllerClient()->UnlockScreen();
  474. WaitDragAndAssertMetalayer(
  475. "screen unlocked", origin, ui::EF_LEFT_MOUSE_BUTTON,
  476. true /* enables metalayer */, false /* no highlighter on press */);
  477. // Disable the metalayer support.
  478. // This should deactivate both the palette tool and the highlighter.
  479. prefs()->SetBoolean(assistant::prefs::kAssistantContextEnabled, false);
  480. EXPECT_FALSE(test_api_->palette_tool_manager()->IsToolActive(
  481. PaletteToolId::METALAYER));
  482. highlighter_test_api_->DestroyPointerView();
  483. EXPECT_FALSE(highlighter_showing());
  484. DragAndAssertMetalayer("disabled", origin, ui::EF_LEFT_MOUSE_BUTTON,
  485. false /* no metalayer */,
  486. false /* no highlighter on press */);
  487. }
  488. // Base class for tests that need to simulate an internal stylus.
  489. class PaletteTrayTestWithInternalStylus : public PaletteTrayTest {
  490. public:
  491. PaletteTrayTestWithInternalStylus() {
  492. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  493. switches::kHasInternalStylus);
  494. }
  495. PaletteTrayTestWithInternalStylus(const PaletteTrayTestWithInternalStylus&) =
  496. delete;
  497. PaletteTrayTestWithInternalStylus& operator=(
  498. const PaletteTrayTestWithInternalStylus&) = delete;
  499. ~PaletteTrayTestWithInternalStylus() override = default;
  500. // PaletteTrayTest:
  501. void SetUp() override {
  502. PaletteTrayTest::SetUp();
  503. test_api_->SetDisplayHasStylus();
  504. }
  505. };
  506. // Verify the palette tray button exists and is visible if the device has an
  507. // internal stylus.
  508. TEST_F(PaletteTrayTestWithInternalStylus, Visible) {
  509. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  510. ASSERT_TRUE(palette_tray_);
  511. EXPECT_TRUE(palette_tray_->GetVisible());
  512. }
  513. // Verify that when entering or exiting the lock screen, the behavior of the
  514. // palette tray button is as expected.
  515. TEST_F(PaletteTrayTestWithInternalStylus, PaletteTrayOnLockScreenBehavior) {
  516. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  517. ASSERT_TRUE(palette_tray_->GetVisible());
  518. PaletteToolManager* manager = test_api_->palette_tool_manager();
  519. manager->ActivateTool(PaletteToolId::LASER_POINTER);
  520. EXPECT_TRUE(manager->IsToolActive(PaletteToolId::LASER_POINTER));
  521. // Verify that when entering the lock screen, the palette tray button is
  522. // hidden, and the tool that was active is no longer active.
  523. GetSessionControllerClient()->LockScreen();
  524. EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER));
  525. EXPECT_FALSE(palette_tray_->GetVisible());
  526. // Verify that when logging back in the tray is visible, but the tool that was
  527. // active before locking the screen is still inactive.
  528. GetSessionControllerClient()->UnlockScreen();
  529. EXPECT_TRUE(palette_tray_->GetVisible());
  530. EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER));
  531. }
  532. // Verify a tool deactivates when the palette bubble is opened while the tool
  533. // is active.
  534. TEST_F(PaletteTrayTestWithInternalStylus, ToolDeactivatesWhenOpeningBubble) {
  535. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  536. ASSERT_TRUE(palette_tray_->GetVisible());
  537. palette_tray_->ShowBubble();
  538. EXPECT_TRUE(test_api_->tray_bubble_wrapper());
  539. PaletteToolManager* manager = test_api_->palette_tool_manager();
  540. manager->ActivateTool(PaletteToolId::LASER_POINTER);
  541. EXPECT_TRUE(manager->IsToolActive(PaletteToolId::LASER_POINTER));
  542. EXPECT_FALSE(test_api_->tray_bubble_wrapper());
  543. palette_tray_->ShowBubble();
  544. EXPECT_TRUE(test_api_->tray_bubble_wrapper());
  545. EXPECT_FALSE(manager->IsToolActive(PaletteToolId::LASER_POINTER));
  546. }
  547. // Verify the palette welcome bubble is shown the first time the stylus is
  548. // removed.
  549. TEST_F(PaletteTrayTestWithInternalStylus, WelcomeBubbleShownOnEject) {
  550. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  551. active_user_pref_service()->SetBoolean(prefs::kLaunchPaletteOnEjectEvent,
  552. false);
  553. ASSERT_FALSE(active_user_pref_service()->GetBoolean(
  554. prefs::kShownPaletteWelcomeBubble));
  555. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  556. EjectStylus();
  557. EXPECT_TRUE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  558. }
  559. // Verify if the pref which tracks if the welcome bubble has been shown before
  560. // is true, the welcome bubble is not shown when the stylus is removed.
  561. TEST_F(PaletteTrayTestWithInternalStylus, WelcomeBubbleNotShownIfShownBefore) {
  562. active_user_pref_service()->SetBoolean(prefs::kLaunchPaletteOnEjectEvent,
  563. false);
  564. active_user_pref_service()->SetBoolean(prefs::kShownPaletteWelcomeBubble,
  565. true);
  566. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  567. EjectStylus();
  568. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  569. }
  570. // Verify that the bubble does not get shown if the auto open palette setting is
  571. // true.
  572. TEST_F(PaletteTrayTestWithInternalStylus,
  573. WelcomeBubbleNotShownIfAutoOpenPaletteTrue) {
  574. ASSERT_TRUE(active_user_pref_service()->GetBoolean(
  575. prefs::kLaunchPaletteOnEjectEvent));
  576. active_user_pref_service()->SetBoolean(prefs::kShownPaletteWelcomeBubble,
  577. false);
  578. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  579. EjectStylus();
  580. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  581. }
  582. // Verify that the bubble does not get shown if a stylus event has been seen by
  583. // the tray prior to the first stylus ejection.
  584. TEST_F(PaletteTrayTestWithInternalStylus,
  585. WelcomeBubbleNotShownIfStylusTouchTray) {
  586. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  587. ASSERT_FALSE(active_user_pref_service()->GetBoolean(
  588. prefs::kShownPaletteWelcomeBubble));
  589. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  590. ui::test::EventGenerator* generator = GetEventGenerator();
  591. generator->EnterPenPointerMode();
  592. generator->set_current_screen_location(
  593. palette_tray_->GetBoundsInScreen().CenterPoint());
  594. generator->PressTouch();
  595. generator->ReleaseTouch();
  596. EXPECT_TRUE(active_user_pref_service()->GetBoolean(
  597. prefs::kShownPaletteWelcomeBubble));
  598. EjectStylus();
  599. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  600. }
  601. // Verify that palette bubble is shown/hidden on stylus eject/insert iff the
  602. // auto open palette setting is true.
  603. TEST_F(PaletteTrayTestWithInternalStylus, PaletteBubbleShownOnEject) {
  604. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  605. // kLaunchPaletteOnEjectEvent is true by default.
  606. ASSERT_TRUE(active_user_pref_service()->GetBoolean(
  607. prefs::kLaunchPaletteOnEjectEvent));
  608. // Removing the stylus shows the bubble.
  609. EjectStylus();
  610. EXPECT_TRUE(palette_tray_->GetBubbleView());
  611. // Inserting the stylus hides the bubble.
  612. InsertStylus();
  613. EXPECT_FALSE(palette_tray_->GetBubbleView());
  614. // Removing the stylus while kLaunchPaletteOnEjectEvent==false does nothing.
  615. active_user_pref_service()->SetBoolean(prefs::kLaunchPaletteOnEjectEvent,
  616. false);
  617. EjectStylus();
  618. EXPECT_FALSE(palette_tray_->GetBubbleView());
  619. InsertStylus();
  620. // Removing the stylus while kEnableStylusTools==false does nothing.
  621. active_user_pref_service()->SetBoolean(prefs::kLaunchPaletteOnEjectEvent,
  622. true);
  623. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, false);
  624. EjectStylus();
  625. EXPECT_FALSE(palette_tray_->GetBubbleView());
  626. InsertStylus();
  627. // Set both prefs to true, removing should work again.
  628. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  629. EjectStylus();
  630. EXPECT_TRUE(palette_tray_->GetBubbleView());
  631. // Inserting the stylus should disable a currently selected tool.
  632. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::LASER_POINTER);
  633. EXPECT_TRUE(test_api_->palette_tool_manager()->IsToolActive(
  634. PaletteToolId::LASER_POINTER));
  635. InsertStylus();
  636. EXPECT_FALSE(test_api_->palette_tool_manager()->IsToolActive(
  637. PaletteToolId::LASER_POINTER));
  638. }
  639. // Base class for tests that need to simulate an internal stylus, and need to
  640. // start without an active session.
  641. class PaletteTrayNoSessionTestWithInternalStylus : public PaletteTrayTest {
  642. public:
  643. PaletteTrayNoSessionTestWithInternalStylus() {
  644. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  645. switches::kHasInternalStylus);
  646. stylus_utils::SetHasStylusInputForTesting();
  647. }
  648. PaletteTrayNoSessionTestWithInternalStylus(
  649. const PaletteTrayNoSessionTestWithInternalStylus&) = delete;
  650. PaletteTrayNoSessionTestWithInternalStylus& operator=(
  651. const PaletteTrayNoSessionTestWithInternalStylus&) = delete;
  652. ~PaletteTrayNoSessionTestWithInternalStylus() override = default;
  653. protected:
  654. PrefService* active_user_pref_service() {
  655. return Shell::Get()->session_controller()->GetActivePrefService();
  656. }
  657. };
  658. // Verify that the palette tray is created on an external display, but it is not
  659. // shown, and the palette tray bubble does not appear when the stylus is
  660. // ejected.
  661. TEST_F(PaletteTrayNoSessionTestWithInternalStylus,
  662. ExternalMonitorBubbleNotShownOnEject) {
  663. // Fakes a stylus event with state |state| on all palette trays.
  664. auto fake_stylus_event_on_all_trays = [](ui::StylusState state) {
  665. Shell::RootWindowControllerList controllers =
  666. Shell::GetAllRootWindowControllers();
  667. for (size_t i = 0; i < controllers.size(); ++i) {
  668. PaletteTray* tray = controllers[i]->GetStatusAreaWidget()->palette_tray();
  669. PaletteTrayTestApi api(tray);
  670. api.OnStylusStateChanged(state);
  671. }
  672. };
  673. // Add a external display, then sign in.
  674. UpdateDisplay("300x200,300x200");
  675. display::test::DisplayManagerTestApi(display_manager())
  676. .SetFirstDisplayAsInternalDisplay();
  677. Shell::RootWindowControllerList controllers =
  678. Shell::GetAllRootWindowControllers();
  679. ASSERT_EQ(2u, controllers.size());
  680. SimulateUserLogin("test@test.com");
  681. base::CommandLine::ForCurrentProcess()->RemoveSwitch(
  682. switches::kAshEnablePaletteOnAllDisplays);
  683. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  684. PaletteTray* main_tray =
  685. controllers[0]->GetStatusAreaWidget()->palette_tray();
  686. PaletteTray* external_tray =
  687. controllers[1]->GetStatusAreaWidget()->palette_tray();
  688. test_api_->SetDisplayHasStylus();
  689. // The palette tray on the external monitor is not visible.
  690. EXPECT_TRUE(main_tray->GetVisible());
  691. EXPECT_FALSE(external_tray->GetVisible());
  692. // Removing the stylus shows the bubble only on the main palette tray.
  693. fake_stylus_event_on_all_trays(ui::StylusState::REMOVED);
  694. EXPECT_TRUE(main_tray->GetBubbleView());
  695. EXPECT_FALSE(external_tray->GetBubbleView());
  696. // Inserting the stylus hides the bubble on both palette trays.
  697. fake_stylus_event_on_all_trays(ui::StylusState::INSERTED);
  698. EXPECT_FALSE(main_tray->GetBubbleView());
  699. EXPECT_FALSE(external_tray->GetBubbleView());
  700. }
  701. class PaletteTrayTestWithOOBE : public PaletteTrayTest {
  702. public:
  703. PaletteTrayTestWithOOBE() = default;
  704. ~PaletteTrayTestWithOOBE() override = default;
  705. // PalatteTrayTest:
  706. void SetUp() override {
  707. set_start_session(false);
  708. PaletteTrayTest::SetUp();
  709. }
  710. };
  711. // Verify there are no crashes if the stylus is used during OOBE.
  712. TEST_F(PaletteTrayTestWithOOBE, StylusEventsSafeDuringOOBE) {
  713. GetSessionControllerClient()->SetSessionState(
  714. session_manager::SessionState::OOBE);
  715. ui::test::EventGenerator* generator = GetEventGenerator();
  716. generator->EnterPenPointerMode();
  717. generator->PressTouch();
  718. generator->ReleaseTouch();
  719. }
  720. // Base class for tests that need to simulate multiple pen
  721. // capable displays.
  722. class PaletteTrayTestMultiDisplay : public PaletteTrayTest {
  723. public:
  724. PaletteTrayTestMultiDisplay() = default;
  725. ~PaletteTrayTestMultiDisplay() override = default;
  726. PaletteTrayTestMultiDisplay(const PaletteTrayTestMultiDisplay&) = delete;
  727. PaletteTrayTestMultiDisplay& operator=(const PaletteTrayTestMultiDisplay&) =
  728. delete;
  729. // Performs a tap on the palette tray button.
  730. void PerformTap(PaletteTray* tray) {
  731. ui::GestureEvent tap(0, 0, 0, base::TimeTicks(),
  732. ui::GestureEventDetails(ui::ET_GESTURE_TAP));
  733. tray->PerformAction(tap);
  734. }
  735. // Fake a stylus ejection.
  736. void EjectStylus() {
  737. test_api_->OnStylusStateChanged(ui::StylusState::REMOVED);
  738. test_api_external_->OnStylusStateChanged(ui::StylusState::REMOVED);
  739. }
  740. // Fake a stylus insertion.
  741. void InsertStylus() {
  742. test_api_->OnStylusStateChanged(ui::StylusState::INSERTED);
  743. test_api_external_->OnStylusStateChanged(ui::StylusState::INSERTED);
  744. }
  745. // PaletteTrayTest:
  746. void SetUp() override {
  747. PaletteTrayTest::SetUp();
  748. base::CommandLine::ForCurrentProcess()->RemoveSwitch(
  749. switches::kAshEnablePaletteOnAllDisplays);
  750. // Add a external display, then sign in.
  751. UpdateDisplay("300x200,300x200");
  752. display::test::DisplayManagerTestApi(display_manager())
  753. .SetFirstDisplayAsInternalDisplay();
  754. Shell::RootWindowControllerList controllers =
  755. Shell::GetAllRootWindowControllers();
  756. ASSERT_EQ(2u, controllers.size());
  757. SimulateUserLogin("test@test.com");
  758. palette_tray_ = controllers[0]->GetStatusAreaWidget()->palette_tray();
  759. palette_tray_external_ =
  760. controllers[1]->GetStatusAreaWidget()->palette_tray();
  761. ASSERT_TRUE(palette_tray_);
  762. ASSERT_TRUE(palette_tray_external_);
  763. test_api_external_ =
  764. std::make_unique<PaletteTrayTestApi>(palette_tray_external_);
  765. }
  766. protected:
  767. PaletteTray* palette_tray_external_ = nullptr;
  768. std::unique_ptr<PaletteTrayTestApi> test_api_external_;
  769. };
  770. // Verify the palette welcome bubble is shown only on the internal display
  771. // the first time the stylus is removed.
  772. TEST_F(PaletteTrayTestMultiDisplay, WelcomeBubbleShownOnEject) {
  773. test_api_->SetDisplayHasStylus();
  774. test_api_external_->SetDisplayHasStylus();
  775. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  776. active_user_pref_service()->SetBoolean(prefs::kLaunchPaletteOnEjectEvent,
  777. false);
  778. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  779. switches::kHasInternalStylus);
  780. ASSERT_FALSE(active_user_pref_service()->GetBoolean(
  781. prefs::kShownPaletteWelcomeBubble));
  782. EXPECT_FALSE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  783. EXPECT_FALSE(test_api_external_->welcome_bubble()->GetBubbleViewForTesting());
  784. EjectStylus();
  785. EXPECT_TRUE(test_api_->welcome_bubble()->GetBubbleViewForTesting());
  786. EXPECT_FALSE(test_api_external_->welcome_bubble()->GetBubbleViewForTesting());
  787. }
  788. // Verify that palette bubble does not open on the external display
  789. // on stylus eject/insert.
  790. TEST_F(PaletteTrayTestMultiDisplay, PaletteBubbleShownOnEject) {
  791. test_api_->SetDisplayHasStylus();
  792. test_api_external_->SetDisplayHasStylus();
  793. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  794. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  795. switches::kHasInternalStylus);
  796. // kLaunchPaletteOnEjectEvent is true by default.
  797. ASSERT_TRUE(active_user_pref_service()->GetBoolean(
  798. prefs::kLaunchPaletteOnEjectEvent));
  799. // Removing the stylus shows the bubble on the internal display.
  800. EjectStylus();
  801. EXPECT_TRUE(palette_tray_->GetBubbleView());
  802. EXPECT_FALSE(palette_tray_external_->GetBubbleView());
  803. // Inserting the stylus hides the bubble.
  804. InsertStylus();
  805. EXPECT_FALSE(palette_tray_->GetBubbleView());
  806. EXPECT_FALSE(palette_tray_external_->GetBubbleView());
  807. // Inserting the stylus should disable a currently selected tool
  808. // even if it is on an external display.
  809. test_api_external_->palette_tool_manager()->ActivateTool(
  810. PaletteToolId::LASER_POINTER);
  811. EXPECT_TRUE(test_api_external_->palette_tool_manager()->IsToolActive(
  812. PaletteToolId::LASER_POINTER));
  813. InsertStylus();
  814. EXPECT_FALSE(test_api_external_->palette_tool_manager()->IsToolActive(
  815. PaletteToolId::LASER_POINTER));
  816. }
  817. void addStylusToDisplay(int64_t display_id) {
  818. ui::DeviceDataManager* device_data_manager =
  819. ui::DeviceDataManager::GetInstance();
  820. int stylus_device_id = 10;
  821. base::RunLoop().RunUntilIdle();
  822. if (device_data_manager->GetTouchscreenDevices().size() == 0) {
  823. ui::TouchscreenDevice stylus_device = ui::TouchscreenDevice(
  824. stylus_device_id, ui::InputDeviceType::INPUT_DEVICE_USB,
  825. std::string("Stylus"), gfx::Size(1, 1), 1, true);
  826. std::vector<ui::TouchscreenDevice> devices;
  827. devices.push_back(stylus_device);
  828. static_cast<ui::DeviceHotplugEventObserver*>(device_data_manager)
  829. ->OnTouchscreenDevicesUpdated(devices);
  830. }
  831. std::vector<ui::TouchDeviceTransform> device_transforms(1);
  832. device_transforms[0].display_id = display_id;
  833. device_transforms[0].device_id = stylus_device_id;
  834. device_data_manager->ConfigureTouchDevices(device_transforms);
  835. ASSERT_EQ(1U, device_data_manager->GetTouchscreenDevices().size());
  836. ASSERT_EQ(display_id,
  837. device_data_manager->GetTouchscreenDevices()[0].target_display_id);
  838. ASSERT_TRUE(device_data_manager->AreTouchscreenTargetDisplaysValid());
  839. }
  840. // Verify that palette state is refreshed when the display
  841. // layout changes.
  842. TEST_F(PaletteTrayTestMultiDisplay, MirrorModeEnable) {
  843. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  844. // We should already by in extended mode with two displays
  845. ASSERT_EQ(2U, Shell::Get()->display_manager()->GetNumDisplays());
  846. const int64_t external_display_id =
  847. display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
  848. .GetSecondaryDisplay()
  849. .id();
  850. addStylusToDisplay(external_display_id);
  851. // The palette tray on the internal monitor is not visible.
  852. EXPECT_FALSE(palette_tray_->GetVisible());
  853. EXPECT_TRUE(palette_tray_external_->GetVisible());
  854. // Enable mirror mode
  855. Shell::Get()->display_manager()->SetMultiDisplayMode(
  856. display::DisplayManager::MIRRORING);
  857. Shell::Get()->display_manager()->UpdateDisplays();
  858. base::RunLoop().RunUntilIdle();
  859. ASSERT_EQ(1U, Shell::Get()->display_manager()->GetNumDisplays());
  860. addStylusToDisplay(external_display_id);
  861. // The external tray will have been deleted, so only check if
  862. // we're visible on the internal display now.
  863. EXPECT_TRUE(palette_tray_->GetVisible());
  864. }
  865. class PaletteTrayTestWithProjector : public PaletteTrayTest {
  866. public:
  867. PaletteTrayTestWithProjector() {
  868. scoped_feature_list_.InitWithFeatures({features::kProjector}, {});
  869. }
  870. PaletteTrayTestWithProjector(const PaletteTrayTestWithProjector&) = delete;
  871. PaletteTrayTestWithProjector& operator=(const PaletteTrayTestWithProjector&) =
  872. delete;
  873. ~PaletteTrayTestWithProjector() override = default;
  874. // AshTestBase:
  875. void SetUp() override {
  876. PaletteTrayTest::SetUp();
  877. projector_session_ = ProjectorControllerImpl::Get()->projector_session();
  878. }
  879. protected:
  880. ProjectorSessionImpl* projector_session_;
  881. private:
  882. base::test::ScopedFeatureList scoped_feature_list_;
  883. };
  884. // Verify that the palette tray is hidden during a Projector session.
  885. TEST_F(PaletteTrayTestWithProjector,
  886. PaletteTrayNotVisibleDuringProjectorSession) {
  887. active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
  888. local_state()->SetBoolean(prefs::kHasSeenStylus, true);
  889. test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::LASER_POINTER);
  890. EXPECT_TRUE(palette_tray_->GetVisible());
  891. EXPECT_EQ(
  892. test_api_->palette_tool_manager()->GetActiveTool(PaletteGroup::MODE),
  893. PaletteToolId::LASER_POINTER);
  894. // Verify palette tray is hidden and the active tool is deactivated during
  895. // Projector session.
  896. projector_session_->Start("projector_data");
  897. EXPECT_FALSE(palette_tray_->GetVisible());
  898. EXPECT_EQ(
  899. test_api_->palette_tool_manager()->GetActiveTool(PaletteGroup::MODE),
  900. PaletteToolId::NONE);
  901. // Verify palette tray is visible when Projector session ends.
  902. projector_session_->Stop();
  903. EXPECT_TRUE(palette_tray_->GetVisible());
  904. }
  905. } // namespace ash