fullscreen_controller_unittest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. // Copyright 2022 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 "components/remote_cocoa/app_shim/native_widget_ns_window_fullscreen_controller.h"
  5. #include "base/test/task_environment.h"
  6. #include "testing/gmock/include/gmock/gmock.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace remote_cocoa {
  9. namespace test {
  10. using testing::_;
  11. using testing::Invoke;
  12. using testing::Return;
  13. class MockClient : public NativeWidgetNSWindowFullscreenController::Client {
  14. public:
  15. MOCK_METHOD1(FullscreenControllerTransitionStart, void(bool));
  16. MOCK_METHOD1(FullscreenControllerTransitionComplete, void(bool));
  17. MOCK_METHOD3(FullscreenControllerSetFrame,
  18. void(const gfx::Rect&,
  19. bool animate,
  20. base::OnceCallback<void()> animation_complete));
  21. MOCK_METHOD0(FullscreenControllerToggleFullscreen, void());
  22. MOCK_METHOD0(FullscreenControllerCloseWindow, void());
  23. MOCK_CONST_METHOD0(FullscreenControllerGetDisplayId, int64_t());
  24. MOCK_CONST_METHOD1(FullscreenControllerGetFrameForDisplay,
  25. gfx::Rect(int64_t display_id));
  26. MOCK_CONST_METHOD0(FullscreenControllerGetFrame, gfx::Rect());
  27. };
  28. class MacFullscreenControllerTest : public testing::Test {
  29. public:
  30. void SetUp() override {
  31. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen()).Times(0);
  32. EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(_, _, _)).Times(0);
  33. EXPECT_CALL(mock_client_, FullscreenControllerCloseWindow()).Times(0);
  34. }
  35. protected:
  36. const gfx::Rect kWindowRect{1, 2, 3, 4};
  37. const int64_t kDisplay0Id = 0;
  38. const int64_t kDisplay1Id = 1;
  39. const gfx::Rect kDisplay0Frame{9, 10, 11, 12};
  40. const gfx::Rect kDisplay1Frame{13, 14, 15, 16};
  41. MockClient mock_client_;
  42. NativeWidgetNSWindowFullscreenController controller_{&mock_client_};
  43. base::test::SingleThreadTaskEnvironment task_environment_;
  44. };
  45. // Fake implementation of FullscreenControllerSetFrame
  46. // which executes the given callback immediately.
  47. void FullscreenControllerSetFrameFake(const gfx::Rect&,
  48. bool,
  49. base::OnceCallback<void()> callback) {
  50. std::move(callback).Run();
  51. }
  52. // Simple enter-and-exit fullscreen via the green traffic light button.
  53. TEST_F(MacFullscreenControllerTest, SimpleUserInitiated) {
  54. // Enter fullscreen the way that clicking the green traffic light does it.
  55. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  56. .Times(1)
  57. .WillOnce(Return(kWindowRect));
  58. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  59. controller_.OnWindowWillEnterFullscreen();
  60. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  61. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  62. // The controller should do nothing, and wait until it receives
  63. // OnWindowDidEnterFullscreen.
  64. task_environment_.RunUntilIdle();
  65. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  66. // Calling EnterFullscreen inside the transition will do nothing.
  67. controller_.EnterFullscreen(display::kInvalidDisplayId);
  68. task_environment_.RunUntilIdle();
  69. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  70. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  71. // Complete the transition.
  72. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  73. .Times(1);
  74. controller_.OnWindowDidEnterFullscreen();
  75. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  76. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  77. // Calling EnterFullscreen while fullscreen should do nothing.
  78. controller_.EnterFullscreen(display::kInvalidDisplayId);
  79. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  80. task_environment_.RunUntilIdle();
  81. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  82. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  83. // Calling EnterFullscreen specifying the display that we are currently on
  84. // will also be a no-op.
  85. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  86. .WillOnce(Return(kDisplay0Id));
  87. controller_.EnterFullscreen(kDisplay0Id);
  88. task_environment_.RunUntilIdle();
  89. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  90. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  91. // Exit fullscreen via the green traffic light.
  92. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  93. .Times(1);
  94. controller_.OnWindowWillExitFullscreen();
  95. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  96. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  97. // Calling ExitFullscreen inside the transition will do nothing.
  98. controller_.ExitFullscreen();
  99. task_environment_.RunUntilIdle();
  100. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  101. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  102. // Complete the transition.
  103. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  104. .Times(1);
  105. controller_.OnWindowDidExitFullscreen();
  106. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  107. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  108. task_environment_.RunUntilIdle();
  109. }
  110. // Simple enter-and-exit fullscreen programmatically.
  111. TEST_F(MacFullscreenControllerTest, SimpleProgrammatic) {
  112. // Enter fullscreen.
  113. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  114. .Times(1)
  115. .WillOnce(Return(kWindowRect));
  116. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  117. controller_.EnterFullscreen(display::kInvalidDisplayId);
  118. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  119. // The call to ToggleFullscreen is sent via a posted task, so it shouldn't
  120. // happen until after the run loop is pumped. The function
  121. // OnWindowWillEnterFullscreen is called from within ToggleFullscreen.
  122. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  123. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  124. OnWindowWillEnterFullscreen));
  125. task_environment_.RunUntilIdle();
  126. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  127. // Complete the transition.
  128. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  129. .Times(1);
  130. controller_.OnWindowDidEnterFullscreen();
  131. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  132. // Exit fullscreen.
  133. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  134. .Times(1);
  135. controller_.ExitFullscreen();
  136. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  137. // Make ToggleFullscreen happen, and invoke OnWindowWillExitFullscreen.
  138. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  139. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  140. OnWindowWillExitFullscreen));
  141. task_environment_.RunUntilIdle();
  142. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  143. // Complete the transition.
  144. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  145. .Times(1);
  146. controller_.OnWindowDidExitFullscreen();
  147. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  148. task_environment_.RunUntilIdle();
  149. }
  150. // A transition that fails to enter fullscreen.
  151. TEST_F(MacFullscreenControllerTest, FailEnterFullscreenSimple) {
  152. // Enter fullscreen.
  153. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  154. .Times(1)
  155. .WillOnce(Return(kWindowRect));
  156. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  157. controller_.EnterFullscreen(display::kInvalidDisplayId);
  158. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  159. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  160. OnWindowWillEnterFullscreen));
  161. task_environment_.RunUntilIdle();
  162. // Fail the transition.
  163. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  164. .Times(1);
  165. controller_.OnWindowDidExitFullscreen();
  166. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  167. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  168. task_environment_.RunUntilIdle();
  169. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  170. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  171. }
  172. // A transition that fails to exit fullscreen.
  173. TEST_F(MacFullscreenControllerTest, FailExitFullscreen) {
  174. // Enter fullscreen.
  175. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  176. .Times(1)
  177. .WillOnce(Return(kWindowRect));
  178. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  179. controller_.EnterFullscreen(display::kInvalidDisplayId);
  180. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  181. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  182. OnWindowWillEnterFullscreen));
  183. task_environment_.RunUntilIdle();
  184. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  185. .Times(1);
  186. controller_.OnWindowDidEnterFullscreen();
  187. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  188. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  189. // Start to exit fullscreen, through OnWindowWillExitFullscreen.
  190. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  191. .Times(1);
  192. controller_.ExitFullscreen();
  193. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  194. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  195. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  196. OnWindowWillExitFullscreen));
  197. task_environment_.RunUntilIdle();
  198. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  199. // Fail the transition.
  200. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  201. .Times(1);
  202. controller_.OnWindowDidEnterFullscreen();
  203. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  204. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  205. task_environment_.RunUntilIdle();
  206. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  207. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  208. }
  209. // A simple cross-screen transition.
  210. TEST_F(MacFullscreenControllerTest, SimpleCrossScreen) {
  211. // Enter fullscreen to display 0, from display 0.
  212. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  213. .Times(1)
  214. .WillOnce(Return(kWindowRect));
  215. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  216. controller_.EnterFullscreen(kDisplay1Id);
  217. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  218. // This will trigger a call to MoveToTargetDisplayThenToggleFullscreen, even
  219. // though we are not actually moving displays. It will also then post a task
  220. // To ToggleFullscreen (because RunUntilIdle will pick up that posted task).
  221. EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id))
  222. .Times(1)
  223. .WillOnce(Return(kDisplay1Frame));
  224. EXPECT_CALL(mock_client_,
  225. FullscreenControllerSetFrame(kDisplay1Frame, true, _))
  226. .WillOnce(FullscreenControllerSetFrameFake);
  227. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  228. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  229. OnWindowWillEnterFullscreen));
  230. task_environment_.RunUntilIdle();
  231. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  232. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  233. // Complete the transition to fullscreen on the new display.
  234. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  235. .Times(1);
  236. controller_.OnWindowDidEnterFullscreen();
  237. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  238. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  239. // Re-entering fullscreen on our current display should be a no-op.
  240. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  241. .WillOnce(Return(kDisplay1Id));
  242. controller_.EnterFullscreen(kDisplay1Id);
  243. task_environment_.RunUntilIdle();
  244. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  245. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  246. // Exit fullscreen. This will post a task to restore bounds.
  247. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  248. .Times(1);
  249. controller_.ExitFullscreen();
  250. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  251. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  252. OnWindowWillExitFullscreen));
  253. task_environment_.RunUntilIdle();
  254. controller_.OnWindowDidExitFullscreen();
  255. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  256. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  257. // Let the run loop run, it will restore the bounds.
  258. EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _))
  259. .WillOnce(FullscreenControllerSetFrameFake);
  260. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  261. .Times(1);
  262. task_environment_.RunUntilIdle();
  263. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  264. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  265. }
  266. // A cross-screen transition after having entered fullscreen.
  267. TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreen) {
  268. // Enter fullscreen the way that clicking the green traffic light does it.
  269. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  270. .Times(1)
  271. .WillOnce(Return(kWindowRect));
  272. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  273. controller_.OnWindowWillEnterFullscreen();
  274. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  275. .Times(1);
  276. controller_.OnWindowDidEnterFullscreen();
  277. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  278. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  279. // Enter fullscreen on a different display.
  280. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  281. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  282. .WillRepeatedly(Return(kDisplay0Id));
  283. controller_.EnterFullscreen(kDisplay1Id);
  284. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  285. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  286. // Execute the task posted to ToggleFullscreen.
  287. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  288. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  289. OnWindowWillExitFullscreen));
  290. task_environment_.RunUntilIdle();
  291. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  292. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  293. // Complete the transition to windowed. This will post a task to move to the
  294. // target display's frame.
  295. EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id))
  296. .Times(1)
  297. .WillOnce(Return(kDisplay1Frame));
  298. controller_.OnWindowDidExitFullscreen();
  299. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  300. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  301. // Execute the posted task to set the new frame. This will also re-toggle
  302. // fullscreen in the RunUntilIdle.
  303. EXPECT_CALL(mock_client_,
  304. FullscreenControllerSetFrame(kDisplay1Frame, true, _))
  305. .WillOnce(FullscreenControllerSetFrameFake);
  306. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  307. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  308. OnWindowWillEnterFullscreen));
  309. task_environment_.RunUntilIdle();
  310. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  311. // Complete the transition.
  312. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  313. .Times(1);
  314. controller_.OnWindowDidEnterFullscreen();
  315. task_environment_.RunUntilIdle();
  316. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  317. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  318. // Exit fullscreen. This will restore bounds.
  319. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  320. .Times(1);
  321. controller_.ExitFullscreen();
  322. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  323. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  324. OnWindowWillExitFullscreen));
  325. task_environment_.RunUntilIdle();
  326. controller_.OnWindowDidExitFullscreen();
  327. EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _))
  328. .WillOnce(FullscreenControllerSetFrameFake);
  329. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  330. .Times(1);
  331. task_environment_.RunUntilIdle();
  332. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  333. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  334. }
  335. // Fail a cross-screen transition when exiting fullscreen.
  336. TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreenFailExit) {
  337. // Enter fullscreen the way that clicking the green traffic light does it.
  338. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  339. .Times(1)
  340. .WillOnce(Return(kWindowRect));
  341. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  342. controller_.OnWindowWillEnterFullscreen();
  343. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  344. .Times(1);
  345. controller_.OnWindowDidEnterFullscreen();
  346. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  347. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  348. // Attempt to enter fullscreen on a different display. Get as far as toggling
  349. // fullscreen to get back to windowed mode.
  350. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  351. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  352. .WillRepeatedly(Return(kDisplay0Id));
  353. controller_.EnterFullscreen(kDisplay1Id);
  354. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  355. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  356. OnWindowWillExitFullscreen));
  357. task_environment_.RunUntilIdle();
  358. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  359. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  360. // Fail the transition back to windowed. This should just leave us as being
  361. // fullscreen. It will issue the TransitionComplete notification indicating
  362. // that the transition is over, and that we're in fullscreen mode (no mention
  363. // of which display).
  364. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  365. .Times(1);
  366. controller_.OnWindowDidEnterFullscreen();
  367. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  368. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  369. // No further tasks should run.
  370. task_environment_.RunUntilIdle();
  371. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  372. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  373. }
  374. // Fail a cross-screen transition when entering fullscreen.
  375. TEST_F(MacFullscreenControllerTest, CrossScreenFromFullscreenFailEnter) {
  376. // Enter fullscreen the way that clicking the green traffic light does it.
  377. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  378. .Times(1)
  379. .WillOnce(Return(kWindowRect));
  380. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  381. controller_.OnWindowWillEnterFullscreen();
  382. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  383. .Times(1);
  384. controller_.OnWindowDidEnterFullscreen();
  385. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  386. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  387. // Enter fullscreen on a different display. Get as far as toggling fullscreen
  388. // to get back to windowed mode, moving the window, and then toggling
  389. // fullscreen on the new display.
  390. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  391. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  392. .WillRepeatedly(Return(kDisplay0Id));
  393. controller_.EnterFullscreen(kDisplay1Id);
  394. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  395. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  396. OnWindowWillExitFullscreen));
  397. task_environment_.RunUntilIdle();
  398. EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id))
  399. .Times(1)
  400. .WillOnce(Return(kDisplay1Frame));
  401. controller_.OnWindowDidExitFullscreen();
  402. EXPECT_CALL(mock_client_,
  403. FullscreenControllerSetFrame(kDisplay1Frame, true, _))
  404. .WillOnce(FullscreenControllerSetFrameFake);
  405. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  406. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  407. OnWindowWillEnterFullscreen));
  408. task_environment_.RunUntilIdle();
  409. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  410. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  411. // Fail the transition to fullscreen mode. This will cause us to post tasks
  412. // to stay in windowed mode.
  413. controller_.OnWindowDidExitFullscreen();
  414. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  415. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  416. // This will cause us to restore the window's original frame, and then declare
  417. // the transition complete, with the final state after transition as being
  418. // windowed.
  419. EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _))
  420. .WillOnce(FullscreenControllerSetFrameFake);
  421. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  422. .Times(1);
  423. task_environment_.RunUntilIdle();
  424. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  425. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  426. }
  427. // Be instructed to exit fullscreen while entering fullscreen.
  428. TEST_F(MacFullscreenControllerTest, ExitWhileEntering) {
  429. // Enter fullscreen the way that clicking the green traffic light does it.
  430. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  431. .Times(1)
  432. .WillOnce(Return(kWindowRect));
  433. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  434. controller_.OnWindowWillEnterFullscreen();
  435. task_environment_.RunUntilIdle();
  436. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  437. // Call ExitFullscreen inside the transition.
  438. controller_.ExitFullscreen();
  439. task_environment_.RunUntilIdle();
  440. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  441. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  442. // Complete the transition to fullscreen. This will report that it is still
  443. // in transition to windowed.
  444. controller_.OnWindowDidEnterFullscreen();
  445. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  446. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  447. // The above call will have posted a ToggleFullscreen task.
  448. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  449. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  450. OnWindowWillExitFullscreen));
  451. task_environment_.RunUntilIdle();
  452. // Complete the transition to windowed mode.
  453. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  454. .Times(1);
  455. controller_.OnWindowDidExitFullscreen();
  456. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  457. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  458. // Nothing more should happen.
  459. task_environment_.RunUntilIdle();
  460. }
  461. // Be instructed to enter fullscreen while exiting fullscreen.
  462. TEST_F(MacFullscreenControllerTest, EnterWhileExiting) {
  463. // Enter fullscreen the way that clicking the green traffic light does it.
  464. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  465. .Times(1)
  466. .WillOnce(Return(kWindowRect));
  467. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  468. controller_.OnWindowWillEnterFullscreen();
  469. task_environment_.RunUntilIdle();
  470. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  471. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  472. .Times(1);
  473. controller_.OnWindowDidEnterFullscreen();
  474. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  475. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  476. // Exit fullscreen.
  477. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  478. .Times(1);
  479. controller_.OnWindowWillExitFullscreen();
  480. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  481. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  482. // Call EnterFullscreen inside the transition.
  483. controller_.EnterFullscreen(display::kInvalidDisplayId);
  484. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  485. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  486. // Complete the transition to windowed mode. This will report that it is
  487. // still in transition to fullscreen.
  488. controller_.OnWindowDidExitFullscreen();
  489. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  490. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  491. // The above call will have posted a ToggleFullscreen task.
  492. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  493. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  494. OnWindowWillEnterFullscreen));
  495. task_environment_.RunUntilIdle();
  496. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  497. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  498. // Complete the transition to fullscreen mode.
  499. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  500. .Times(1);
  501. controller_.OnWindowDidEnterFullscreen();
  502. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  503. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  504. // Nothing more should happen.
  505. task_environment_.RunUntilIdle();
  506. }
  507. // Be instructed to enter fullscreen on a different screen, while exiting
  508. // fullscreen.
  509. TEST_F(MacFullscreenControllerTest, EnterCrossScreenWhileExiting) {
  510. // Enter fullscreen the way that clicking the green traffic light does it.
  511. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  512. .Times(1)
  513. .WillOnce(Return(kWindowRect));
  514. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  515. controller_.OnWindowWillEnterFullscreen();
  516. task_environment_.RunUntilIdle();
  517. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  518. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  519. .Times(1);
  520. controller_.OnWindowDidEnterFullscreen();
  521. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  522. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  523. // Exit fullscreen.
  524. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  525. .Times(1);
  526. controller_.OnWindowWillExitFullscreen();
  527. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  528. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  529. // Call EnterFullscreen inside the transition.
  530. controller_.EnterFullscreen(kDisplay1Id);
  531. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  532. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  533. // Complete the transition to windowed mode. This will report that it is
  534. // still in transition to fullscreen.
  535. controller_.OnWindowDidExitFullscreen();
  536. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  537. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  538. // The above call will have posted a MoveToTargetDisplayThenToggleFullscreen
  539. // task, which will then post a ToggleFullscreen task.
  540. EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id))
  541. .Times(1)
  542. .WillOnce(Return(kDisplay1Frame));
  543. EXPECT_CALL(mock_client_,
  544. FullscreenControllerSetFrame(kDisplay1Frame, true, _))
  545. .WillOnce(FullscreenControllerSetFrameFake);
  546. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  547. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  548. OnWindowWillEnterFullscreen));
  549. task_environment_.RunUntilIdle();
  550. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  551. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  552. // Complete the transition to fullscreen mode.
  553. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  554. .Times(1);
  555. controller_.OnWindowDidEnterFullscreen();
  556. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  557. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  558. // Nothing more should happen.
  559. task_environment_.RunUntilIdle();
  560. }
  561. // Be instructed to enter fullscreen on a different screen, while entering
  562. // fullscreen.
  563. TEST_F(MacFullscreenControllerTest, EnterCrossScreenWhileEntering) {
  564. // Enter fullscreen the way that clicking the green traffic light does it.
  565. EXPECT_CALL(mock_client_, FullscreenControllerGetFrame())
  566. .Times(1)
  567. .WillOnce(Return(kWindowRect));
  568. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(true)).Times(1);
  569. controller_.OnWindowWillEnterFullscreen();
  570. task_environment_.RunUntilIdle();
  571. // Call EnterFullscreen inside the transition.
  572. controller_.EnterFullscreen(kDisplay1Id);
  573. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  574. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  575. // Complete the original fullscreen transition. This will check to see if
  576. // the display we are on is the display we wanted to be on. Seeing that it
  577. // isn't it will post a task to exit fullscreen to move to the correct
  578. // display.
  579. EXPECT_CALL(mock_client_, FullscreenControllerGetDisplayId())
  580. .WillOnce(Return(kDisplay0Id));
  581. controller_.OnWindowDidEnterFullscreen();
  582. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  583. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  584. // The above will have posted a task to ToggleFullscreen.
  585. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  586. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  587. OnWindowWillExitFullscreen));
  588. task_environment_.RunUntilIdle();
  589. // Complete the transition to windowed mode. This will then move the window
  590. // and toggle fullscreen.
  591. controller_.OnWindowDidExitFullscreen();
  592. EXPECT_CALL(mock_client_, FullscreenControllerGetFrameForDisplay(kDisplay1Id))
  593. .Times(1)
  594. .WillOnce(Return(kDisplay1Frame));
  595. EXPECT_CALL(mock_client_,
  596. FullscreenControllerSetFrame(kDisplay1Frame, true, _))
  597. .WillOnce(FullscreenControllerSetFrameFake);
  598. EXPECT_CALL(mock_client_, FullscreenControllerToggleFullscreen())
  599. .WillOnce(Invoke(&controller_, &NativeWidgetNSWindowFullscreenController::
  600. OnWindowWillEnterFullscreen));
  601. task_environment_.RunUntilIdle();
  602. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  603. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  604. // Complete the transition to fullscreen.
  605. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(true))
  606. .Times(1);
  607. controller_.OnWindowDidEnterFullscreen();
  608. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  609. EXPECT_TRUE(controller_.GetTargetFullscreenState());
  610. // Exit fullscreen.
  611. EXPECT_CALL(mock_client_, FullscreenControllerTransitionStart(false))
  612. .Times(1);
  613. controller_.OnWindowWillExitFullscreen();
  614. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  615. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  616. // Complete the transition to windowed mode. The frame frame should be reset.
  617. controller_.OnWindowDidExitFullscreen();
  618. EXPECT_TRUE(controller_.IsInFullscreenTransition());
  619. EXPECT_CALL(mock_client_, FullscreenControllerSetFrame(kWindowRect, true, _))
  620. .WillOnce(FullscreenControllerSetFrameFake);
  621. EXPECT_CALL(mock_client_, FullscreenControllerTransitionComplete(false))
  622. .Times(1);
  623. task_environment_.RunUntilIdle();
  624. EXPECT_FALSE(controller_.IsInFullscreenTransition());
  625. EXPECT_FALSE(controller_.GetTargetFullscreenState());
  626. }
  627. } // namespace test
  628. } // namespace remote_cocoa