persistent_window_controller_unittest.cc 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. // Copyright 2018 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/display/persistent_window_controller.h"
  5. #include "ash/display/display_move_window_util.h"
  6. #include "ash/display/screen_orientation_controller_test_api.h"
  7. #include "ash/display/window_tree_host_manager.h"
  8. #include "ash/screen_util.h"
  9. #include "ash/session/test_session_controller_client.h"
  10. #include "ash/shell.h"
  11. #include "ash/test/ash_test_base.h"
  12. #include "ash/wm/mru_window_tracker.h"
  13. #include "ash/wm/splitview/split_view_controller.h"
  14. #include "ash/wm/window_state.h"
  15. #include "ash/wm/window_util.h"
  16. #include "base/test/metrics/histogram_tester.h"
  17. #include "chromeos/ui/base/display_util.h"
  18. #include "chromeos/ui/base/window_state_type.h"
  19. #include "ui/display/test/display_manager_test_api.h"
  20. using session_manager::SessionState;
  21. namespace ash {
  22. using PersistentWindowControllerTest = AshTestBase;
  23. TEST_F(PersistentWindowControllerTest, DisconnectDisplay) {
  24. UpdateDisplay("500x600,500x600");
  25. aura::Window* w1 =
  26. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  27. aura::Window* w2 =
  28. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  29. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  30. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  31. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  32. const int64_t secondary_id =
  33. display::test::DisplayManagerTestApi(display_manager())
  34. .GetSecondaryDisplay()
  35. .id();
  36. display::ManagedDisplayInfo primary_info =
  37. display_manager()->GetDisplayInfo(primary_id);
  38. display::ManagedDisplayInfo secondary_info =
  39. display_manager()->GetDisplayInfo(secondary_id);
  40. // Disconnects secondary display.
  41. std::vector<display::ManagedDisplayInfo> display_info_list;
  42. display_info_list.push_back(primary_info);
  43. display_manager()->OnNativeDisplaysChanged(display_info_list);
  44. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  45. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  46. // Reconnects secondary display.
  47. display_info_list.push_back(secondary_info);
  48. display_manager()->OnNativeDisplaysChanged(display_info_list);
  49. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  50. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  51. // Disconnects primary display.
  52. display_info_list.clear();
  53. display_info_list.push_back(secondary_info);
  54. display_manager()->OnNativeDisplaysChanged(display_info_list);
  55. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  56. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  57. // Reconnects primary display.
  58. display_info_list.push_back(primary_info);
  59. display_manager()->OnNativeDisplaysChanged(display_info_list);
  60. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  61. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  62. // Disconnects secondary display.
  63. display_info_list.clear();
  64. display_info_list.push_back(primary_info);
  65. display_manager()->OnNativeDisplaysChanged(display_info_list);
  66. // A third id which is different from primary and secondary.
  67. const int64_t third_id = secondary_id + 1;
  68. display::ManagedDisplayInfo third_info =
  69. display::CreateDisplayInfo(third_id, gfx::Rect(0, 501, 600, 500));
  70. // Connects another secondary display with |third_id|.
  71. display_info_list.push_back(third_info);
  72. display_manager()->OnNativeDisplaysChanged(display_info_list);
  73. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  74. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  75. // Connects secondary display with |secondary_id|.
  76. display_info_list.clear();
  77. display_info_list.push_back(primary_info);
  78. display_info_list.push_back(secondary_info);
  79. display_manager()->OnNativeDisplaysChanged(display_info_list);
  80. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  81. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  82. // Disconnects secondary display.
  83. display_info_list.clear();
  84. display_info_list.push_back(primary_info);
  85. display_manager()->OnNativeDisplaysChanged(display_info_list);
  86. // Sets |w2|'s bounds changed by user and then reconnects secondary display.
  87. WindowState* w2_state = WindowState::Get(w2);
  88. w2_state->set_bounds_changed_by_user(true);
  89. display_info_list.push_back(secondary_info);
  90. display_manager()->OnNativeDisplaysChanged(display_info_list);
  91. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  92. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  93. }
  94. TEST_F(PersistentWindowControllerTest, ThreeDisplays) {
  95. UpdateDisplay("500x600,500x600,500x600");
  96. aura::Window* w1 =
  97. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  98. aura::Window* w2 =
  99. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  100. aura::Window* w3 =
  101. CreateTestWindowInShellWithBounds(gfx::Rect(1002, 0, 400, 200));
  102. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  103. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  104. EXPECT_EQ(gfx::Rect(1002, 0, 400, 200), w3->GetBoundsInScreen());
  105. const int64_t primary_id = display_manager()->GetDisplayAt(0).id();
  106. const int64_t second_id = display_manager()->GetDisplayAt(1).id();
  107. const int64_t third_id = display_manager()->GetDisplayAt(2).id();
  108. display::ManagedDisplayInfo primary_info =
  109. display_manager()->GetDisplayInfo(primary_id);
  110. display::ManagedDisplayInfo second_info =
  111. display_manager()->GetDisplayInfo(second_id);
  112. display::ManagedDisplayInfo third_info =
  113. display_manager()->GetDisplayInfo(third_id);
  114. // Disconnects third display.
  115. std::vector<display::ManagedDisplayInfo> display_info_list;
  116. display_info_list.push_back(primary_info);
  117. display_info_list.push_back(second_info);
  118. display_manager()->OnNativeDisplaysChanged(display_info_list);
  119. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  120. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  121. EXPECT_EQ(gfx::Rect(2, 0, 400, 200), w3->GetBoundsInScreen());
  122. // Disconnects second display.
  123. display_info_list.clear();
  124. display_info_list.push_back(primary_info);
  125. display_manager()->OnNativeDisplaysChanged(display_info_list);
  126. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  127. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  128. EXPECT_EQ(gfx::Rect(2, 0, 400, 200), w3->GetBoundsInScreen());
  129. // Reconnects third display.
  130. display_info_list.push_back(third_info);
  131. display_manager()->OnNativeDisplaysChanged(display_info_list);
  132. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  133. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  134. EXPECT_EQ(gfx::Rect(502, 0, 400, 200), w3->GetBoundsInScreen());
  135. // Reconnects second display.
  136. display_info_list.push_back(second_info);
  137. display_manager()->OnNativeDisplaysChanged(display_info_list);
  138. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  139. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  140. EXPECT_EQ(gfx::Rect(1002, 0, 400, 200), w3->GetBoundsInScreen());
  141. // Disconnects both external displays.
  142. display_info_list.clear();
  143. display_info_list.push_back(primary_info);
  144. display_manager()->OnNativeDisplaysChanged(display_info_list);
  145. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  146. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  147. EXPECT_EQ(gfx::Rect(2, 0, 400, 200), w3->GetBoundsInScreen());
  148. // Reconnects second display.
  149. display_info_list.push_back(second_info);
  150. display_manager()->OnNativeDisplaysChanged(display_info_list);
  151. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  152. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  153. EXPECT_EQ(gfx::Rect(2, 0, 400, 200), w3->GetBoundsInScreen());
  154. // Reconnects third display.
  155. display_info_list.push_back(third_info);
  156. display_manager()->OnNativeDisplaysChanged(display_info_list);
  157. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  158. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  159. EXPECT_EQ(gfx::Rect(1002, 0, 400, 200), w3->GetBoundsInScreen());
  160. }
  161. TEST_F(PersistentWindowControllerTest, NormalMirrorMode) {
  162. UpdateDisplay("500x600,500x600");
  163. aura::Window* w1 =
  164. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  165. aura::Window* w2 =
  166. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  167. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  168. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  169. // Enables mirror mode.
  170. display_manager()->SetMirrorMode(display::MirrorMode::kNormal, absl::nullopt);
  171. EXPECT_TRUE(display_manager()->IsInMirrorMode());
  172. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  173. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  174. // Disables mirror mode.
  175. display_manager()->SetMirrorMode(display::MirrorMode::kOff, absl::nullopt);
  176. EXPECT_FALSE(display_manager()->IsInMirrorMode());
  177. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  178. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  179. }
  180. TEST_F(PersistentWindowControllerTest, MixedMirrorMode) {
  181. UpdateDisplay("500x600,500x600,500x600");
  182. aura::Window* w1 =
  183. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  184. aura::Window* w2 =
  185. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  186. aura::Window* w3 =
  187. CreateTestWindowInShellWithBounds(gfx::Rect(1002, 0, 400, 200));
  188. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  189. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  190. EXPECT_EQ(gfx::Rect(1002, 0, 400, 200), w3->GetBoundsInScreen());
  191. const int64_t primary_id = display_manager()->GetDisplayAt(0).id();
  192. const int64_t second_id = display_manager()->GetDisplayAt(1).id();
  193. const int64_t third_id = display_manager()->GetDisplayAt(2).id();
  194. display::ManagedDisplayInfo primary_info =
  195. display_manager()->GetDisplayInfo(primary_id);
  196. display::ManagedDisplayInfo second_info =
  197. display_manager()->GetDisplayInfo(second_id);
  198. display::ManagedDisplayInfo third_info =
  199. display_manager()->GetDisplayInfo(third_id);
  200. // Turn on mixed mirror mode. (Mirror from the primary display to the second
  201. // display).
  202. display::DisplayIdList dst_ids;
  203. dst_ids.emplace_back(second_id);
  204. display_manager()->SetMirrorMode(
  205. display::MirrorMode::kMixed,
  206. absl::make_optional<display::MixedMirrorModeParams>(primary_id, dst_ids));
  207. EXPECT_TRUE(display_manager()->IsInMirrorMode());
  208. EXPECT_TRUE(display_manager()->mixed_mirror_mode_params());
  209. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  210. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  211. EXPECT_EQ(gfx::Rect(502, 0, 400, 200), w3->GetBoundsInScreen());
  212. // Turn off mixed mirror mode.
  213. display_manager()->SetMirrorMode(display::MirrorMode::kOff, absl::nullopt);
  214. EXPECT_FALSE(display_manager()->IsInMirrorMode());
  215. EXPECT_FALSE(display_manager()->mixed_mirror_mode_params());
  216. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  217. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  218. EXPECT_EQ(gfx::Rect(1002, 0, 400, 200), w3->GetBoundsInScreen());
  219. }
  220. TEST_F(PersistentWindowControllerTest, WindowMovedByAccel) {
  221. UpdateDisplay("500x600,500x600");
  222. aura::Window* w1 =
  223. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  224. aura::Window* w2 =
  225. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  226. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  227. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  228. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  229. const int64_t secondary_id =
  230. display::test::DisplayManagerTestApi(display_manager())
  231. .GetSecondaryDisplay()
  232. .id();
  233. display::ManagedDisplayInfo primary_info =
  234. display_manager()->GetDisplayInfo(primary_id);
  235. display::ManagedDisplayInfo secondary_info =
  236. display_manager()->GetDisplayInfo(secondary_id);
  237. // Disconnects secondary display.
  238. std::vector<display::ManagedDisplayInfo> display_info_list;
  239. display_info_list.push_back(primary_info);
  240. display_manager()->OnNativeDisplaysChanged(display_info_list);
  241. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  242. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  243. // Reconnects secondary display.
  244. display_info_list.push_back(secondary_info);
  245. display_manager()->OnNativeDisplaysChanged(display_info_list);
  246. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  247. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  248. // Moves |w2| to primary display by accelerators after we reset the persistent
  249. // window info. It should be able to save persistent window info again on next
  250. // display change.
  251. wm::ActivateWindow(w2);
  252. display_move_window_util::HandleMoveActiveWindowBetweenDisplays();
  253. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  254. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  255. // Disconnects secondary display.
  256. display_info_list.clear();
  257. display_info_list.push_back(primary_info);
  258. display_manager()->OnNativeDisplaysChanged(display_info_list);
  259. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  260. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  261. // Reconnects secondary display.
  262. display_info_list.push_back(secondary_info);
  263. display_manager()->OnNativeDisplaysChanged(display_info_list);
  264. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  265. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  266. }
  267. TEST_F(PersistentWindowControllerTest, ReconnectOnLockScreen) {
  268. UpdateDisplay("500x600,500x600");
  269. aura::Window* w1 =
  270. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  271. aura::Window* w2 =
  272. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  273. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  274. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  275. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  276. const int64_t secondary_id =
  277. display::test::DisplayManagerTestApi(display_manager())
  278. .GetSecondaryDisplay()
  279. .id();
  280. display::ManagedDisplayInfo primary_info =
  281. display_manager()->GetDisplayInfo(primary_id);
  282. display::ManagedDisplayInfo secondary_info =
  283. display_manager()->GetDisplayInfo(secondary_id);
  284. // Disconnects secondary display.
  285. std::vector<display::ManagedDisplayInfo> display_info_list;
  286. display_info_list.push_back(primary_info);
  287. display_manager()->OnNativeDisplaysChanged(display_info_list);
  288. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  289. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  290. // Spin a run loop to ensure shelf is deleted. https://crbug.com/810807.
  291. base::RunLoop().RunUntilIdle();
  292. // Enters locked session state and reconnects secondary display.
  293. GetSessionControllerClient()->SetSessionState(SessionState::LOCKED);
  294. display_info_list.push_back(secondary_info);
  295. display_manager()->OnNativeDisplaysChanged(display_info_list);
  296. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  297. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  298. // Unlocks and checks that |w2| is restored.
  299. GetSessionControllerClient()->SetSessionState(SessionState::ACTIVE);
  300. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  301. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  302. }
  303. TEST_F(PersistentWindowControllerTest, RecordNumOfWindowsRestored) {
  304. UpdateDisplay("500x600,500x600");
  305. aura::Window* w1 =
  306. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  307. aura::Window* w2 =
  308. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  309. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  310. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  311. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  312. const int64_t secondary_id =
  313. display::test::DisplayManagerTestApi(display_manager())
  314. .GetSecondaryDisplay()
  315. .id();
  316. display::ManagedDisplayInfo primary_info =
  317. display_manager()->GetDisplayInfo(primary_id);
  318. display::ManagedDisplayInfo secondary_info =
  319. display_manager()->GetDisplayInfo(secondary_id);
  320. // Disconnects secondary display.
  321. std::vector<display::ManagedDisplayInfo> display_info_list;
  322. display_info_list.push_back(primary_info);
  323. display_manager()->OnNativeDisplaysChanged(display_info_list);
  324. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  325. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  326. base::HistogramTester histogram_tester;
  327. histogram_tester.ExpectTotalCount(
  328. PersistentWindowController::kNumOfWindowsRestoredOnDisplayAdded, 0);
  329. // Reconnects secondary display.
  330. display_info_list.push_back(secondary_info);
  331. display_manager()->OnNativeDisplaysChanged(display_info_list);
  332. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  333. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  334. histogram_tester.ExpectTotalCount(
  335. PersistentWindowController::kNumOfWindowsRestoredOnDisplayAdded, 1);
  336. }
  337. // Tests that swapping primary display shall not do persistent window restore.
  338. TEST_F(PersistentWindowControllerTest, SwapPrimaryDisplay) {
  339. const int64_t internal_display_id =
  340. display::test::DisplayManagerTestApi(display_manager())
  341. .SetFirstDisplayAsInternalDisplay();
  342. const display::ManagedDisplayInfo native_display_info =
  343. display::CreateDisplayInfo(internal_display_id,
  344. gfx::Rect(0, 0, 500, 600));
  345. const display::ManagedDisplayInfo secondary_display_info =
  346. display::CreateDisplayInfo(10, gfx::Rect(1, 1, 400, 500));
  347. std::vector<display::ManagedDisplayInfo> display_info_list;
  348. display_info_list.push_back(native_display_info);
  349. display_info_list.push_back(secondary_display_info);
  350. display_manager()->OnNativeDisplaysChanged(display_info_list);
  351. aura::Window* w1 =
  352. CreateTestWindowInShellWithBounds(gfx::Rect(200, 0, 100, 200));
  353. aura::Window* w2 =
  354. CreateTestWindowInShellWithBounds(gfx::Rect(501, 0, 200, 100));
  355. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  356. EXPECT_EQ(gfx::Rect(501, 0, 200, 100), w2->GetBoundsInScreen());
  357. // Swaps primary display and check window bounds.
  358. SwapPrimaryDisplay();
  359. ASSERT_EQ(gfx::Rect(-500, 0, 500, 600),
  360. display_manager()->GetDisplayForId(internal_display_id).bounds());
  361. ASSERT_EQ(gfx::Rect(0, 0, 400, 500),
  362. display_manager()->GetDisplayForId(10).bounds());
  363. EXPECT_EQ(gfx::Rect(200, 0, 100, 200), w1->GetBoundsInScreen());
  364. EXPECT_EQ(gfx::Rect(-499, 0, 200, 100), w2->GetBoundsInScreen());
  365. }
  366. // Tests that restore bounds persist after adding and removing a display.
  367. TEST_F(PersistentWindowControllerTest, RestoreBounds) {
  368. UpdateDisplay("500x600,500x600");
  369. std::unique_ptr<aura::Window> window = CreateTestWindow(gfx::Rect(200, 200));
  370. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  371. const int64_t secondary_id =
  372. display::test::DisplayManagerTestApi(display_manager())
  373. .GetSecondaryDisplay()
  374. .id();
  375. display::Screen* screen = display::Screen::GetScreen();
  376. ASSERT_EQ(primary_id, screen->GetDisplayNearestWindow(window.get()).id());
  377. // Move the window to the secondary display and maximize it.
  378. display_move_window_util::HandleMoveActiveWindowBetweenDisplays();
  379. ASSERT_EQ(secondary_id, screen->GetDisplayNearestWindow(window.get()).id());
  380. WindowState* window_state = WindowState::Get(window.get());
  381. window_state->Maximize();
  382. EXPECT_TRUE(window_state->HasRestoreBounds());
  383. const gfx::Rect restore_bounds_in_screen =
  384. window_state->GetRestoreBoundsInScreen();
  385. display::ManagedDisplayInfo primary_info =
  386. display_manager()->GetDisplayInfo(primary_id);
  387. display::ManagedDisplayInfo secondary_info =
  388. display_manager()->GetDisplayInfo(secondary_id);
  389. // Disconnect secondary display.
  390. std::vector<display::ManagedDisplayInfo> display_info_list;
  391. display_info_list.push_back(primary_info);
  392. display_manager()->OnNativeDisplaysChanged(display_info_list);
  393. EXPECT_EQ(primary_id, screen->GetDisplayNearestWindow(window.get()).id());
  394. // Reconnect secondary display. On restoring the maximized window, the bounds
  395. // should be the same as they were before maximizing and disconnecting the
  396. // display.
  397. display_info_list.push_back(secondary_info);
  398. display_manager()->OnNativeDisplaysChanged(display_info_list);
  399. EXPECT_EQ(secondary_id, screen->GetDisplayNearestWindow(window.get()).id());
  400. EXPECT_TRUE(window_state->IsMaximized());
  401. // Restore the window (i.e. press restore button on header).
  402. window_state->Restore();
  403. EXPECT_TRUE(window_state->IsNormalStateType());
  404. EXPECT_EQ(restore_bounds_in_screen, window->GetBoundsInScreen());
  405. }
  406. // Tests that the MRU order is maintained visually after adding and removing a
  407. // display.
  408. TEST_F(PersistentWindowControllerTest, MRUOrderMatchesStacking) {
  409. UpdateDisplay("500x600,500x600");
  410. // Add three windows, all on the secondary display.
  411. const gfx::Rect bounds(500, 0, 200, 200);
  412. std::unique_ptr<aura::Window> window1 = CreateTestWindow(bounds);
  413. std::unique_ptr<aura::Window> window2 = CreateTestWindow(bounds);
  414. std::unique_ptr<aura::Window> window3 = CreateTestWindow(bounds);
  415. // MRU order should be opposite of the order the windows were created. Verify
  416. // that all three windows are indeed on the secondary display.
  417. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  418. const int64_t secondary_id =
  419. display::test::DisplayManagerTestApi(display_manager())
  420. .GetSecondaryDisplay()
  421. .id();
  422. display::Screen* screen = display::Screen::GetScreen();
  423. const std::vector<aura::Window*> expected_mru_order = {
  424. window3.get(), window2.get(), window1.get()};
  425. ASSERT_EQ(
  426. expected_mru_order,
  427. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  428. for (auto* window : expected_mru_order)
  429. ASSERT_EQ(secondary_id, screen->GetDisplayNearestWindow(window).id());
  430. // Disconnect secondary display. The windows should move to the primary
  431. // display and retain MRU ordering.
  432. display::ManagedDisplayInfo primary_info =
  433. display_manager()->GetDisplayInfo(primary_id);
  434. display::ManagedDisplayInfo secondary_info =
  435. display_manager()->GetDisplayInfo(secondary_id);
  436. std::vector<display::ManagedDisplayInfo> display_info_list;
  437. display_info_list.push_back(primary_info);
  438. display_manager()->OnNativeDisplaysChanged(display_info_list);
  439. // The order which the children are stacked in is the reverse of the order
  440. // they are in the children() field.
  441. aura::Window* parent = window1->parent();
  442. ASSERT_TRUE(parent);
  443. std::vector<aura::Window*> children_ordered_by_stacking = parent->children();
  444. std::reverse(children_ordered_by_stacking.begin(),
  445. children_ordered_by_stacking.end());
  446. EXPECT_EQ(
  447. expected_mru_order,
  448. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  449. EXPECT_EQ(expected_mru_order, children_ordered_by_stacking);
  450. EXPECT_EQ(primary_id, screen->GetDisplayNearestWindow(parent).id());
  451. // Reconnect secondary display. The windows should move to the secondary
  452. // display and retain MRU ordering.
  453. display_info_list.push_back(secondary_info);
  454. display_manager()->OnNativeDisplaysChanged(display_info_list);
  455. parent = window1->parent();
  456. children_ordered_by_stacking = parent->children();
  457. std::reverse(children_ordered_by_stacking.begin(),
  458. children_ordered_by_stacking.end());
  459. ASSERT_TRUE(parent);
  460. EXPECT_EQ(
  461. expected_mru_order,
  462. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  463. EXPECT_EQ(expected_mru_order, children_ordered_by_stacking);
  464. EXPECT_EQ(secondary_id, screen->GetDisplayNearestWindow(parent).id());
  465. }
  466. // Similar to the above test but with windows created on both displays.
  467. TEST_F(PersistentWindowControllerTest, MRUOrderMatchesStackingInterleaved) {
  468. UpdateDisplay("500x600,500x600");
  469. // Add four windows, two on each display.
  470. const gfx::Rect primary_bounds(200, 200);
  471. const gfx::Rect secondary_bounds(500, 0, 200, 200);
  472. std::unique_ptr<aura::Window> window1 = CreateTestWindow(primary_bounds);
  473. std::unique_ptr<aura::Window> window2 = CreateTestWindow(secondary_bounds);
  474. std::unique_ptr<aura::Window> window3 = CreateTestWindow(primary_bounds);
  475. std::unique_ptr<aura::Window> window4 = CreateTestWindow(secondary_bounds);
  476. // MRU order should be opposite of the order the windows were created.
  477. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  478. const int64_t secondary_id =
  479. display::test::DisplayManagerTestApi(display_manager())
  480. .GetSecondaryDisplay()
  481. .id();
  482. display::Screen* screen = display::Screen::GetScreen();
  483. const std::vector<aura::Window*> expected_mru_order = {
  484. window4.get(), window3.get(), window2.get(), window1.get()};
  485. ASSERT_EQ(
  486. expected_mru_order,
  487. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  488. // Disconnect secondary display. The windows should move to the primary
  489. // display and retain MRU ordering. Note that this logic is part of
  490. // RootWindowController and not PersistentWindowController.
  491. display::ManagedDisplayInfo primary_info =
  492. display_manager()->GetDisplayInfo(primary_id);
  493. display::ManagedDisplayInfo secondary_info =
  494. display_manager()->GetDisplayInfo(secondary_id);
  495. std::vector<display::ManagedDisplayInfo> display_info_list;
  496. display_info_list.push_back(primary_info);
  497. display_manager()->OnNativeDisplaysChanged(display_info_list);
  498. // The order which the children are stacked in is the reverse of the order
  499. // they are in the children() field.
  500. aura::Window* parent = window1->parent();
  501. ASSERT_TRUE(parent);
  502. ASSERT_EQ(parent, window2->parent());
  503. std::vector<aura::Window*> children_ordered_by_stacking = parent->children();
  504. std::reverse(children_ordered_by_stacking.begin(),
  505. children_ordered_by_stacking.end());
  506. EXPECT_EQ(
  507. expected_mru_order,
  508. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  509. EXPECT_EQ(expected_mru_order, children_ordered_by_stacking);
  510. EXPECT_EQ(primary_id, screen->GetDisplayNearestWindow(parent).id());
  511. // Reconnect secondary display. |window2| and |window4| should move back to
  512. // the secondary display.
  513. display_info_list.push_back(secondary_info);
  514. display_manager()->OnNativeDisplaysChanged(display_info_list);
  515. EXPECT_EQ(
  516. expected_mru_order,
  517. Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks));
  518. parent = window1->parent();
  519. EXPECT_EQ(primary_id, screen->GetDisplayNearestWindow(parent).id());
  520. ASSERT_EQ(2u, parent->children().size());
  521. EXPECT_EQ(window1.get(), parent->children()[0]);
  522. EXPECT_EQ(window3.get(), parent->children()[1]);
  523. parent = window2->parent();
  524. EXPECT_EQ(secondary_id, screen->GetDisplayNearestWindow(parent).id());
  525. ASSERT_EQ(2u, parent->children().size());
  526. EXPECT_EQ(window2.get(), parent->children()[0]);
  527. EXPECT_EQ(window4.get(), parent->children()[1]);
  528. }
  529. // Tests that if a window is on a primary display which gets disconnected, on
  530. // reconnect the windows bounds will be persisted.
  531. TEST_F(PersistentWindowControllerTest, DisconnectingPrimaryDisplay) {
  532. // Create two displays with the one higher resolution.
  533. UpdateDisplay("500x600,1500x500");
  534. const int64_t small_id = WindowTreeHostManager::GetPrimaryDisplayId();
  535. const int64_t large_id =
  536. display::test::DisplayManagerTestApi(display_manager())
  537. .GetSecondaryDisplay()
  538. .id();
  539. // Set the larger display to be the primary display.
  540. Shell::Get()->window_tree_host_manager()->SetPrimaryDisplayId(large_id);
  541. ASSERT_EQ(large_id, WindowTreeHostManager::GetPrimaryDisplayId());
  542. // Add a window on the larger display.
  543. const gfx::Rect bounds(0, 200, 1500, 200);
  544. std::unique_ptr<aura::Window> window = CreateTestWindow(bounds);
  545. // Disconnect the large display. The windows should move to the new primary
  546. // display (small display) and shrink to fit.
  547. display::ManagedDisplayInfo small_info =
  548. display_manager()->GetDisplayInfo(small_id);
  549. display::ManagedDisplayInfo large_info =
  550. display_manager()->GetDisplayInfo(large_id);
  551. std::vector<display::ManagedDisplayInfo> display_info_list;
  552. display_info_list.push_back(small_info);
  553. display_manager()->OnNativeDisplaysChanged(display_info_list);
  554. EXPECT_EQ(small_id, WindowTreeHostManager::GetPrimaryDisplayId());
  555. EXPECT_EQ(gfx::Size(500, 200), window->bounds().size());
  556. // Reconnect the large display. The window should move back and have the old
  557. // size.
  558. display_info_list.push_back(large_info);
  559. display_manager()->OnNativeDisplaysChanged(display_info_list);
  560. EXPECT_EQ(large_id, WindowTreeHostManager::GetPrimaryDisplayId());
  561. EXPECT_EQ(gfx::Size(1500, 200), window->bounds().size());
  562. }
  563. TEST_F(PersistentWindowControllerTest, RestoreBoundsOnScreenRotation) {
  564. UpdateDisplay("800x600");
  565. display::test::DisplayManagerTestApi(display_manager())
  566. .SetFirstDisplayAsInternalDisplay();
  567. gfx::Rect bounds_in_landscape = gfx::Rect(420, 200, 200, 100);
  568. aura::Window* w1 = CreateTestWindowInShellWithBounds(bounds_in_landscape);
  569. ScreenOrientationControllerTestApi test_api(
  570. Shell::Get()->screen_orientation_controller());
  571. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  572. display::Display::RotationSource::ACTIVE);
  573. EXPECT_EQ(test_api.GetCurrentOrientation(),
  574. chromeos::OrientationType::kLandscapePrimary);
  575. EXPECT_EQ(bounds_in_landscape, w1->GetBoundsInScreen());
  576. // The window should be fully visible after rotation.
  577. base::HistogramTester histogram_tester;
  578. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  579. display::Display::RotationSource::ACTIVE);
  580. EXPECT_EQ(test_api.GetCurrentOrientation(),
  581. chromeos::OrientationType::kPortraitPrimary);
  582. gfx::Rect bounds_in_portrait = w1->GetBoundsInScreen();
  583. EXPECT_NE(bounds_in_landscape, bounds_in_portrait);
  584. EXPECT_TRUE(GetPrimaryDisplay().bounds().Contains(bounds_in_portrait));
  585. histogram_tester.ExpectTotalCount(
  586. PersistentWindowController::kNumOfWindowsRestoredOnScreenRotation, 0);
  587. // The window's bounds should be restored after rotated back to landscape
  588. // primary.
  589. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  590. display::Display::RotationSource::ACTIVE);
  591. EXPECT_EQ(test_api.GetCurrentOrientation(),
  592. chromeos::OrientationType::kLandscapePrimary);
  593. EXPECT_EQ(bounds_in_landscape, w1->GetBoundsInScreen());
  594. histogram_tester.ExpectTotalCount(
  595. PersistentWindowController::kNumOfWindowsRestoredOnScreenRotation, 1);
  596. // Update window's bounds in portrait primary.
  597. auto* window_state = WindowState::Get(w1);
  598. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  599. display::Display::RotationSource::ACTIVE);
  600. EXPECT_EQ(test_api.GetCurrentOrientation(),
  601. chromeos::OrientationType::kPortraitPrimary);
  602. EXPECT_EQ(bounds_in_portrait, w1->GetBoundsInScreen());
  603. w1->SetBounds(gfx::Rect(
  604. gfx::Point(bounds_in_portrait.x() - 100, bounds_in_portrait.y() - 100),
  605. bounds_in_portrait.size()));
  606. window_state->set_bounds_changed_by_user(true);
  607. bounds_in_portrait = w1->GetBoundsInScreen();
  608. EXPECT_FALSE(window_state->persistent_window_info_of_screen_rotation());
  609. // The window's bounds should not be restored after rotated to landscape
  610. // secondary, since the window's bounds has been changed by user.
  611. test_api.SetDisplayRotation(display::Display::ROTATE_180,
  612. display::Display::RotationSource::ACTIVE);
  613. EXPECT_EQ(test_api.GetCurrentOrientation(),
  614. chromeos::OrientationType::kLandscapeSecondary);
  615. EXPECT_NE(bounds_in_landscape, w1->GetBoundsInScreen());
  616. bounds_in_landscape = w1->GetBoundsInScreen();
  617. // The window's bounds should be the same as its bounds in portrait primary
  618. // after rotated to portrait secondary.
  619. test_api.SetDisplayRotation(display::Display::ROTATE_90,
  620. display::Display::RotationSource::ACTIVE);
  621. EXPECT_EQ(test_api.GetCurrentOrientation(),
  622. chromeos::OrientationType::kPortraitSecondary);
  623. EXPECT_EQ(bounds_in_portrait, w1->GetBoundsInScreen());
  624. // The window's bounds should be the same as its bounds in landscape secondary
  625. // after rotated to landscape primary.
  626. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  627. display::Display::RotationSource::ACTIVE);
  628. EXPECT_EQ(test_api.GetCurrentOrientation(),
  629. chromeos::OrientationType::kLandscapePrimary);
  630. EXPECT_EQ(bounds_in_landscape, w1->GetBoundsInScreen());
  631. }
  632. TEST_F(PersistentWindowControllerTest, RotationOnLockScreen) {
  633. UpdateDisplay("800x600");
  634. display::test::DisplayManagerTestApi(display_manager())
  635. .SetFirstDisplayAsInternalDisplay();
  636. const gfx::Rect bounds_in_landscape = gfx::Rect(420, 200, 200, 100);
  637. aura::Window* w1 = CreateTestWindowInShellWithBounds(bounds_in_landscape);
  638. ScreenOrientationControllerTestApi test_api(
  639. Shell::Get()->screen_orientation_controller());
  640. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  641. display::Display::RotationSource::ACTIVE);
  642. EXPECT_EQ(test_api.GetCurrentOrientation(),
  643. chromeos::OrientationType::kLandscapePrimary);
  644. EXPECT_EQ(bounds_in_landscape, w1->GetBoundsInScreen());
  645. // Rotates to portrait primary.
  646. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  647. display::Display::RotationSource::ACTIVE);
  648. // Enters locked session state and rotates the screen back to landscape
  649. // primary.
  650. GetSessionControllerClient()->SetSessionState(SessionState::LOCKED);
  651. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  652. display::Display::RotationSource::ACTIVE);
  653. // Unlocks and checks that `w1` is restored.
  654. GetSessionControllerClient()->SetSessionState(SessionState::ACTIVE);
  655. EXPECT_EQ(bounds_in_landscape, w1->GetBoundsInScreen());
  656. }
  657. TEST_F(PersistentWindowControllerTest, RotationOnDisplayReconnecting) {
  658. UpdateDisplay("500x600,500x600");
  659. display::test::DisplayManagerTestApi(display_manager())
  660. .SetFirstDisplayAsInternalDisplay();
  661. ScreenOrientationControllerTestApi test_api(
  662. Shell::Get()->screen_orientation_controller());
  663. const gfx::Rect w1_bounds_in_landscape = gfx::Rect(200, 0, 100, 200);
  664. const gfx::Rect w2_bounds_in_second_display = gfx::Rect(501, 0, 200, 100);
  665. aura::Window* w1 = CreateTestWindowInShellWithBounds(w1_bounds_in_landscape);
  666. aura::Window* w2 =
  667. CreateTestWindowInShellWithBounds(w2_bounds_in_second_display);
  668. const int64_t primary_id = WindowTreeHostManager::GetPrimaryDisplayId();
  669. const int64_t secondary_id =
  670. display::test::DisplayManagerTestApi(display_manager())
  671. .GetSecondaryDisplay()
  672. .id();
  673. display::ManagedDisplayInfo primary_info =
  674. display_manager()->GetDisplayInfo(primary_id);
  675. display::ManagedDisplayInfo secondary_info =
  676. display_manager()->GetDisplayInfo(secondary_id);
  677. // Disconnects secondary display.
  678. std::vector<display::ManagedDisplayInfo> display_info_list;
  679. display_info_list.push_back(primary_info);
  680. display_manager()->OnNativeDisplaysChanged(display_info_list);
  681. EXPECT_EQ(w1_bounds_in_landscape, w1->GetBoundsInScreen());
  682. EXPECT_EQ(gfx::Rect(1, 0, 200, 100), w2->GetBoundsInScreen());
  683. EXPECT_EQ(test_api.GetCurrentOrientation(),
  684. chromeos::OrientationType::kLandscapePrimary);
  685. test_api.SetDisplayRotation(display::Display::ROTATE_270,
  686. display::Display::RotationSource::ACTIVE);
  687. EXPECT_EQ(test_api.GetCurrentOrientation(),
  688. chromeos::OrientationType::kPortraitPrimary);
  689. // Reconnects secondary display, `w2` should be restored.
  690. display_info_list.push_back(secondary_info);
  691. display_manager()->OnNativeDisplaysChanged(display_info_list);
  692. EXPECT_EQ(w2_bounds_in_second_display, w2->GetBoundsInScreen());
  693. // Rotates the internal display back to landscape primary.
  694. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  695. display::Display::RotationSource::ACTIVE);
  696. EXPECT_EQ(w1_bounds_in_landscape, w1->GetBoundsInScreen());
  697. }
  698. TEST_F(PersistentWindowControllerTest, NoRestoreOnRotationForSnappedWindows) {
  699. UpdateDisplay("800x600");
  700. display::test::DisplayManagerTestApi(display_manager())
  701. .SetFirstDisplayAsInternalDisplay();
  702. ScreenOrientationControllerTestApi test_api(
  703. Shell::Get()->screen_orientation_controller());
  704. test_api.SetDisplayRotation(display::Display::ROTATE_0,
  705. display::Display::RotationSource::ACTIVE);
  706. EXPECT_EQ(test_api.GetCurrentOrientation(),
  707. chromeos::OrientationType::kLandscapePrimary);
  708. aura::Window* w1 =
  709. CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 200, 200));
  710. auto* split_view_controller =
  711. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  712. // Snap the unique window in clamshell mode will not enter split view mode.
  713. WindowSnapWMEvent wm_left_snap_event(WM_EVENT_SNAP_PRIMARY);
  714. auto* window_state = WindowState::Get(w1);
  715. window_state->OnWMEvent(&wm_left_snap_event);
  716. EXPECT_FALSE(split_view_controller->InSplitViewMode());
  717. EXPECT_TRUE(window_state->IsSnapped());
  718. EXPECT_EQ(chromeos::WindowStateType::kPrimarySnapped,
  719. window_state->GetStateType());
  720. const gfx::Rect bounds_in_landscape_primary = w1->GetBoundsInScreen();
  721. EXPECT_EQ(0, bounds_in_landscape_primary.x());
  722. // Snapped window should not have persistent window info on screen rotation
  723. // so its bounds will not be restored.
  724. test_api.SetDisplayRotation(display::Display::ROTATE_90,
  725. display::Display::RotationSource::ACTIVE);
  726. EXPECT_EQ(test_api.GetCurrentOrientation(),
  727. chromeos::OrientationType::kPortraitSecondary);
  728. EXPECT_FALSE(window_state->persistent_window_info_of_screen_rotation());
  729. // Snapped window's bounds should not be restored on screen rotation. The
  730. // primary snapped window in landscape primary should still be primary snapped
  731. // after rotated to landscape secondary, and be kept at the right side of the
  732. // screen.
  733. test_api.SetDisplayRotation(display::Display::ROTATE_180,
  734. display::Display::RotationSource::ACTIVE);
  735. EXPECT_EQ(test_api.GetCurrentOrientation(),
  736. chromeos::OrientationType::kLandscapeSecondary);
  737. EXPECT_FALSE(window_state->persistent_window_info_of_screen_rotation());
  738. EXPECT_TRUE(window_state->IsSnapped());
  739. EXPECT_EQ(chromeos::WindowStateType::kPrimarySnapped,
  740. window_state->GetStateType());
  741. const gfx::Rect bounds_in_landscape_secondary = w1->GetBoundsInScreen();
  742. EXPECT_NE(bounds_in_landscape_primary, bounds_in_landscape_secondary);
  743. EXPECT_NE(0, bounds_in_landscape_secondary.x());
  744. EXPECT_EQ(
  745. bounds_in_landscape_secondary.right(),
  746. screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(w1)
  747. .right());
  748. }
  749. } // namespace ash