hotseat_widget_unittest.cc 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766
  1. // Copyright (c) 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <tuple>
  6. #include <vector>
  7. #include "ash/app_list/app_list_controller_impl.h"
  8. #include "ash/app_list/test/app_list_test_helper.h"
  9. #include "ash/app_list/views/app_list_view.h"
  10. #include "ash/assistant/assistant_controller_impl.h"
  11. #include "ash/constants/ash_features.h"
  12. #include "ash/focus_cycler.h"
  13. #include "ash/public/cpp/assistant/controller/assistant_ui_controller.h"
  14. #include "ash/public/cpp/test/assistant_test_api.h"
  15. #include "ash/public/cpp/test/shell_test_api.h"
  16. #include "ash/shelf/drag_window_from_shelf_controller_test_api.h"
  17. #include "ash/shelf/home_button.h"
  18. #include "ash/shelf/hotseat_widget.h"
  19. #include "ash/shelf/scrollable_shelf_view.h"
  20. #include "ash/shelf/shelf.h"
  21. #include "ash/shelf/shelf_app_button.h"
  22. #include "ash/shelf/shelf_controller.h"
  23. #include "ash/shelf/shelf_focus_cycler.h"
  24. #include "ash/shelf/shelf_layout_manager.h"
  25. #include "ash/shelf/shelf_metrics.h"
  26. #include "ash/shelf/shelf_navigation_widget.h"
  27. #include "ash/shelf/shelf_test_util.h"
  28. #include "ash/shelf/shelf_view.h"
  29. #include "ash/shelf/shelf_view_test_api.h"
  30. #include "ash/shelf/test/hotseat_state_watcher.h"
  31. #include "ash/shelf/test/shelf_layout_manager_test_base.h"
  32. #include "ash/shelf/test/widget_animation_smoothness_inspector.h"
  33. #include "ash/shell.h"
  34. #include "ash/system/ime_menu/ime_menu_tray.h"
  35. #include "ash/system/overview/overview_button_tray.h"
  36. #include "ash/system/status_area_widget.h"
  37. #include "ash/system/unified/unified_system_tray.h"
  38. #include "ash/test/ash_test_base.h"
  39. #include "ash/test/layer_animation_verifier.h"
  40. #include "ash/wm/overview/overview_controller.h"
  41. #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
  42. #include "ash/wm/window_state.h"
  43. #include "ash/wm/wm_event.h"
  44. #include "ash/wm/work_area_insets.h"
  45. #include "base/test/icu_test_util.h"
  46. #include "base/test/metrics/histogram_tester.h"
  47. #include "base/test/scoped_feature_list.h"
  48. #include "chromeos/ash/services/assistant/public/cpp/assistant_service.h"
  49. #include "testing/gtest/include/gtest/gtest.h"
  50. #include "ui/aura/client/aura_constants.h"
  51. #include "ui/compositor/presentation_time_recorder.h"
  52. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  53. #include "ui/compositor/scoped_layer_animation_settings.h"
  54. #include "ui/events/gesture_detection/gesture_configuration.h"
  55. #include "ui/events/test/event_generator.h"
  56. #include "ui/views/test/widget_animation_waiter.h"
  57. #include "ui/wm/core/window_util.h"
  58. namespace ash {
  59. namespace {
  60. ShelfWidget* GetShelfWidget() {
  61. return AshTestBase::GetPrimaryShelf()->shelf_widget();
  62. }
  63. ShelfLayoutManager* GetShelfLayoutManager() {
  64. return AshTestBase::GetPrimaryShelf()->shelf_layout_manager();
  65. }
  66. } // namespace
  67. class HotseatWidgetTest
  68. : public ShelfLayoutManagerTestBase,
  69. public testing::WithParamInterface<
  70. std::tuple<ShelfAutoHideBehavior,
  71. /*is_assistant_enabled*/ bool,
  72. /*navigation_buttons_shown_in_tablet_mode*/ bool>> {
  73. public:
  74. HotseatWidgetTest()
  75. : ShelfLayoutManagerTestBase(
  76. base::test::TaskEnvironment::TimeSource::MOCK_TIME),
  77. shelf_auto_hide_behavior_(std::get<0>(GetParam())),
  78. is_assistant_enabled_(std::get<1>(GetParam())),
  79. navigation_buttons_shown_in_tablet_mode_(std::get<2>(GetParam())) {
  80. if (is_assistant_enabled_)
  81. assistant_test_api_ = AssistantTestApi::Create();
  82. std::vector<base::Feature> enabled_features;
  83. std::vector<base::Feature> disabled_features;
  84. if (navigation_buttons_shown_in_tablet_mode_) {
  85. disabled_features.push_back(features::kHideShelfControlsInTabletMode);
  86. } else {
  87. enabled_features.push_back(features::kHideShelfControlsInTabletMode);
  88. }
  89. enabled_features.push_back(features::kShelfPalmRejectionSwipeOffset);
  90. scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
  91. }
  92. // testing::Test:
  93. void SetUp() override {
  94. ShelfLayoutManagerTestBase::SetUp();
  95. if (is_assistant_enabled_) {
  96. assistant_test_api_->SetAssistantEnabled(true);
  97. assistant_test_api_->GetAssistantState()->NotifyFeatureAllowed(
  98. assistant::AssistantAllowedState::ALLOWED);
  99. assistant_test_api_->GetAssistantState()->NotifyStatusChanged(
  100. assistant::AssistantStatus::READY);
  101. assistant_test_api_->WaitUntilIdle();
  102. }
  103. }
  104. void TearDown() override {
  105. // Some tests may override this value, make sure it's reset.
  106. ui::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
  107. false);
  108. ShelfLayoutManagerTestBase::TearDown();
  109. }
  110. ShelfAutoHideBehavior shelf_auto_hide_behavior() const {
  111. return shelf_auto_hide_behavior_;
  112. }
  113. bool is_assistant_enabled() const { return is_assistant_enabled_; }
  114. bool navigation_buttons_shown_in_tablet_mode() const {
  115. return navigation_buttons_shown_in_tablet_mode_;
  116. }
  117. AssistantTestApi* assistant_test_api() { return assistant_test_api_.get(); }
  118. void ShowShelfAndActivateAssistant() {
  119. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  120. SwipeUpOnShelf();
  121. // If the launcher button is not expected to be shown, show the assistant UI
  122. // directly; otherwise, simulate the long press on the home button,
  123. if (!navigation_buttons_shown_in_tablet_mode_ &&
  124. Shell::Get()->tablet_mode_controller()->InTabletMode()) {
  125. AssistantUiController::Get()->ShowUi(
  126. assistant::AssistantEntryPoint::kLongPressLauncher);
  127. return;
  128. }
  129. views::View* home_button =
  130. GetPrimaryShelf()->navigation_widget()->GetHomeButton();
  131. auto center_point = home_button->GetBoundsInScreen().CenterPoint();
  132. GetEventGenerator()->set_current_screen_location(center_point);
  133. GetEventGenerator()->PressTouch();
  134. GetAppListTestHelper()->WaitUntilIdle();
  135. // Advance clock to make sure long press gesture is triggered.
  136. task_environment()->AdvanceClock(base::Seconds(5));
  137. GetAppListTestHelper()->WaitUntilIdle();
  138. GetEventGenerator()->ReleaseTouch();
  139. GetAppListTestHelper()->WaitUntilIdle();
  140. }
  141. void ShowShelfAndGoHome() {
  142. // If the launcher button is not expected to be shown, go home directly;
  143. // otherwise, simulate tap on the home button,
  144. if (!navigation_buttons_shown_in_tablet_mode_ &&
  145. Shell::Get()->tablet_mode_controller()->InTabletMode()) {
  146. Shell::Get()->app_list_controller()->GoHome(GetPrimaryDisplay().id());
  147. return;
  148. }
  149. // Ensure the shelf, and the home button, are visible.
  150. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  151. SwipeUpOnShelf();
  152. views::View* home_button =
  153. GetPrimaryShelf()->navigation_widget()->GetHomeButton();
  154. GetEventGenerator()->GestureTapAt(
  155. home_button->GetBoundsInScreen().CenterPoint());
  156. }
  157. void StartOverview() {
  158. ASSERT_FALSE(Shell::Get()->overview_controller()->InOverviewSession());
  159. // If the overview button is not expected to be shown, start overview
  160. // directly; otherwise, simulate tap on the overview button, which should
  161. // toggle overview.
  162. if (!navigation_buttons_shown_in_tablet_mode_ &&
  163. Shell::Get()->tablet_mode_controller()->InTabletMode()) {
  164. EnterOverview();
  165. return;
  166. }
  167. const gfx::Point overview_button_center = GetPrimaryShelf()
  168. ->status_area_widget()
  169. ->overview_button_tray()
  170. ->GetBoundsInScreen()
  171. .CenterPoint();
  172. GetEventGenerator()->GestureTapAt(overview_button_center);
  173. }
  174. void EndOverview() {
  175. ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
  176. // If the overview button is not expected to be shown, end overview
  177. // directly; otherwise, simulate tap on the overview button, which should
  178. // toggle overview.
  179. if (!navigation_buttons_shown_in_tablet_mode_ &&
  180. Shell::Get()->tablet_mode_controller()->InTabletMode()) {
  181. ExitOverview();
  182. return;
  183. }
  184. const gfx::Point overview_button_center = GetPrimaryShelf()
  185. ->status_area_widget()
  186. ->overview_button_tray()
  187. ->GetBoundsInScreen()
  188. .CenterPoint();
  189. GetEventGenerator()->GestureTapAt(overview_button_center);
  190. }
  191. private:
  192. const ShelfAutoHideBehavior shelf_auto_hide_behavior_;
  193. const bool is_assistant_enabled_;
  194. const bool navigation_buttons_shown_in_tablet_mode_;
  195. std::unique_ptr<AssistantTestApi> assistant_test_api_;
  196. base::test::ScopedFeatureList scoped_feature_list_;
  197. };
  198. // Counts the number of times the work area changes.
  199. class DisplayWorkAreaChangeCounter : public display::DisplayObserver {
  200. public:
  201. DisplayWorkAreaChangeCounter() {
  202. Shell::Get()->display_manager()->AddObserver(this);
  203. }
  204. DisplayWorkAreaChangeCounter(const DisplayWorkAreaChangeCounter&) = delete;
  205. DisplayWorkAreaChangeCounter& operator=(const DisplayWorkAreaChangeCounter&) =
  206. delete;
  207. ~DisplayWorkAreaChangeCounter() override {
  208. Shell::Get()->display_manager()->RemoveObserver(this);
  209. }
  210. void OnDisplayMetricsChanged(const display::Display& display,
  211. uint32_t metrics) override {
  212. if (metrics & display::DisplayObserver::DISPLAY_METRIC_WORK_AREA)
  213. work_area_change_count_++;
  214. }
  215. int count() const { return work_area_change_count_; }
  216. private:
  217. int work_area_change_count_ = 0;
  218. };
  219. // Watches the shelf for state changes.
  220. class ShelfStateWatcher : public ShelfObserver {
  221. public:
  222. ShelfStateWatcher() { AshTestBase::GetPrimaryShelf()->AddObserver(this); }
  223. ~ShelfStateWatcher() override {
  224. AshTestBase::GetPrimaryShelf()->RemoveObserver(this);
  225. }
  226. void WillChangeVisibilityState(ShelfVisibilityState new_state) override {
  227. state_change_count_++;
  228. }
  229. int state_change_count() const { return state_change_count_; }
  230. private:
  231. int state_change_count_ = 0;
  232. };
  233. // Watches the Hotseat transition animation states.
  234. class HotseatTransitionAnimationObserver
  235. : public HotseatTransitionAnimator::Observer {
  236. public:
  237. explicit HotseatTransitionAnimationObserver(
  238. HotseatTransitionAnimator* hotseat_transition_animator)
  239. : hotseat_transition_animator_(hotseat_transition_animator) {
  240. hotseat_transition_animator_->AddObserver(this);
  241. }
  242. ~HotseatTransitionAnimationObserver() override {
  243. hotseat_transition_animator_->RemoveObserver(this);
  244. }
  245. // HotseatTransitionAnimtor::Observer:
  246. void OnHotseatTransitionAnimationWillStart(HotseatState from_state,
  247. HotseatState to_start) override {
  248. ++observer_counts_.started;
  249. }
  250. void OnHotseatTransitionAnimationEnded(HotseatState from_state,
  251. HotseatState to_start) override {
  252. ++observer_counts_.ended;
  253. if (run_loop_)
  254. run_loop_->Quit();
  255. }
  256. void OnHotseatTransitionAnimationAborted() override {
  257. ++observer_counts_.aborted;
  258. }
  259. void Wait() {
  260. run_loop_ = std::make_unique<base::RunLoop>();
  261. run_loop_->Run();
  262. }
  263. void Reset() {
  264. if (run_loop_)
  265. run_loop_->Quit();
  266. observer_counts_ = {0};
  267. }
  268. // Checks that the started and ending/aborting methods have fired the same
  269. // amount of times.
  270. bool ObserverCountsEqual() const {
  271. return observer_counts_.started ==
  272. (observer_counts_.ended + observer_counts_.aborted);
  273. }
  274. int AnimationAbortedCalls() const { return observer_counts_.aborted; }
  275. private:
  276. // Struct which keeps track of the counts of the Observer method has fired.
  277. // These are used to verify that started calls = ended calls + aborted calls.
  278. struct ObserverCounts {
  279. int started;
  280. int ended;
  281. int aborted;
  282. } observer_counts_ = {0};
  283. std::unique_ptr<base::RunLoop> run_loop_;
  284. HotseatTransitionAnimator* hotseat_transition_animator_;
  285. };
  286. // Used to test the Hotseat, ScrollableShelf, and DenseShelf features.
  287. INSTANTIATE_TEST_SUITE_P(
  288. All,
  289. HotseatWidgetTest,
  290. testing::Combine(
  291. testing::Values(ShelfAutoHideBehavior::kNever,
  292. ShelfAutoHideBehavior::kAlways),
  293. /*is_assistant_enabled*/ testing::Bool(),
  294. /*navigation_buttons_shown_in_tablet_mode*/ testing::Bool()));
  295. TEST_P(HotseatWidgetTest, LongPressHomeWithoutAppWindow) {
  296. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  297. TabletModeControllerTestApi().EnterTabletMode();
  298. GetAppListTestHelper()->CheckVisibility(true);
  299. HotseatStateWatcher watcher(GetShelfLayoutManager());
  300. ShowShelfAndActivateAssistant();
  301. GetAppListTestHelper()->CheckVisibility(true);
  302. EXPECT_EQ(
  303. is_assistant_enabled(),
  304. GetAppListTestHelper()->GetAppListView()->IsShowingEmbeddedAssistantUI());
  305. // Hotseat should not change when showing Assistant.
  306. watcher.CheckEqual({});
  307. }
  308. TEST_P(HotseatWidgetTest, LongPressHomeWithAppWindow) {
  309. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  310. TabletModeControllerTestApi().EnterTabletMode();
  311. GetAppListTestHelper()->CheckVisibility(true);
  312. std::unique_ptr<aura::Window> window =
  313. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  314. wm::ActivateWindow(window.get());
  315. GetAppListTestHelper()->CheckVisibility(false);
  316. HotseatStateWatcher watcher(GetShelfLayoutManager());
  317. ShowShelfAndActivateAssistant();
  318. GetAppListTestHelper()->CheckVisibility(false);
  319. EXPECT_EQ(
  320. is_assistant_enabled(),
  321. GetAppListTestHelper()->GetAppListView()->IsShowingEmbeddedAssistantUI());
  322. std::vector<HotseatState> expected_state;
  323. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  324. // |ShowShelfAndActivateAssistant()| will bring up shelf so it will trigger
  325. // one hotseat state change.
  326. expected_state.push_back(HotseatState::kExtended);
  327. // Launching the assistant from a shelf button on an autohidden shelf will
  328. // hide the shelf at the end of the operation.
  329. if (is_assistant_enabled() && navigation_buttons_shown_in_tablet_mode())
  330. expected_state.push_back(HotseatState::kHidden);
  331. }
  332. watcher.CheckEqual(expected_state);
  333. }
  334. // Tests that closing a window which was opened prior to entering tablet mode
  335. // results in a kShownHomeLauncher hotseat.
  336. TEST_P(HotseatWidgetTest, ClosingLastWindowInTabletMode) {
  337. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  338. std::unique_ptr<aura::Window> window =
  339. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  340. // Activate the window and go to tablet mode.
  341. wm::ActivateWindow(window.get());
  342. TabletModeControllerTestApi().EnterTabletMode();
  343. // Close the window, the AppListView should be shown, and the hotseat should
  344. // be kShownHomeLauncher.
  345. window->Hide();
  346. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  347. GetShelfLayoutManager()->hotseat_state());
  348. GetAppListTestHelper()->CheckVisibility(true);
  349. }
  350. // Tests that the hotseat is kShownHomeLauncher when entering tablet mode with
  351. // no windows.
  352. TEST_P(HotseatWidgetTest, GoingToTabletModeNoWindows) {
  353. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  354. TabletModeControllerTestApi().EnterTabletMode();
  355. GetAppListTestHelper()->CheckVisibility(true);
  356. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  357. GetShelfLayoutManager()->hotseat_state());
  358. }
  359. // Tests that the hotseat is kHidden when entering tablet mode with a window.
  360. TEST_P(HotseatWidgetTest, GoingToTabletModeWithWindows) {
  361. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  362. std::unique_ptr<aura::Window> window =
  363. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  364. // Activate the window and go to tablet mode.
  365. wm::ActivateWindow(window.get());
  366. TabletModeControllerTestApi().EnterTabletMode();
  367. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  368. GetAppListTestHelper()->CheckVisibility(false);
  369. }
  370. // The in-app Hotseat should not be hidden automatically when the shelf context
  371. // menu shows (https://crbug.com/1020388).
  372. TEST_P(HotseatWidgetTest, InAppShelfShowingContextMenu) {
  373. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  374. TabletModeControllerTestApi().EnterTabletMode();
  375. std::unique_ptr<aura::Window> window =
  376. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  377. wm::ActivateWindow(window.get());
  378. EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible(
  379. display::Screen::GetScreen()->GetPrimaryDisplay().id()));
  380. ShelfTestUtil::AddAppShortcut("app_id", TYPE_PINNED_APP);
  381. // Swipe up on the shelf to show the hotseat.
  382. SwipeUpOnShelf();
  383. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  384. ShelfViewTestAPI shelf_view_test_api(
  385. GetPrimaryShelf()->shelf_widget()->shelf_view_for_testing());
  386. ShelfAppButton* app_icon = shelf_view_test_api.GetButton(0);
  387. // Accelerate the generation of the long press event.
  388. ui::GestureConfiguration::GetInstance()->set_show_press_delay_in_ms(1);
  389. ui::GestureConfiguration::GetInstance()->set_short_press_time(
  390. base::Milliseconds(1));
  391. ui::GestureConfiguration::GetInstance()->set_long_press_time_in_ms(1);
  392. // Press the icon enough long time to generate the long press event.
  393. GetEventGenerator()->MoveTouch(app_icon->GetBoundsInScreen().CenterPoint());
  394. GetEventGenerator()->PressTouch();
  395. ui::GestureConfiguration* gesture_config =
  396. ui::GestureConfiguration::GetInstance();
  397. const int long_press_delay_ms = gesture_config->long_press_time_in_ms() +
  398. gesture_config->show_press_delay_in_ms();
  399. base::RunLoop run_loop;
  400. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  401. FROM_HERE, run_loop.QuitClosure(),
  402. base::Milliseconds(long_press_delay_ms));
  403. run_loop.Run();
  404. GetEventGenerator()->ReleaseTouch();
  405. // Expects that the hotseat's state is kExntended.
  406. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  407. // Ensures that the ink drop state is InkDropState::ACTIVATED before closing
  408. // the menu.
  409. app_icon->FireRippleActivationTimerForTest();
  410. }
  411. // Tests that a window that is created after going to tablet mode, then closed,
  412. // results in a kShownHomeLauncher hotseat.
  413. TEST_P(HotseatWidgetTest, CloseLastWindowOpenedInTabletMode) {
  414. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  415. TabletModeControllerTestApi().EnterTabletMode();
  416. std::unique_ptr<aura::Window> window =
  417. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  418. // Activate the window after entering tablet mode.
  419. wm::ActivateWindow(window.get());
  420. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  421. GetAppListTestHelper()->CheckVisibility(false);
  422. // Hide the window, the hotseat should be kShownHomeLauncher, and the home
  423. // launcher should be visible.
  424. window->Hide();
  425. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  426. GetShelfLayoutManager()->hotseat_state());
  427. GetAppListTestHelper()->CheckVisibility(true);
  428. }
  429. // Verifies removing a shelf item by dragging it off the extended hotseat.
  430. TEST_P(HotseatWidgetTest, DragItemOffExtendedHotseat) {
  431. TabletModeControllerTestApi().EnterTabletMode();
  432. std::unique_ptr<aura::Window> window =
  433. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  434. wm::ActivateWindow(window.get());
  435. ShelfTestUtil::AddAppShortcut("app_id_1", TYPE_PINNED_APP);
  436. ShelfTestUtil::AddAppShortcut("app_id_2", TYPE_PINNED_APP);
  437. ShelfView* shelf_view = GetPrimaryShelf()
  438. ->hotseat_widget()
  439. ->scrollable_shelf_view()
  440. ->shelf_view();
  441. EXPECT_EQ(2u, shelf_view->view_model_for_test()->view_size());
  442. // Show the in-app shelf.
  443. SwipeUpOnShelf();
  444. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  445. // Start mouse drag on a shelf item.
  446. ShelfAppButton* dragged_button =
  447. ShelfViewTestAPI(shelf_view).GetButton(/*index=*/0);
  448. GetEventGenerator()->MoveMouseTo(
  449. dragged_button->GetBoundsInScreen().CenterPoint());
  450. GetEventGenerator()->PressLeftButton();
  451. EXPECT_TRUE(dragged_button->FireDragTimerForTest());
  452. EXPECT_TRUE(shelf_view->drag_view());
  453. // Move mouse. Verify that the hotseat is still extended.
  454. GetEventGenerator()->MoveMouseBy(/*x=*/0, /*y=*/-80);
  455. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  456. // Release the mouse press. Verify that:
  457. // 1. Shelf item count decreases by one; and
  458. // 2. Hotseat is still extended.
  459. GetEventGenerator()->ReleaseLeftButton();
  460. EXPECT_EQ(1u, shelf_view->view_model_for_test()->view_size());
  461. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  462. }
  463. // Tests that swiping up on an autohidden shelf shows the hotseat, and swiping
  464. // down hides it.
  465. TEST_P(HotseatWidgetTest, ShowingAndHidingAutohiddenShelf) {
  466. if (shelf_auto_hide_behavior() != ShelfAutoHideBehavior::kAlways)
  467. return;
  468. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  469. TabletModeControllerTestApi().EnterTabletMode();
  470. std::unique_ptr<aura::Window> window =
  471. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  472. wm::ActivateWindow(window.get());
  473. SwipeUpOnShelf();
  474. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  475. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  476. SwipeDownOnShelf();
  477. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  478. EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState());
  479. // Swipe down again, nothing should change.
  480. SwipeDownOnShelf();
  481. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  482. EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState());
  483. }
  484. // Tests that swiping up on several places in the in-app shelf shows the
  485. // hotseat (crbug.com/1016931).
  486. TEST_P(HotseatWidgetTest, SwipeUpInAppShelfShowsHotseat) {
  487. TabletModeControllerTestApi().EnterTabletMode();
  488. std::unique_ptr<aura::Window> window =
  489. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  490. wm::ActivateWindow(window.get());
  491. base::HistogramTester histogram_tester;
  492. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  493. InAppShelfGestures::kSwipeDownToHide, 0);
  494. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  495. InAppShelfGestures::kSwipeUpToShow, 0);
  496. // Swipe up from the center of the shelf.
  497. SwipeUpOnShelf();
  498. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  499. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  500. InAppShelfGestures::kSwipeDownToHide, 0);
  501. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  502. InAppShelfGestures::kSwipeUpToShow, 1);
  503. // Swipe down from the hotseat to hide it.
  504. gfx::Rect hotseat_bounds =
  505. GetPrimaryShelf()->hotseat_widget()->GetWindowBoundsInScreen();
  506. gfx::Point start = hotseat_bounds.top_center();
  507. gfx::Point end = start + gfx::Vector2d(0, 80);
  508. const base::TimeDelta kTimeDelta = base::Milliseconds(100);
  509. const int kNumScrollSteps = 4;
  510. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  511. kNumScrollSteps);
  512. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  513. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  514. InAppShelfGestures::kSwipeDownToHide, 1);
  515. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  516. InAppShelfGestures::kSwipeUpToShow, 1);
  517. // Swipe up from the right part of the shelf (the system tray).
  518. start = GetShelfWidget()
  519. ->status_area_widget()
  520. ->GetWindowBoundsInScreen()
  521. .CenterPoint();
  522. end = start + gfx::Vector2d(0, -80);
  523. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  524. kNumScrollSteps);
  525. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  526. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  527. InAppShelfGestures::kSwipeDownToHide, 1);
  528. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  529. InAppShelfGestures::kSwipeUpToShow, 2);
  530. // Swipe down from the hotseat to hide it.
  531. start = hotseat_bounds.top_center();
  532. end = start + gfx::Vector2d(0, 80);
  533. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  534. kNumScrollSteps);
  535. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  536. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  537. InAppShelfGestures::kSwipeDownToHide, 2);
  538. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  539. InAppShelfGestures::kSwipeUpToShow, 2);
  540. // Swipe up from the left part of the shelf (the home/back button).
  541. start = GetShelfWidget()
  542. ->navigation_widget()
  543. ->GetWindowBoundsInScreen()
  544. .CenterPoint();
  545. end = start + gfx::Vector2d(0, -80);
  546. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  547. kNumScrollSteps);
  548. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  549. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  550. InAppShelfGestures::kSwipeDownToHide, 2);
  551. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  552. InAppShelfGestures::kSwipeUpToShow, 3);
  553. }
  554. // Tests that swiping up on the hotseat does nothing.
  555. TEST_P(HotseatWidgetTest, SwipeUpOnHotseatBackgroundDoesNothing) {
  556. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  557. TabletModeControllerTestApi().EnterTabletMode();
  558. std::unique_ptr<aura::Window> window =
  559. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  560. wm::ActivateWindow(window.get());
  561. base::HistogramTester histogram_tester;
  562. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  563. InAppShelfGestures::kSwipeDownToHide, 0);
  564. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  565. InAppShelfGestures::kSwipeUpToShow, 0);
  566. // Swipe up on the shelf to show the hotseat.
  567. EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible(
  568. display::Screen::GetScreen()->GetPrimaryDisplay().id()));
  569. SwipeUpOnShelf();
  570. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  571. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  572. InAppShelfGestures::kSwipeDownToHide, 0);
  573. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  574. InAppShelfGestures::kSwipeUpToShow, 1);
  575. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  576. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  577. // Swipe up on the Hotseat (parent of ShelfView) does nothing.
  578. gfx::Point start(GetPrimaryShelf()
  579. ->shelf_widget()
  580. ->hotseat_widget()
  581. ->GetWindowBoundsInScreen()
  582. .top_center());
  583. const gfx::Point end(start + gfx::Vector2d(0, -300));
  584. const base::TimeDelta kTimeDelta = base::Milliseconds(100);
  585. const int kNumScrollSteps = 4;
  586. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  587. kNumScrollSteps);
  588. EXPECT_FALSE(Shell::Get()->app_list_controller()->IsVisible(
  589. display::Screen::GetScreen()->GetPrimaryDisplay().id()));
  590. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  591. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  592. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  593. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  594. InAppShelfGestures::kSwipeDownToHide, 0);
  595. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  596. InAppShelfGestures::kSwipeUpToShow, 1);
  597. }
  598. // Tests that tapping an active window with an extended hotseat results in a
  599. // hidden hotseat.
  600. TEST_P(HotseatWidgetTest, TappingActiveWindowHidesHotseat) {
  601. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  602. TabletModeControllerTestApi().EnterTabletMode();
  603. std::unique_ptr<aura::Window> window =
  604. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  605. wm::ActivateWindow(window.get());
  606. base::HistogramTester histogram_tester;
  607. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  608. InAppShelfGestures::kSwipeDownToHide, 0);
  609. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  610. InAppShelfGestures::kSwipeUpToShow, 0);
  611. histogram_tester.ExpectBucketCount(
  612. kHotseatGestureHistogramName,
  613. InAppShelfGestures::kHotseatHiddenDueToInteractionOutsideOfShelf, 0);
  614. // Swipe up on the shelf to show the hotseat.
  615. SwipeUpOnShelf();
  616. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  617. InAppShelfGestures::kSwipeDownToHide, 0);
  618. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  619. InAppShelfGestures::kSwipeUpToShow, 1);
  620. histogram_tester.ExpectBucketCount(
  621. kHotseatGestureHistogramName,
  622. InAppShelfGestures::kHotseatHiddenDueToInteractionOutsideOfShelf, 0);
  623. // Tap the shelf background, nothing should happen.
  624. gfx::Rect display_bounds =
  625. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  626. gfx::Point tap_point = display_bounds.bottom_center();
  627. GetEventGenerator()->GestureTapAt(tap_point);
  628. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  629. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  630. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  631. // Tap the active window, the hotseat should hide.
  632. tap_point.Offset(0, -200);
  633. GetEventGenerator()->GestureTapAt(tap_point);
  634. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  635. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  636. EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState());
  637. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  638. InAppShelfGestures::kSwipeDownToHide, 0);
  639. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  640. InAppShelfGestures::kSwipeUpToShow, 1);
  641. histogram_tester.ExpectBucketCount(
  642. kHotseatGestureHistogramName,
  643. InAppShelfGestures::kHotseatHiddenDueToInteractionOutsideOfShelf, 1);
  644. }
  645. // Tests that gesture dragging an active window hides the hotseat.
  646. TEST_P(HotseatWidgetTest, GestureDraggingActiveWindowHidesHotseat) {
  647. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  648. TabletModeControllerTestApi().EnterTabletMode();
  649. std::unique_ptr<aura::Window> window =
  650. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  651. wm::ActivateWindow(window.get());
  652. base::HistogramTester histogram_tester;
  653. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  654. InAppShelfGestures::kSwipeDownToHide, 0);
  655. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  656. InAppShelfGestures::kSwipeUpToShow, 0);
  657. // Swipe up on the shelf to show the hotseat.
  658. SwipeUpOnShelf();
  659. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  660. InAppShelfGestures::kSwipeDownToHide, 0);
  661. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  662. InAppShelfGestures::kSwipeUpToShow, 1);
  663. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  664. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  665. // Gesture drag on the active window, the hotseat should hide.
  666. gfx::Rect display_bounds =
  667. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  668. gfx::Point start = display_bounds.bottom_center();
  669. start.Offset(0, -200);
  670. gfx::Point end = start;
  671. end.Offset(0, -200);
  672. GetEventGenerator()->GestureScrollSequence(start, end, base::Milliseconds(10),
  673. 4);
  674. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  675. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  676. EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState());
  677. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  678. InAppShelfGestures::kSwipeDownToHide, 0);
  679. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  680. InAppShelfGestures::kSwipeUpToShow, 1);
  681. }
  682. // Tests that a swipe up on the shelf shows the hotseat while in split view.
  683. TEST_P(HotseatWidgetTest, SwipeUpOnShelfShowsHotseatInSplitView) {
  684. TabletModeControllerTestApi().EnterTabletMode();
  685. std::unique_ptr<aura::Window> window =
  686. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  687. wm::ActivateWindow(window.get());
  688. std::unique_ptr<aura::Window> window2 =
  689. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  690. base::HistogramTester histogram_tester;
  691. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  692. InAppShelfGestures::kSwipeDownToHide, 0);
  693. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  694. InAppShelfGestures::kSwipeUpToShow, 0);
  695. // Go into split view mode by first going into overview, and then snapping
  696. // the open window on one side.
  697. EnterOverview();
  698. SplitViewController* split_view_controller =
  699. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  700. split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
  701. split_view_controller->SnapWindow(window2.get(), SplitViewController::RIGHT);
  702. EXPECT_TRUE(split_view_controller->BothSnapped());
  703. // We should still be able to drag up the hotseat.
  704. SwipeUpOnShelf();
  705. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  706. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  707. InAppShelfGestures::kSwipeDownToHide, 0);
  708. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  709. InAppShelfGestures::kSwipeUpToShow, 1);
  710. }
  711. // Tests that HotseatTransitionAimationObserver starting and ending calls have a
  712. // 1:1 relation. This test verifies that behavior.
  713. TEST_P(HotseatWidgetTest, ObserverCallsMatch) {
  714. ui::ScopedAnimationDurationScaleMode non_zero(
  715. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  716. // Enter tablet mode to show the home launcher. Hotseat state should be
  717. // kShownHomeLauncher.
  718. TabletModeControllerTestApi().EnterTabletMode();
  719. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  720. GetShelfLayoutManager()->hotseat_state());
  721. // Create a window to transition to the in-app shelf. Hotseat state should be
  722. // kHidden.
  723. HotseatTransitionAnimationObserver observer(
  724. GetPrimaryShelf()->shelf_widget()->hotseat_transition_animator());
  725. std::unique_ptr<aura::Window> window =
  726. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 800, 800));
  727. observer.Wait();
  728. EXPECT_TRUE(observer.ObserverCountsEqual());
  729. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  730. observer.Reset();
  731. // Go to home launcher again. Hotseat state should be kShownHomeLauncher.
  732. ShowShelfAndGoHome();
  733. observer.Wait();
  734. EXPECT_TRUE(observer.ObserverCountsEqual());
  735. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  736. GetShelfLayoutManager()->hotseat_state());
  737. observer.Reset();
  738. // Go to overview and cancel immediately. Hotseat state should be
  739. // kShownHomeLauncher.
  740. StartOverview();
  741. EXPECT_TRUE(Shell::Get()->overview_controller()->IsInStartAnimation());
  742. // No animations should have been started so no animations are in progress
  743. // or aborted.
  744. EXPECT_TRUE(observer.ObserverCountsEqual());
  745. EXPECT_EQ(0, observer.AnimationAbortedCalls());
  746. EndOverview();
  747. // No animations should have been started or aborted.
  748. EXPECT_EQ(0, observer.AnimationAbortedCalls());
  749. EXPECT_TRUE(observer.ObserverCountsEqual());
  750. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  751. GetShelfLayoutManager()->hotseat_state());
  752. observer.Reset();
  753. // Go to overview. Hotseat state should be kExtended.
  754. StartOverview();
  755. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  756. GetShelfLayoutManager()->hotseat_state());
  757. EXPECT_TRUE(observer.ObserverCountsEqual());
  758. }
  759. // Tests that a swipe up on the shelf shows the hotseat while in split view.
  760. TEST_P(HotseatWidgetTest, DisableBlurDuringOverviewMode) {
  761. TabletModeControllerTestApi().EnterTabletMode();
  762. ASSERT_EQ(
  763. ShelfConfig::Get()->shelf_blur_radius(),
  764. GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  765. // Go into overview and check that at the end of the animation, background
  766. // blur is disabled.
  767. StartOverview();
  768. WaitForOverviewAnimation(/*enter=*/true);
  769. EXPECT_EQ(
  770. 0, GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  771. // Exit overview and check that at the end of the animation, background
  772. // blur is enabled again.
  773. EndOverview();
  774. WaitForOverviewAnimation(/*enter=*/false);
  775. EXPECT_EQ(
  776. ShelfConfig::Get()->shelf_blur_radius(),
  777. GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  778. }
  779. // Tests that releasing the hotseat gesture below the threshold results in a
  780. // kHidden hotseat when the shelf is shown.
  781. TEST_P(HotseatWidgetTest, ReleasingSlowDragBelowThreshold) {
  782. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
  783. TabletModeControllerTestApi().EnterTabletMode();
  784. std::unique_ptr<aura::Window> window =
  785. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  786. wm::ActivateWindow(window.get());
  787. base::HistogramTester histogram_tester;
  788. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  789. InAppShelfGestures::kSwipeDownToHide, 0);
  790. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  791. InAppShelfGestures::kSwipeUpToShow, 0);
  792. gfx::Rect display_bounds =
  793. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  794. const gfx::Point start(display_bounds.bottom_center());
  795. const int hotseat_size = GetPrimaryShelf()
  796. ->shelf_widget()
  797. ->hotseat_widget()
  798. ->GetWindowBoundsInScreen()
  799. .height();
  800. const gfx::Point end(start + gfx::Vector2d(0, -hotseat_size / 2 + 1));
  801. const base::TimeDelta kTimeDelta = base::Milliseconds(1000);
  802. const int kNumScrollSteps = 4;
  803. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  804. kNumScrollSteps);
  805. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  806. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  807. InAppShelfGestures::kSwipeDownToHide, 0);
  808. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  809. InAppShelfGestures::kSwipeUpToShow, 0);
  810. }
  811. // Tests that releasing the hotseat gesture above the threshold results in a
  812. // kExtended hotseat.
  813. TEST_P(HotseatWidgetTest, ReleasingSlowDragAboveThreshold) {
  814. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  815. TabletModeControllerTestApi().EnterTabletMode();
  816. std::unique_ptr<aura::Window> window =
  817. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  818. wm::ActivateWindow(window.get());
  819. base::HistogramTester histogram_tester;
  820. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  821. InAppShelfGestures::kSwipeDownToHide, 0);
  822. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  823. InAppShelfGestures::kSwipeUpToShow, 0);
  824. gfx::Rect display_bounds =
  825. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  826. const gfx::Point start(display_bounds.bottom_center());
  827. const int hotseat_size = GetPrimaryShelf()
  828. ->shelf_widget()
  829. ->hotseat_widget()
  830. ->GetWindowBoundsInScreen()
  831. .height();
  832. const gfx::Point end(start + gfx::Vector2d(0, -hotseat_size * 3.0f / 2.0f));
  833. const base::TimeDelta kTimeDelta = base::Milliseconds(1000);
  834. const int kNumScrollSteps = 4;
  835. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  836. kNumScrollSteps);
  837. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  838. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  839. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  840. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  841. InAppShelfGestures::kSwipeDownToHide, 0);
  842. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  843. InAppShelfGestures::kSwipeUpToShow, 1);
  844. }
  845. // Tests that releasing the hotseat gesture when a stylus app is active has a
  846. // bigger thresehold than normal apps.
  847. TEST_P(HotseatWidgetTest, HotseatDragGestureForStylusApp) {
  848. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  849. TabletModeControllerTestApi().EnterTabletMode();
  850. // Taken from ShelfLayoutManager.
  851. const int kShelfPalmRejectionSwipeOffset = 80;
  852. const std::string stylus_app = "fhapgmpiiiigioilnjmkiohjhlegnceb";
  853. ShelfModel* model = Shell::Get()->shelf_controller()->model();
  854. const ShelfID test_stylus_app_id(stylus_app);
  855. std::unique_ptr<aura::Window> window =
  856. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  857. window->SetProperty(kShelfIDKey, test_stylus_app_id.Serialize());
  858. wm::ActivateWindow(window.get());
  859. EXPECT_EQ(test_stylus_app_id, model->active_shelf_id());
  860. base::HistogramTester histogram_tester;
  861. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  862. InAppShelfGestures::kSwipeDownToHide, 0);
  863. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  864. InAppShelfGestures::kSwipeUpToShow, 0);
  865. gfx::Rect display_bounds =
  866. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  867. const gfx::Point start(display_bounds.bottom_center());
  868. const int hotseat_size = GetPrimaryShelf()
  869. ->shelf_widget()
  870. ->hotseat_widget()
  871. ->GetWindowBoundsInScreen()
  872. .height();
  873. const gfx::Point normal_thereshold(
  874. start + gfx::Vector2d(0, -hotseat_size * 3.0f / 2.0f));
  875. const base::TimeDelta kTimeDelta = base::Milliseconds(1000);
  876. const int kNumScrollSteps = 4;
  877. GetEventGenerator()->GestureScrollSequence(start, normal_thereshold,
  878. kTimeDelta, kNumScrollSteps);
  879. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  880. const gfx::Point offset_thereshold(
  881. normal_thereshold + gfx::Vector2d(0, -kShelfPalmRejectionSwipeOffset));
  882. GetEventGenerator()->GestureScrollSequence(start, offset_thereshold,
  883. kTimeDelta, kNumScrollSteps);
  884. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  885. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  886. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, GetPrimaryShelf()->GetAutoHideState());
  887. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  888. InAppShelfGestures::kSwipeDownToHide, 0);
  889. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  890. InAppShelfGestures::kSwipeUpToShow, 1);
  891. }
  892. // Tests that showing overview after showing the hotseat results in only one
  893. // animation, to |kExtended|.
  894. TEST_P(HotseatWidgetTest, ShowingOverviewFromShownAnimatesOnce) {
  895. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  896. TabletModeControllerTestApi().EnterTabletMode();
  897. std::unique_ptr<aura::Window> window =
  898. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  899. wm::ActivateWindow(window.get());
  900. std::unique_ptr<HotseatStateWatcher> state_watcher_ =
  901. std::make_unique<HotseatStateWatcher>(GetShelfLayoutManager());
  902. SwipeUpOnShelf();
  903. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  904. StartOverview();
  905. state_watcher_->CheckEqual({HotseatState::kExtended});
  906. }
  907. // Tests that the hotseat is not flush with the bottom of the screen when home
  908. // launcher is showing.
  909. TEST_P(HotseatWidgetTest, HotseatNotFlushWhenHomeLauncherShowing) {
  910. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  911. TabletModeControllerTestApi().EnterTabletMode();
  912. const int display_height =
  913. display::Screen::GetScreen()->GetPrimaryDisplay().bounds().height();
  914. const int hotseat_bottom = GetPrimaryShelf()
  915. ->shelf_widget()
  916. ->hotseat_widget()
  917. ->GetWindowBoundsInScreen()
  918. .bottom();
  919. EXPECT_LT(hotseat_bottom, display_height);
  920. }
  921. // Tests that home -> overview results in only one hotseat state change.
  922. TEST_P(HotseatWidgetTest, HomeToOverviewChangesStateOnce) {
  923. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  924. TabletModeControllerTestApi().EnterTabletMode();
  925. // First, try with no windows open.
  926. {
  927. HotseatStateWatcher watcher(GetShelfLayoutManager());
  928. StartOverview();
  929. WaitForOverviewAnimation(/*enter=*/true);
  930. watcher.CheckEqual({/* shelf state should not change*/});
  931. }
  932. // Open a window, then open the home launcher.
  933. std::unique_ptr<aura::Window> window =
  934. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  935. wm::ActivateWindow(window.get());
  936. ShowShelfAndGoHome();
  937. GetAppListTestHelper()->CheckVisibility(true);
  938. // Activate overview and expect the hotseat only changes state to extended.
  939. {
  940. HotseatStateWatcher watcher(GetShelfLayoutManager());
  941. StartOverview();
  942. WaitForOverviewAnimation(/*enter=*/true);
  943. watcher.CheckEqual({/* shelf state should not change*/});
  944. }
  945. }
  946. // Verifies that the hotseat widget and the status area widget are animated to
  947. // the target location when entering overview mode in home launcher
  948. // (https://crbug.com/1079347).
  949. TEST_P(HotseatWidgetTest, VerifyShelfAnimationWhenEnteringOverview) {
  950. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  951. TabletModeControllerTestApi().EnterTabletMode();
  952. ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
  953. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  954. HotseatWidget* hotseat_widget = GetPrimaryShelf()->hotseat_widget();
  955. ASSERT_EQ(HotseatState::kShownHomeLauncher, hotseat_widget->state());
  956. ui::LayerAnimator* hotseat_layer_animator =
  957. hotseat_widget->GetNativeView()->layer()->GetAnimator();
  958. ui::LayerAnimator* status_area_layer_animator = GetShelfWidget()
  959. ->status_area_widget()
  960. ->GetNativeView()
  961. ->layer()
  962. ->GetAnimator();
  963. ASSERT_FALSE(hotseat_layer_animator->is_animating());
  964. ASSERT_FALSE(status_area_layer_animator->is_animating());
  965. StartOverview();
  966. EXPECT_FALSE(hotseat_layer_animator->is_animating());
  967. EXPECT_FALSE(status_area_layer_animator->is_animating());
  968. ASSERT_EQ(HotseatState::kShownHomeLauncher, hotseat_widget->state());
  969. }
  970. // Tests that home -> in-app results in only one state change.
  971. TEST_P(HotseatWidgetTest, HomeToInAppChangesStateOnce) {
  972. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  973. TabletModeControllerTestApi().EnterTabletMode();
  974. // Go to in-app, the hotseat should hide.
  975. HotseatStateWatcher watcher(GetShelfLayoutManager());
  976. std::unique_ptr<aura::Window> window =
  977. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  978. wm::ActivateWindow(window.get());
  979. watcher.CheckEqual({HotseatState::kHidden});
  980. }
  981. // Tests that in-app -> home via closing the only window, swiping from the
  982. // bottom of the shelf, and tapping the home launcher button results in only one
  983. // state change.
  984. TEST_P(HotseatWidgetTest, InAppToHomeChangesStateOnce) {
  985. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  986. TabletModeControllerTestApi().EnterTabletMode();
  987. // Go to in-app with an extended hotseat.
  988. std::unique_ptr<aura::Window> window =
  989. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  990. wm::ActivateWindow(window.get());
  991. SwipeUpOnShelf();
  992. // Press the home button, the hotseat should transition directly to
  993. // kShownHomeLauncher.
  994. {
  995. HotseatStateWatcher watcher(GetShelfLayoutManager());
  996. ShowShelfAndGoHome();
  997. watcher.CheckEqual({HotseatState::kShownHomeLauncher});
  998. }
  999. // Go to in-app.
  1000. window->Show();
  1001. wm::ActivateWindow(window.get());
  1002. // Extend the hotseat, then Swipe up to go home, the hotseat should transition
  1003. // directly to kShownHomeLauncher.
  1004. SwipeUpOnShelf();
  1005. {
  1006. ui::ScopedAnimationDurationScaleMode regular_animations(
  1007. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1008. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1009. FlingUpOnShelf();
  1010. watcher.CheckEqual({HotseatState::kShownHomeLauncher});
  1011. // Wait for the window animation to complete, and verify the hotseat state
  1012. // remained kShownHomeLauncher.
  1013. ShellTestApi().WaitForWindowFinishAnimating(window.get());
  1014. watcher.CheckEqual({HotseatState::kShownHomeLauncher});
  1015. }
  1016. // Nothing left to test for autohidden shelf.
  1017. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  1018. return;
  1019. // Go to in-app and do not extend the hotseat.
  1020. window->Show();
  1021. wm::ActivateWindow(window.get());
  1022. // TODO(manucornet): This is flaky when the shelf is always auto-hidden.
  1023. // Investigate and fix (sometimes fails when the assistant is enabled,
  1024. // sometimes not).
  1025. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kNever)
  1026. return;
  1027. // Press the home button, the hotseat should transition directly to
  1028. // kShownHomeLauncher.
  1029. {
  1030. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1031. ShowShelfAndGoHome();
  1032. watcher.CheckEqual({HotseatState::kShownHomeLauncher});
  1033. }
  1034. }
  1035. // Tests that transitioning from overview to home while a transition from home
  1036. // to overview is still in progress ends up with hotseat in kShownHomeLauncher
  1037. // state (and in app shelf not visible).
  1038. TEST_P(HotseatWidgetTest, HomeToOverviewAndBack) {
  1039. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1040. TabletModeControllerTestApi().EnterTabletMode();
  1041. std::unique_ptr<aura::Window> window =
  1042. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1043. WindowState::Get(window.get())->Minimize();
  1044. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1045. // Start going to overview.
  1046. {
  1047. ui::ScopedAnimationDurationScaleMode regular_animations(
  1048. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1049. StartOverview();
  1050. watcher.CheckEqual({/*Hotseat state should not change*/});
  1051. }
  1052. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1053. EXPECT_TRUE(overview_controller->InOverviewSession());
  1054. ShowShelfAndGoHome();
  1055. GetAppListTestHelper()->CheckVisibility(true);
  1056. EXPECT_FALSE(overview_controller->InOverviewSession());
  1057. EXPECT_FALSE(ShelfConfig::Get()->is_in_app());
  1058. watcher.CheckEqual({/*Hotseat state should not change*/});
  1059. }
  1060. TEST_P(HotseatWidgetTest, InAppToOverviewAndBack) {
  1061. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1062. TabletModeControllerTestApi().EnterTabletMode();
  1063. std::unique_ptr<aura::Window> window =
  1064. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1065. wm::ActivateWindow(window.get());
  1066. // Start watching hotseat state before swipping up the shelf, so hotseat
  1067. // change expectation match for both auto-hidden and always-shown shelf.
  1068. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1069. // Make sure shelf (and overview button) are visible - this is moves the
  1070. // hotseat into kExtended state.
  1071. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  1072. SwipeUpOnShelf();
  1073. // Start going to overview - use non zero animation so transition is not
  1074. // immediate.
  1075. {
  1076. ui::ScopedAnimationDurationScaleMode regular_animations(
  1077. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1078. StartOverview();
  1079. }
  1080. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1081. EXPECT_TRUE(overview_controller->InOverviewSession());
  1082. GetAppListTestHelper()->CheckVisibility(false);
  1083. // Hotseat should be extended as overview is starting.
  1084. watcher.CheckEqual({HotseatState::kExtended});
  1085. // Exit overview to go back to the app window.
  1086. EndOverview();
  1087. EXPECT_FALSE(overview_controller->InOverviewSession());
  1088. EXPECT_TRUE(ShelfConfig::Get()->is_in_app());
  1089. // The hotseat is expected to be hidden.
  1090. watcher.CheckEqual({HotseatState::kExtended, HotseatState::kHidden});
  1091. }
  1092. // Tests transition to home screen initiated while transition from app window to
  1093. // overview is in progress.
  1094. TEST_P(HotseatWidgetTest, ShowShelfAndGoHomeDuringInAppToOverviewTransition) {
  1095. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1096. TabletModeControllerTestApi().EnterTabletMode();
  1097. std::unique_ptr<aura::Window> window =
  1098. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1099. wm::ActivateWindow(window.get());
  1100. // Start watching hotseat state before swipping up the shelf, so hotseat
  1101. // change expectation match for both auto-hidden and always-shown shelf.
  1102. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1103. // Make sure shelf (and overview button) are visible - this is moves the
  1104. // hotseat into kExtended state.
  1105. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways)
  1106. SwipeUpOnShelf();
  1107. // Start going to overview - use non zero animation so transition is not
  1108. // immediate.
  1109. {
  1110. ui::ScopedAnimationDurationScaleMode regular_animations(
  1111. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1112. StartOverview();
  1113. }
  1114. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1115. EXPECT_TRUE(overview_controller->InOverviewSession());
  1116. GetAppListTestHelper()->CheckVisibility(false);
  1117. // Hotseat should be extended as overview is starting.
  1118. watcher.CheckEqual({HotseatState::kExtended});
  1119. // Go home - expect transition to home (with hotseat in kShownHomeLauncher
  1120. // state, and in app shelf hidden).
  1121. ShowShelfAndGoHome();
  1122. GetAppListTestHelper()->CheckVisibility(true);
  1123. EXPECT_FALSE(overview_controller->InOverviewSession());
  1124. EXPECT_FALSE(ShelfConfig::Get()->is_in_app());
  1125. watcher.CheckEqual(
  1126. {HotseatState::kExtended, HotseatState::kShownHomeLauncher});
  1127. }
  1128. // Tests that in-app -> overview results in only one state change with an
  1129. // autohidden shelf.
  1130. TEST_P(HotseatWidgetTest, InAppToOverviewChangesStateOnceAutohiddenShelf) {
  1131. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  1132. TabletModeControllerTestApi().EnterTabletMode();
  1133. // Test going to overview mode using the controller from an autohide hidden
  1134. // shelf. Go to in-app.
  1135. std::unique_ptr<aura::Window> window =
  1136. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1137. wm::ActivateWindow(window.get());
  1138. {
  1139. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1140. // Enter overview by using the controller.
  1141. EnterOverview();
  1142. WaitForOverviewAnimation(/*enter=*/true);
  1143. watcher.CheckEqual({HotseatState::kExtended});
  1144. }
  1145. ExitOverview();
  1146. WaitForOverviewAnimation(/*enter=*/false);
  1147. // Test in-app -> overview again with the autohide shown shelf.
  1148. EXPECT_TRUE(ShelfConfig::Get()->is_in_app());
  1149. EXPECT_EQ(ShelfAutoHideState::SHELF_AUTO_HIDE_HIDDEN,
  1150. GetShelfLayoutManager()->auto_hide_state());
  1151. SwipeUpOnShelf();
  1152. {
  1153. HotseatStateWatcher watcher(GetShelfLayoutManager());
  1154. // Enter overview by using the controller.
  1155. EnterOverview();
  1156. WaitForOverviewAnimation(/*enter=*/true);
  1157. watcher.CheckEqual({});
  1158. EXPECT_EQ(HotseatState::kExtended,
  1159. GetShelfLayoutManager()->hotseat_state());
  1160. }
  1161. }
  1162. // Tests that going between Applist and overview in tablet mode with no windows
  1163. // results in no work area change.
  1164. TEST_P(HotseatWidgetTest,
  1165. WorkAreaDoesNotUpdateAppListToFromOverviewWithNoWindow) {
  1166. TabletModeControllerTestApi().EnterTabletMode();
  1167. DisplayWorkAreaChangeCounter counter;
  1168. EnterOverview();
  1169. WaitForOverviewAnimation(/*enter=*/true);
  1170. EXPECT_EQ(0, counter.count());
  1171. EnterOverview();
  1172. WaitForOverviewAnimation(/*enter=*/true);
  1173. EXPECT_EQ(0, counter.count());
  1174. }
  1175. // Tests that switching between AppList and overview with a window results in no
  1176. // work area change.
  1177. TEST_P(HotseatWidgetTest,
  1178. WorkAreaDoesNotUpdateAppListToFromOverviewWithWindow) {
  1179. DisplayWorkAreaChangeCounter counter;
  1180. TabletModeControllerTestApi().EnterTabletMode();
  1181. std::unique_ptr<aura::Window> window =
  1182. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1183. wm::ActivateWindow(window.get());
  1184. ASSERT_EQ(1, counter.count());
  1185. ShowShelfAndGoHome();
  1186. StartOverview();
  1187. WaitForOverviewAnimation(/*enter=*/true);
  1188. EXPECT_EQ(1, counter.count());
  1189. EndOverview();
  1190. WaitForOverviewAnimation(/*enter=*/false);
  1191. EXPECT_EQ(1, counter.count());
  1192. }
  1193. // Tests that switching between AppList and an active window does not update the
  1194. // work area.
  1195. TEST_P(HotseatWidgetTest, WorkAreaDoesNotUpdateOpenWindowToFromAppList) {
  1196. TabletModeControllerTestApi().EnterTabletMode();
  1197. std::unique_ptr<aura::Window> window =
  1198. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1199. wm::ActivateWindow(window.get());
  1200. ASSERT_TRUE(ShelfConfig::Get()->is_in_app());
  1201. // Go to the home launcher, work area should not update.
  1202. DisplayWorkAreaChangeCounter counter;
  1203. ShowShelfAndGoHome();
  1204. GetAppListTestHelper()->CheckVisibility(true);
  1205. EXPECT_EQ(0, counter.count());
  1206. // Go back to the window, work area should not update.
  1207. wm::ActivateWindow(window.get());
  1208. EXPECT_TRUE(ShelfConfig::Get()->is_in_app());
  1209. EXPECT_EQ(0, counter.count());
  1210. }
  1211. // Tests that switching between overview and an active window does not update
  1212. // the work area.
  1213. TEST_P(HotseatWidgetTest, WorkAreaDoesNotUpdateOpenWindowToFromOverview) {
  1214. TabletModeControllerTestApi().EnterTabletMode();
  1215. std::unique_ptr<aura::Window> window =
  1216. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1217. wm::ActivateWindow(window.get());
  1218. ASSERT_TRUE(ShelfConfig::Get()->is_in_app());
  1219. // Go to overview, there should not be a work area update.
  1220. DisplayWorkAreaChangeCounter counter;
  1221. StartOverview();
  1222. WaitForOverviewAnimation(/*enter=*/true);
  1223. EXPECT_EQ(0, counter.count());
  1224. // Go back to the app, there should not be a work area update.
  1225. wm::ActivateWindow(window.get());
  1226. EXPECT_TRUE(ShelfConfig::Get()->is_in_app());
  1227. EXPECT_EQ(0, counter.count());
  1228. }
  1229. // Tests that the shelf opaque background is properly updated after a tablet
  1230. // mode transition with no apps.
  1231. TEST_P(HotseatWidgetTest, ShelfBackgroundNotVisibleInTabletModeNoApps) {
  1232. TabletModeControllerTestApi().EnterTabletMode();
  1233. EXPECT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
  1234. }
  1235. // Tests that the shelf opaque background is properly updated after a tablet
  1236. // mode transition with no apps with dense shelf.
  1237. TEST_P(HotseatWidgetTest, DenseShelfBackgroundNotVisibleInTabletModeNoApps) {
  1238. UpdateDisplay("300x1000");
  1239. TabletModeControllerTestApi().EnterTabletMode();
  1240. EXPECT_FALSE(GetShelfWidget()->GetOpaqueBackground()->visible());
  1241. }
  1242. // Tests that the hotseat is extended if focused with a keyboard.
  1243. TEST_P(HotseatWidgetTest, ExtendHotseatIfFocusedWithKeyboard) {
  1244. TabletModeControllerTestApi().EnterTabletMode();
  1245. std::unique_ptr<aura::Window> window =
  1246. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1247. wm::ActivateWindow(window.get());
  1248. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1249. // Focus the shelf. Hotseat should now show extended.
  1250. GetPrimaryShelf()->shelf_focus_cycler()->FocusShelf(false /* last_element */);
  1251. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1252. // Focus the status area. Hotseat should now hide, as it was
  1253. // automatically extended by focusing it.
  1254. GetPrimaryShelf()->shelf_focus_cycler()->FocusStatusArea(
  1255. false /* last_element */);
  1256. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1257. // Now swipe up to show the shelf and then focus it with the keyboard. Hotseat
  1258. // should keep extended.
  1259. SwipeUpOnShelf();
  1260. GetPrimaryShelf()->shelf_focus_cycler()->FocusShelf(false /* last_element */);
  1261. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1262. // Now focus the status area widget again. Hotseat should remain shown, as it
  1263. // was manually extended.
  1264. GetPrimaryShelf()->shelf_focus_cycler()->FocusStatusArea(
  1265. false /* last_element */);
  1266. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1267. }
  1268. // Tests that if the hotseat was hidden while being focused, doing a traversal
  1269. // focus on the next element brings it up again.
  1270. TEST_P(HotseatWidgetTest, SwipeDownOnFocusedHotseat) {
  1271. TabletModeControllerTestApi().EnterTabletMode();
  1272. std::unique_ptr<aura::Window> window =
  1273. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1274. wm::ActivateWindow(window.get());
  1275. ShelfTestUtil::AddAppShortcut("app_id_1", TYPE_APP);
  1276. ShelfTestUtil::AddAppShortcut("app_id_2", TYPE_APP);
  1277. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1278. // Focus the shelf, then swipe down on the shelf to hide it. Hotseat should be
  1279. // hidden.
  1280. GetPrimaryShelf()->shelf_focus_cycler()->FocusShelf(false /* last_element */);
  1281. gfx::Rect hotseat_bounds =
  1282. GetPrimaryShelf()->hotseat_widget()->GetWindowBoundsInScreen();
  1283. gfx::Point start = hotseat_bounds.top_center();
  1284. gfx::Point end = start + gfx::Vector2d(0, 80);
  1285. GetEventGenerator()->GestureScrollSequence(
  1286. start, end, base::Milliseconds(100), 4 /*scroll_steps*/);
  1287. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1288. // Focus to the next element in the hotseat. The hotseat should show again.
  1289. PressAndReleaseKey(ui::VKEY_TAB);
  1290. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1291. }
  1292. // Tests that in overview, we can still exit by clicking on the hotseat if the
  1293. // point is not on the visible area.
  1294. TEST_P(HotseatWidgetTest, ExitOverviewWithClickOnHotseat) {
  1295. std::unique_ptr<aura::Window> window1 = AshTestBase::CreateTestWindow();
  1296. ShelfTestUtil::AddAppShortcut("app_id_1", TYPE_APP);
  1297. TabletModeControllerTestApi().EnterTabletMode();
  1298. ASSERT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted());
  1299. ASSERT_FALSE(WindowState::Get(window1.get())->IsMinimized());
  1300. // Enter overview, hotseat is visible. Choose the point to the farthest left.
  1301. // This point will not be visible.
  1302. auto* overview_controller = Shell::Get()->overview_controller();
  1303. auto* hotseat_widget = GetPrimaryShelf()->hotseat_widget();
  1304. EnterOverview();
  1305. ASSERT_TRUE(overview_controller->InOverviewSession());
  1306. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1307. gfx::Point far_left_point =
  1308. hotseat_widget->GetWindowBoundsInScreen().left_center();
  1309. // Tests that on clicking, we exit overview and all windows are minimized.
  1310. GetEventGenerator()->set_current_screen_location(far_left_point);
  1311. GetEventGenerator()->ClickLeftButton();
  1312. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  1313. GetShelfLayoutManager()->hotseat_state());
  1314. EXPECT_TRUE(WindowState::Get(window1.get())->IsMinimized());
  1315. EXPECT_FALSE(overview_controller->InOverviewSession());
  1316. }
  1317. // Hides the hotseat if the hotseat is in kExtendedMode and the system tray
  1318. // is about to show (see https://crbug.com/1028321).
  1319. TEST_P(HotseatWidgetTest, DismissHotseatWhenSystemTrayShows) {
  1320. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1321. TabletModeControllerTestApi().EnterTabletMode();
  1322. std::unique_ptr<aura::Window> window =
  1323. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1324. wm::ActivateWindow(window.get());
  1325. SwipeUpOnShelf();
  1326. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1327. // Activates the system tray when hotseat is in kExtended mode and waits for
  1328. // the update in system tray to finish.
  1329. StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
  1330. const gfx::Point status_area_widget_center =
  1331. status_area_widget->GetNativeView()->GetBoundsInScreen().CenterPoint();
  1332. GetEventGenerator()->GestureTapAt(status_area_widget_center);
  1333. base::RunLoop().RunUntilIdle();
  1334. // Expects that the system tray shows and the hotseat is hidden.
  1335. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1336. EXPECT_TRUE(status_area_widget->unified_system_tray()->IsBubbleShown());
  1337. // Early out since the remaining code is only meaningful for auto-hide shelf.
  1338. if (GetPrimaryShelf()->auto_hide_behavior() !=
  1339. ShelfAutoHideBehavior::kAlways) {
  1340. return;
  1341. }
  1342. // Auto-hide shelf should show when opening the system tray.
  1343. EXPECT_EQ(ShelfAutoHideState::SHELF_AUTO_HIDE_SHOWN,
  1344. GetShelfLayoutManager()->auto_hide_state());
  1345. // Auto-hide shelf should hide when closing the system tray.
  1346. GetEventGenerator()->GestureTapAt(status_area_widget_center);
  1347. // Waits for the system tray to be closed.
  1348. base::RunLoop().RunUntilIdle();
  1349. EXPECT_EQ(ShelfAutoHideState::SHELF_AUTO_HIDE_HIDDEN,
  1350. GetShelfLayoutManager()->auto_hide_state());
  1351. }
  1352. // Tests that the hotseat hides when it is in kExtendedMode and a status area
  1353. // tray bubble is shown.
  1354. TEST_P(HotseatWidgetTest, DismissHotseatWhenStatusAreaTrayShows) {
  1355. TabletModeControllerTestApi().EnterTabletMode();
  1356. std::unique_ptr<aura::Window> window =
  1357. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1358. wm::ActivateWindow(window.get());
  1359. StatusAreaWidget* status_area_widget = GetShelfWidget()->status_area_widget();
  1360. status_area_widget->ime_menu_tray()->SetVisiblePreferred(true);
  1361. // Show the hotseat.
  1362. SwipeUpOnShelf();
  1363. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1364. EXPECT_FALSE(status_area_widget->ime_menu_tray()->GetBubbleView());
  1365. // Show the ime menu tray bubble, and wait for the hotseat to be hidden.
  1366. GetEventGenerator()->GestureTapAt(
  1367. status_area_widget->ime_menu_tray()->GetBoundsInScreen().CenterPoint());
  1368. base::RunLoop().RunUntilIdle();
  1369. // The hotseat should be hidden and the tray bubble should be shown.
  1370. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1371. EXPECT_TRUE(status_area_widget->ime_menu_tray()->GetBubbleView());
  1372. // Swiping up on the shelf should hide the tray bubble and extend the hotseat.
  1373. SwipeUpOnShelf();
  1374. EXPECT_FALSE(status_area_widget->ime_menu_tray()->GetBubbleView());
  1375. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1376. }
  1377. // Tests that the work area updates once each when going to/from tablet mode
  1378. // with no windows open.
  1379. TEST_P(HotseatWidgetTest, WorkAreaUpdatesClamshellToFromHomeLauncherNoWindows) {
  1380. DisplayWorkAreaChangeCounter counter;
  1381. TabletModeControllerTestApi().EnterTabletMode();
  1382. EXPECT_EQ(1, counter.count());
  1383. TabletModeControllerTestApi().LeaveTabletMode();
  1384. EXPECT_EQ(2, counter.count());
  1385. }
  1386. // Tests that the work area changes just once when opening a window in tablet
  1387. // mode.
  1388. TEST_P(HotseatWidgetTest, OpenWindowInTabletModeChangesWorkArea) {
  1389. DisplayWorkAreaChangeCounter counter;
  1390. TabletModeControllerTestApi().EnterTabletMode();
  1391. ASSERT_EQ(1, counter.count());
  1392. std::unique_ptr<aura::Window> window =
  1393. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1394. wm::ActivateWindow(window.get());
  1395. EXPECT_EQ(1, counter.count());
  1396. }
  1397. // Tests that going to and from tablet mode with an open window results in a
  1398. // work area change.
  1399. TEST_P(HotseatWidgetTest, ToFromTabletModeWithWindowChangesWorkArea) {
  1400. DisplayWorkAreaChangeCounter counter;
  1401. std::unique_ptr<aura::Window> window =
  1402. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1403. wm::ActivateWindow(window.get());
  1404. TabletModeControllerTestApi().EnterTabletMode();
  1405. EXPECT_EQ(1, counter.count());
  1406. TabletModeControllerTestApi().LeaveTabletMode();
  1407. EXPECT_EQ(2, counter.count());
  1408. }
  1409. // Tests that the work area changes when fullscreening the active window or
  1410. // autohiding the shelf.
  1411. TEST_P(HotseatWidgetTest, ShelfVisibilityChangeChangesWorkArea) {
  1412. UpdateDisplay("800x603");
  1413. TabletModeControllerTestApi().EnterTabletMode();
  1414. auto window = AshTestBase::CreateTestWindow(gfx::Rect(400, 400));
  1415. // The expected work area is 3 pixels smaller to leave space to swipe the auto
  1416. // hide shelf up.
  1417. const gfx::Rect expected_auto_hide_work_area(800, 600);
  1418. const gfx::Rect expected_in_app_work_area(
  1419. 800, 603 - ShelfConfig::Get()->in_app_shelf_size());
  1420. auto get_work_area = []() -> gfx::Rect {
  1421. return WorkAreaInsets::ForWindow(Shell::GetPrimaryRootWindow())
  1422. ->user_work_area_bounds();
  1423. };
  1424. DisplayWorkAreaChangeCounter counter;
  1425. WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN);
  1426. WindowState::Get(window.get())->OnWMEvent(&toggle_fullscreen);
  1427. EXPECT_EQ(expected_auto_hide_work_area, get_work_area());
  1428. EXPECT_EQ(1, counter.count());
  1429. WindowState::Get(window.get())->OnWMEvent(&toggle_fullscreen);
  1430. EXPECT_EQ(expected_in_app_work_area, get_work_area());
  1431. EXPECT_EQ(2, counter.count());
  1432. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  1433. EXPECT_EQ(expected_auto_hide_work_area, get_work_area());
  1434. EXPECT_EQ(3, counter.count());
  1435. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
  1436. EXPECT_EQ(expected_in_app_work_area, get_work_area());
  1437. EXPECT_EQ(4, counter.count());
  1438. }
  1439. // Tests that the hotseat is flush with the bottom of the screen when in
  1440. // clamshell mode and the shelf is oriented on the bottom.
  1441. TEST_P(HotseatWidgetTest, HotseatFlushWithScreenBottomInClamshell) {
  1442. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1443. const int display_height =
  1444. display::Screen::GetScreen()->GetPrimaryDisplay().bounds().height();
  1445. const int hotseat_bottom = GetPrimaryShelf()
  1446. ->shelf_widget()
  1447. ->hotseat_widget()
  1448. ->GetWindowBoundsInScreen()
  1449. .bottom();
  1450. EXPECT_EQ(hotseat_bottom, display_height);
  1451. }
  1452. // Tests that upward drag gesture from the shelf in tablet mode affects the
  1453. // active window presentation.
  1454. TEST_P(HotseatWidgetTest, DragActiveWindowInTabletMode) {
  1455. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1456. TabletModeControllerTestApi().EnterTabletMode();
  1457. std::unique_ptr<aura::Window> window =
  1458. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1459. wm::ActivateWindow(window.get());
  1460. // Swipe up to bring up the hotseat first.
  1461. SwipeUpOnShelf();
  1462. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1463. // Now swipe up again to start drag the active window.
  1464. ui::test::EventGenerator* generator = GetEventGenerator();
  1465. const gfx::Rect bottom_shelf_bounds =
  1466. GetShelfWidget()->GetWindowBoundsInScreen();
  1467. generator->MoveMouseTo(bottom_shelf_bounds.CenterPoint());
  1468. generator->PressTouch();
  1469. EXPECT_TRUE(window->layer()->transform().IsIdentity());
  1470. // Drag upward, test the window transform changes.
  1471. const gfx::Rect display_bounds =
  1472. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  1473. generator->MoveTouch(display_bounds.CenterPoint());
  1474. const gfx::Transform upward_transform = window->layer()->transform();
  1475. EXPECT_FALSE(upward_transform.IsIdentity());
  1476. // Drag downwad, test the window tranfrom changes.
  1477. generator->MoveTouch(display_bounds.bottom_center());
  1478. const gfx::Transform downward_transform = window->layer()->transform();
  1479. EXPECT_NE(upward_transform, downward_transform);
  1480. generator->ReleaseTouch();
  1481. EXPECT_TRUE(window->layer()->transform().IsIdentity());
  1482. }
  1483. // Tests that when hotseat and drag-window-to-overview features are both
  1484. // enabled, hotseat is not extended after dragging a window to overview, and
  1485. // then activating the window.
  1486. TEST_P(HotseatWidgetTest, ExitingOverviewHidesHotseat) {
  1487. const ShelfAutoHideBehavior auto_hide_behavior = shelf_auto_hide_behavior();
  1488. GetPrimaryShelf()->SetAutoHideBehavior(auto_hide_behavior);
  1489. TabletModeControllerTestApi().EnterTabletMode();
  1490. std::unique_ptr<aura::Window> window =
  1491. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1492. wm::ActivateWindow(window.get());
  1493. // If the shelf is auto-hidden, swipe up to bring up shelf and hotseat first
  1494. // (otherwise, the window drag to overview will not be handled).
  1495. if (auto_hide_behavior == ShelfAutoHideBehavior::kAlways) {
  1496. SwipeUpOnShelf();
  1497. ASSERT_EQ(HotseatState::kExtended,
  1498. GetShelfLayoutManager()->hotseat_state());
  1499. }
  1500. // Swipe up to start dragging the active window.
  1501. const gfx::Rect bottom_shelf_bounds =
  1502. GetShelfWidget()->GetWindowBoundsInScreen();
  1503. StartScroll(bottom_shelf_bounds.CenterPoint());
  1504. // Ensure swipe goes past the top of the hotseat first to activate the window
  1505. // drag controller.
  1506. UpdateScroll(
  1507. -GetPrimaryShelf()->hotseat_widget()->GetHotseatFullDragAmount());
  1508. // Drag upward, to the center of the screen, and release (this should enter
  1509. // the overview).
  1510. const gfx::Rect display_bounds =
  1511. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  1512. UpdateScroll(display_bounds.CenterPoint().y() -
  1513. bottom_shelf_bounds.CenterPoint().y());
  1514. // Small scroll update, to simulate the user holding the pointer.
  1515. UpdateScroll(2);
  1516. DragWindowFromShelfController* window_drag_controller =
  1517. GetShelfLayoutManager()->window_drag_controller_for_testing();
  1518. ASSERT_TRUE(window_drag_controller);
  1519. DragWindowFromShelfControllerTestApi test_api;
  1520. test_api.WaitUntilOverviewIsShown(window_drag_controller);
  1521. EndScroll(/*is_fling=*/false, 0.f);
  1522. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1523. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1524. EXPECT_TRUE(overview_controller->InOverviewSession());
  1525. // Activate the window - the overview session should exit, and hotseat should
  1526. // be hidden.
  1527. wm::ActivateWindow(window.get());
  1528. EXPECT_FALSE(overview_controller->InOverviewSession());
  1529. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1530. }
  1531. // Tests that failing to drag the maximized window to overview mode results in
  1532. // an extended hotseat.
  1533. TEST_P(HotseatWidgetTest, FailingOverviewDragResultsInExtendedHotseat) {
  1534. const ShelfAutoHideBehavior auto_hide_behavior = shelf_auto_hide_behavior();
  1535. GetPrimaryShelf()->SetAutoHideBehavior(auto_hide_behavior);
  1536. TabletModeControllerTestApi().EnterTabletMode();
  1537. std::unique_ptr<aura::Window> window =
  1538. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1539. wm::ActivateWindow(window.get());
  1540. // If the shelf is auto-hidden, swipe up to bring up shelf and hotseat first
  1541. // (otherwise, the window drag to overview will not be handled).
  1542. if (auto_hide_behavior == ShelfAutoHideBehavior::kAlways) {
  1543. SwipeUpOnShelf();
  1544. ASSERT_EQ(HotseatState::kExtended,
  1545. GetShelfLayoutManager()->hotseat_state());
  1546. }
  1547. // Swipe up to start dragging the active window.
  1548. const gfx::Rect bottom_shelf_bounds =
  1549. GetShelfWidget()->GetWindowBoundsInScreen();
  1550. StartScroll(bottom_shelf_bounds.top_center());
  1551. const int extended_hotseat_distance_from_top_of_shelf =
  1552. ShelfConfig::Get()->hotseat_bottom_padding() +
  1553. GetPrimaryShelf()->hotseat_widget()->GetHotseatSize();
  1554. // Overview is triggered when the bottom of the dragged window goes past the
  1555. // top of the hotseat. The window scaling and translation are handled slightly
  1556. // differently for if the hotseat is extended or not.
  1557. if (HotseatState::kExtended == GetShelfLayoutManager()->hotseat_state()) {
  1558. // Drag upward, a bit below the hotseat extended height, to ensure that the
  1559. // bottom of the dragged window doesn't go past the top of the hotseat, so
  1560. // that it doesn't go into overview.
  1561. UpdateScroll(-extended_hotseat_distance_from_top_of_shelf + 20);
  1562. } else {
  1563. // Drag upward, a bit past the hotseat extended height so that the window
  1564. // drag controller is activated, but not enough to go to overview.
  1565. UpdateScroll(-extended_hotseat_distance_from_top_of_shelf - 30);
  1566. }
  1567. EndScroll(/*is_fling=*/false, 0.f);
  1568. ASSERT_FALSE(Shell::Get()->overview_controller()->InOverviewSession());
  1569. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1570. }
  1571. // Tests that hotseat remains in extended state while in overview mode when
  1572. // flinging the shelf up or down.
  1573. TEST_P(HotseatWidgetTest, SwipeOnHotseatInOverview) {
  1574. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1575. TabletModeControllerTestApi().EnterTabletMode();
  1576. std::unique_ptr<aura::Window> window =
  1577. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1578. wm::ActivateWindow(window.get());
  1579. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1580. EnterOverview();
  1581. Shelf* const shelf = GetPrimaryShelf();
  1582. SwipeUpOnShelf();
  1583. EXPECT_TRUE(overview_controller->InOverviewSession());
  1584. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1585. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1586. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1587. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1588. } else {
  1589. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1590. }
  1591. // Drag from the hotseat to the bezel, the hotseat should remain in extended
  1592. // state.
  1593. DragHotseatDownToBezel();
  1594. EXPECT_TRUE(overview_controller->InOverviewSession());
  1595. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1596. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1597. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1598. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1599. } else {
  1600. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1601. }
  1602. SwipeUpOnShelf();
  1603. EXPECT_TRUE(overview_controller->InOverviewSession());
  1604. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1605. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1606. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1607. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1608. } else {
  1609. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1610. }
  1611. }
  1612. TEST_P(HotseatWidgetTest, SwipeOnHotseatInSplitViewWithOverview) {
  1613. Shelf* const shelf = GetPrimaryShelf();
  1614. shelf->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1615. TabletModeControllerTestApi().EnterTabletMode();
  1616. std::unique_ptr<aura::Window> window =
  1617. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1618. wm::ActivateWindow(window.get());
  1619. OverviewController* overview_controller = Shell::Get()->overview_controller();
  1620. EnterOverview();
  1621. SplitViewController* split_view_controller =
  1622. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  1623. split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
  1624. SwipeUpOnShelf();
  1625. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1626. EXPECT_TRUE(overview_controller->InOverviewSession());
  1627. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1628. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1629. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1630. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1631. } else {
  1632. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1633. }
  1634. DragHotseatDownToBezel();
  1635. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1636. EXPECT_TRUE(overview_controller->InOverviewSession());
  1637. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1638. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1639. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1640. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1641. } else {
  1642. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1643. }
  1644. SwipeUpOnShelf();
  1645. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1646. EXPECT_TRUE(overview_controller->InOverviewSession());
  1647. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1648. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1649. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1650. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1651. } else {
  1652. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1653. }
  1654. }
  1655. TEST_P(HotseatWidgetTest, SwipeOnHotseatInSplitView) {
  1656. Shelf* const shelf = GetPrimaryShelf();
  1657. shelf->SetAutoHideBehavior(shelf_auto_hide_behavior());
  1658. TabletModeControllerTestApi().EnterTabletMode();
  1659. std::unique_ptr<aura::Window> window1 =
  1660. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1661. std::unique_ptr<aura::Window> window2 =
  1662. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1663. wm::ActivateWindow(window1.get());
  1664. SplitViewController* split_view_controller =
  1665. SplitViewController::Get(Shell::GetPrimaryRootWindow());
  1666. split_view_controller->SnapWindow(window1.get(), SplitViewController::LEFT);
  1667. split_view_controller->SnapWindow(window2.get(), SplitViewController::RIGHT);
  1668. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1669. SwipeUpOnShelf();
  1670. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1671. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1672. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1673. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1674. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1675. } else {
  1676. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1677. }
  1678. DragHotseatDownToBezel();
  1679. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1680. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1681. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1682. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1683. EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
  1684. } else {
  1685. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1686. }
  1687. SwipeUpOnShelf();
  1688. EXPECT_TRUE(split_view_controller->InSplitViewMode());
  1689. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1690. if (shelf_auto_hide_behavior() == ShelfAutoHideBehavior::kAlways) {
  1691. EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  1692. EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
  1693. } else {
  1694. EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
  1695. }
  1696. }
  1697. // Tests that swiping downward, towards the bezel, from a variety of points
  1698. // results in hiding the hotseat.
  1699. TEST_P(HotseatWidgetTest, HotseatHidesWhenSwipedToBezel) {
  1700. // Go to in-app shelf and extend the hotseat.
  1701. TabletModeControllerTestApi().EnterTabletMode();
  1702. std::unique_ptr<aura::Window> window =
  1703. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1704. wm::ActivateWindow(window.get());
  1705. SwipeUpOnShelf();
  1706. // Drag from the hotseat to the bezel, the hotseat should hide.
  1707. DragHotseatDownToBezel();
  1708. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1709. // Reset the hotseat and swipe from the center of the hotseat, it should hide.
  1710. SwipeUpOnShelf();
  1711. gfx::Rect shelf_widget_bounds = GetShelfWidget()->GetWindowBoundsInScreen();
  1712. gfx::Rect hotseat_bounds =
  1713. GetPrimaryShelf()->hotseat_widget()->GetWindowBoundsInScreen();
  1714. gfx::Point start = hotseat_bounds.CenterPoint();
  1715. const gfx::Point end =
  1716. gfx::Point(shelf_widget_bounds.x() + shelf_widget_bounds.width() / 2,
  1717. shelf_widget_bounds.bottom() + 1);
  1718. const base::TimeDelta kTimeDelta = base::Milliseconds(100);
  1719. const int kNumScrollSteps = 4;
  1720. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  1721. kNumScrollSteps);
  1722. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1723. // Reset the hotseat and swipe from the bottom of the hotseat, it should hide.
  1724. SwipeUpOnShelf();
  1725. start = hotseat_bounds.bottom_center();
  1726. start.Offset(0, -1);
  1727. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  1728. kNumScrollSteps);
  1729. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1730. // Reset the hotseat and swipe from the center of the in-app shelf, it should
  1731. // hide.
  1732. SwipeUpOnShelf();
  1733. start = shelf_widget_bounds.CenterPoint();
  1734. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  1735. kNumScrollSteps);
  1736. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1737. // Reset the hotseat and swipe from the bottom of the in-app shelf, it should
  1738. // hide.
  1739. SwipeUpOnShelf();
  1740. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1741. start = shelf_widget_bounds.bottom_center();
  1742. // The first few events which get sent to ShelfLayoutManager are
  1743. // ui::ET_TAP_DOWN, and ui::ET_GESTURE_START. After a few px we get
  1744. // ui::ET_GESTURE_SCROLL_UPDATE. Add 6 px of slop to get the first events out
  1745. // of the way, and 1 extra px to ensure we are not on the bottom edge of the
  1746. // display.
  1747. start.Offset(0, -7);
  1748. GetEventGenerator()->GestureScrollSequence(start, end, kTimeDelta,
  1749. kNumScrollSteps);
  1750. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1751. }
  1752. // Tests that flinging up the in-app shelf should show the hotseat.
  1753. TEST_P(HotseatWidgetTest, FlingUpHotseatWithShortFling) {
  1754. TabletModeControllerTestApi().EnterTabletMode();
  1755. std::unique_ptr<aura::Window> window =
  1756. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1757. wm::ActivateWindow(window.get());
  1758. GetAppListTestHelper()->CheckVisibility(false);
  1759. base::HistogramTester histogram_tester;
  1760. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  1761. InAppShelfGestures::kSwipeUpToShow, 0);
  1762. // Scrolls the hotseat by a distance not sufficuent to trigger the action of
  1763. // entering home screen from the in-app shelf.
  1764. gfx::Rect display_bounds =
  1765. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  1766. const gfx::Point start(display_bounds.bottom_center());
  1767. const gfx::Point end(start + gfx::Vector2d(0, -20));
  1768. const int fling_speed =
  1769. DragWindowFromShelfController::kVelocityToHomeScreenThreshold + 1;
  1770. const int scroll_steps = 20;
  1771. base::TimeDelta scroll_time =
  1772. GetEventGenerator()->CalculateScrollDurationForFlingVelocity(
  1773. start, end, fling_speed, scroll_steps);
  1774. GetEventGenerator()->GestureScrollSequence(start, end, scroll_time,
  1775. scroll_steps);
  1776. base::RunLoop().RunUntilIdle();
  1777. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1778. GetAppListTestHelper()->CheckVisibility(false);
  1779. histogram_tester.ExpectBucketCount(kHotseatGestureHistogramName,
  1780. InAppShelfGestures::kSwipeUpToShow, 1);
  1781. }
  1782. // Tests that flinging up the in-app shelf should show the home launcher if the
  1783. // gesture distance is long enough.
  1784. TEST_P(HotseatWidgetTest, FlingUpHotseatWithLongFling) {
  1785. TabletModeControllerTestApi().EnterTabletMode();
  1786. std::unique_ptr<aura::Window> window =
  1787. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1788. wm::ActivateWindow(window.get());
  1789. GetAppListTestHelper()->CheckVisibility(false);
  1790. base::HistogramTester histogram_tester;
  1791. histogram_tester.ExpectBucketCount(
  1792. kHotseatGestureHistogramName,
  1793. InAppShelfGestures::kFlingUpToShowHomeScreen, 0);
  1794. // Scrolls the hotseat by the sufficient distance to trigger the action of
  1795. // entering home screen from the in-app shelf.
  1796. gfx::Rect display_bounds =
  1797. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  1798. const gfx::Point start(display_bounds.bottom_center());
  1799. const gfx::Point end(start + gfx::Vector2d(0, -200));
  1800. const int fling_speed =
  1801. DragWindowFromShelfController::kVelocityToHomeScreenThreshold + 1;
  1802. const int scroll_steps = 20;
  1803. base::TimeDelta scroll_time =
  1804. GetEventGenerator()->CalculateScrollDurationForFlingVelocity(
  1805. start, end, fling_speed, scroll_steps);
  1806. GetEventGenerator()->GestureScrollSequence(start, end, scroll_time,
  1807. scroll_steps);
  1808. base::RunLoop().RunUntilIdle();
  1809. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  1810. GetShelfLayoutManager()->hotseat_state());
  1811. GetAppListTestHelper()->CheckVisibility(true);
  1812. histogram_tester.ExpectBucketCount(
  1813. kHotseatGestureHistogramName,
  1814. InAppShelfGestures::kFlingUpToShowHomeScreen, 1);
  1815. }
  1816. // Tests that UpdateVisibilityState is ignored during a shelf drag. This
  1817. // prevents drag from getting interrupted.
  1818. TEST_P(HotseatWidgetTest, NoVisibilityStateUpdateDuringDrag) {
  1819. // Autohide the shelf, then start a shelf drag.
  1820. GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  1821. std::unique_ptr<aura::Window> window1 =
  1822. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1823. wm::ActivateWindow(window1.get());
  1824. ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN, GetPrimaryShelf()->GetAutoHideState());
  1825. // Drag the autohidden shelf up a bit, then open a new window and activate it
  1826. // during the drag. The shelf state should not change.
  1827. gfx::Point start_drag = GetVisibleShelfWidgetBoundsInScreen().top_center();
  1828. GetEventGenerator()->set_current_screen_location(start_drag);
  1829. GetEventGenerator()->PressTouch();
  1830. GetEventGenerator()->MoveTouchBy(0, -2);
  1831. auto shelf_state_watcher = std::make_unique<ShelfStateWatcher>();
  1832. std::unique_ptr<aura::Window> window2 =
  1833. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1834. wm::ActivateWindow(window2.get());
  1835. window2->SetBounds(gfx::Rect(0, 0, 200, 200));
  1836. EXPECT_EQ(0, shelf_state_watcher->state_change_count());
  1837. }
  1838. // Tests that when tablet mode has ended, the hotseat background is no longer
  1839. // visible. See crbug/1050383
  1840. TEST_P(HotseatWidgetTest, HotseatBackgroundDisappearsAfterTabletModeEnd) {
  1841. HotseatWidget* hotseat = GetPrimaryShelf()->hotseat_widget();
  1842. EXPECT_FALSE(hotseat->GetIsTranslucentBackgroundVisibleForTest());
  1843. TabletModeControllerTestApi().EnterTabletMode();
  1844. EXPECT_TRUE(hotseat->GetIsTranslucentBackgroundVisibleForTest());
  1845. TabletModeControllerTestApi().LeaveTabletMode();
  1846. EXPECT_FALSE(hotseat->GetIsTranslucentBackgroundVisibleForTest());
  1847. }
  1848. // Tests that popups don't activate the hotseat. (crbug.com/1018266)
  1849. TEST_P(HotseatWidgetTest, HotseatRemainsHiddenIfPopupLaunched) {
  1850. // Go to in-app shelf and extend the hotseat.
  1851. TabletModeControllerTestApi().EnterTabletMode();
  1852. std::unique_ptr<aura::Window> window =
  1853. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1854. wm::ActivateWindow(window.get());
  1855. SwipeUpOnShelf();
  1856. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1857. // Hide hotseat by clicking outside its bounds.
  1858. gfx::Rect hotseat_bounds =
  1859. GetPrimaryShelf()->hotseat_widget()->GetWindowBoundsInScreen();
  1860. gfx::Point start = hotseat_bounds.top_center();
  1861. GetEventGenerator()->GestureTapAt(gfx::Point(start.x() + 1, start.y() - 1));
  1862. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1863. // Create a popup window and wait until all actions finish. The hotseat should
  1864. // remain hidden.
  1865. aura::Window* window_2 = CreateTestWindowInParent(window.get());
  1866. window_2->SetBounds(gfx::Rect(201, 0, 100, 100));
  1867. window_2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  1868. window_2->Show();
  1869. GetAppListTestHelper()->WaitUntilIdle();
  1870. EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1871. }
  1872. // Tests that blur is not showing during animations.
  1873. TEST_P(HotseatWidgetTest, NoBlurDuringAnimations) {
  1874. TabletModeControllerTestApi().EnterTabletMode();
  1875. ASSERT_EQ(
  1876. ShelfConfig::Get()->shelf_blur_radius(),
  1877. GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  1878. ui::ScopedAnimationDurationScaleMode regular_animations(
  1879. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  1880. // Open a window, as the hotseat animates to kHidden, it should lose its blur.
  1881. std::unique_ptr<aura::Window> window =
  1882. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1883. wm::ActivateWindow(window.get());
  1884. EXPECT_EQ(
  1885. 0, GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  1886. // Wait for the animation to finish, hotseat blur should return.
  1887. ShellTestApi().WaitForWindowFinishAnimating(window.get());
  1888. EXPECT_EQ(
  1889. ShelfConfig::Get()->shelf_blur_radius(),
  1890. GetShelfWidget()->hotseat_widget()->GetHotseatBackgroundBlurForTest());
  1891. }
  1892. // Tests that hotseat bounds don't jump when transitioning from drag to
  1893. // animation.
  1894. TEST_P(HotseatWidgetTest, AnimationAfterDrag) {
  1895. TabletModeControllerTestApi().EnterTabletMode();
  1896. // Add an app to shelf - the app will be used to track the shelf view position
  1897. // throughout the test.
  1898. ShelfTestUtil::AddAppShortcut("fake_app", TYPE_PINNED_APP);
  1899. // Open a window so the hotseat transitions to hidden state.
  1900. std::unique_ptr<aura::Window> window =
  1901. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1902. wm::ActivateWindow(window.get());
  1903. ui::ScopedAnimationDurationScaleMode animation_duration(
  1904. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  1905. HotseatWidget* const hotseat_widget = GetPrimaryShelf()->hotseat_widget();
  1906. gfx::Point last_app_views_position =
  1907. hotseat_widget->GetWindowBoundsInScreen().origin();
  1908. // Returns whether the hotseat vertical position has changed comapred to
  1909. // |last_hotseat_y|, and updates |last_hotseat_y| to match the current hotseat
  1910. // position.
  1911. auto app_views_moved = [&last_app_views_position, &hotseat_widget]() -> bool {
  1912. gfx::Point app_views_position =
  1913. ShelfViewTestAPI(hotseat_widget->scrollable_shelf_view()->shelf_view())
  1914. .GetViewAt(0)
  1915. ->GetBoundsInScreen()
  1916. .origin();
  1917. hotseat_widget->GetLayer()->transform().TransformPoint(&app_views_position);
  1918. const bool position_changed = app_views_position != last_app_views_position;
  1919. last_app_views_position = app_views_position;
  1920. return position_changed;
  1921. };
  1922. ui::test::EventGenerator* generator = GetEventGenerator();
  1923. const gfx::Rect display_bounds =
  1924. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  1925. // Drag upwards from the bottom of the screen to bring up hotseat - this
  1926. // should request presentation time metric to be reported.
  1927. generator->PressTouch(display_bounds.bottom_center());
  1928. // Drag the hotseat upward, by the height of the shelf.
  1929. const int shelf_height = GetShelfWidget()->GetWindowBoundsInScreen().height();
  1930. generator->MoveTouchBy(0, -shelf_height);
  1931. ASSERT_TRUE(app_views_moved());
  1932. // Release touch, and verify the hotseat position remained the same.
  1933. generator->ReleaseTouch();
  1934. EXPECT_FALSE(app_views_moved());
  1935. // Wait for the hotseat to animate to extended state.
  1936. ShellTestApi().WaitForWindowFinishAnimating(
  1937. hotseat_widget->GetNativeWindow());
  1938. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  1939. EXPECT_TRUE(app_views_moved());
  1940. // Drag hotseat down.
  1941. generator->PressTouch(hotseat_widget->GetWindowBoundsInScreen().top_center());
  1942. generator->MoveTouchBy(0, shelf_height);
  1943. ASSERT_TRUE(app_views_moved());
  1944. // Release touch, and verify the hotseat position remained the same.
  1945. generator->ReleaseTouch();
  1946. EXPECT_FALSE(app_views_moved());
  1947. // Wait for the hotseat to animate to extended state.
  1948. ShellTestApi().WaitForWindowFinishAnimating(
  1949. hotseat_widget->GetNativeWindow());
  1950. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  1951. ASSERT_TRUE(app_views_moved());
  1952. // Drag the hotseat back up, and release so animation to extended state
  1953. // starts.
  1954. generator->PressTouch(display_bounds.bottom_center());
  1955. generator->MoveTouchBy(0, -shelf_height);
  1956. ASSERT_TRUE(app_views_moved());
  1957. generator->ReleaseTouch();
  1958. EXPECT_FALSE(app_views_moved());
  1959. // Close the test widget to start transition to the shown state.
  1960. window.reset();
  1961. // The apparent hotseat bound should remain the same as the transition to show
  1962. // state starts.
  1963. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  1964. GetShelfLayoutManager()->hotseat_state());
  1965. EXPECT_FALSE(app_views_moved());
  1966. // Finish the animation to shown state.
  1967. ShellTestApi().WaitForWindowFinishAnimating(
  1968. hotseat_widget->GetNativeWindow());
  1969. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  1970. GetShelfLayoutManager()->hotseat_state());
  1971. EXPECT_TRUE(app_views_moved());
  1972. }
  1973. // Tests that hotseat bounds don't jump when the hotseat widget is translated
  1974. // when a transitionj animation starts.
  1975. TEST_P(HotseatWidgetTest, InitialAnimationPositionWithNonIdentityTransform) {
  1976. TabletModeControllerTestApi().EnterTabletMode();
  1977. // Add an app to shelf - the app will be used to track the shelf view position
  1978. // throughout the test.
  1979. ShelfTestUtil::AddAppShortcut("fake_app", TYPE_PINNED_APP);
  1980. // Open a window so the hotseat transitions to hidden state.
  1981. std::unique_ptr<aura::Window> window =
  1982. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  1983. wm::ActivateWindow(window.get());
  1984. // Make sure that all shelf item views complete their bounds animations
  1985. // before starting the test (tests depend on the first item bounds within the
  1986. // shelf view).
  1987. auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  1988. ShelfViewTestAPI(shelf_view).RunMessageLoopUntilAnimationsDone();
  1989. HotseatWidget* const hotseat_widget = GetPrimaryShelf()->hotseat_widget();
  1990. gfx::Point last_app_views_position =
  1991. hotseat_widget->GetWindowBoundsInScreen().origin();
  1992. // Returns whether the hotseat vertical position has changed comapred to
  1993. // |last_hotseat_y|, and updates |last_hotseat_y| to match the current hotseat
  1994. // position.
  1995. auto app_views_moved = [&last_app_views_position, &hotseat_widget]() -> bool {
  1996. gfx::Point app_views_position =
  1997. ShelfViewTestAPI(hotseat_widget->scrollable_shelf_view()->shelf_view())
  1998. .GetViewAt(0)
  1999. ->GetBoundsInScreen()
  2000. .origin();
  2001. hotseat_widget->GetLayer()->transform().TransformPoint(&app_views_position);
  2002. const bool position_changed = app_views_position != last_app_views_position;
  2003. last_app_views_position = app_views_position;
  2004. return position_changed;
  2005. };
  2006. ui::test::EventGenerator* generator = GetEventGenerator();
  2007. const gfx::Rect display_bounds =
  2008. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  2009. // Drag upwards from the bottom of the screen to bring up hotseat - this
  2010. // should request presentation time metric to be reported.
  2011. generator->PressTouch(display_bounds.bottom_center());
  2012. // Drag the hotseat upward, to transition hotseat to the extended state.
  2013. const int shelf_height = GetShelfWidget()->GetWindowBoundsInScreen().height();
  2014. generator->MoveTouchBy(0, -shelf_height);
  2015. // Release touch, and verify the hotseat position remained the same.
  2016. generator->ReleaseTouch();
  2017. ASSERT_TRUE(app_views_moved());
  2018. ui::ScopedAnimationDurationScaleMode animation_duration(
  2019. ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  2020. auto set_animated_transform = [](ui::Layer* layer,
  2021. const gfx::Vector2d& initial_offset) {
  2022. // Set translate animation on the hotseat widget, to simulate a state which
  2023. // the widget may have while a transform animation is in progress.
  2024. gfx::Transform initial_transform;
  2025. initial_transform.Translate(initial_offset.x(), initial_offset.y());
  2026. layer->SetTransform(initial_transform);
  2027. // Set up an animation to identity transform.
  2028. ui::ScopedLayerAnimationSettings animation(layer->GetAnimator());
  2029. animation.SetTransitionDuration(base::Milliseconds(300));
  2030. layer->SetTransform(gfx::Transform());
  2031. };
  2032. set_animated_transform(hotseat_widget->GetLayer(), gfx::Vector2d(0, -10));
  2033. ASSERT_TRUE(app_views_moved());
  2034. // Tap in the middle of the screen to initiate transition to hidden state.
  2035. generator->GestureTapAt(display_bounds.CenterPoint());
  2036. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  2037. // Verify the current hotseat position remains unchanged.
  2038. EXPECT_FALSE(app_views_moved());
  2039. // Wait for the hotseat animation to hidden state to finish.
  2040. ShellTestApi().WaitForWindowFinishAnimating(
  2041. hotseat_widget->GetNativeWindow());
  2042. ASSERT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
  2043. EXPECT_TRUE(app_views_moved());
  2044. // Set the hotseat widget transform again.
  2045. set_animated_transform(hotseat_widget->GetLayer(), gfx::Vector2d(0, -10));
  2046. ASSERT_TRUE(app_views_moved());
  2047. // CLose the window to transition to the shown state.
  2048. window.reset();
  2049. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  2050. GetShelfLayoutManager()->hotseat_state());
  2051. // The apparent hotseat bound should remain the same as the transition to show
  2052. // state starts.
  2053. EXPECT_FALSE(app_views_moved());
  2054. // Finish the animation to shown state.
  2055. ShellTestApi().WaitForWindowFinishAnimating(
  2056. hotseat_widget->GetNativeWindow());
  2057. EXPECT_TRUE(app_views_moved());
  2058. // Open another widow, and move the hotseat to extended state.
  2059. window = AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  2060. wm::ActivateWindow(window.get());
  2061. generator->PressTouch(display_bounds.bottom_center());
  2062. generator->MoveTouchBy(0, -shelf_height);
  2063. generator->ReleaseTouch();
  2064. ShellTestApi().WaitForWindowFinishAnimating(
  2065. hotseat_widget->GetNativeWindow());
  2066. ASSERT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  2067. set_animated_transform(hotseat_widget->GetLayer(), gfx::Vector2d(0, -10));
  2068. ASSERT_TRUE(app_views_moved());
  2069. // Close the window to transition to shown hotseat state.
  2070. window.reset();
  2071. ASSERT_EQ(HotseatState::kShownHomeLauncher,
  2072. GetShelfLayoutManager()->hotseat_state());
  2073. // The apparent hotseat bound should remain the same as the transition to show
  2074. // state starts.
  2075. EXPECT_FALSE(app_views_moved());
  2076. // Finish the animation to shown state.
  2077. ShellTestApi().WaitForWindowFinishAnimating(
  2078. hotseat_widget->GetNativeWindow());
  2079. EXPECT_TRUE(app_views_moved());
  2080. }
  2081. TEST_P(HotseatWidgetTest, PresentationTimeMetricDuringDrag) {
  2082. ui::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(
  2083. true);
  2084. std::unique_ptr<aura::Window> window =
  2085. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  2086. wm::ActivateWindow(window.get());
  2087. GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
  2088. TabletModeControllerTestApi().EnterTabletMode();
  2089. ui::test::EventGenerator* generator = GetEventGenerator();
  2090. const gfx::Rect display_bounds =
  2091. display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  2092. // Drag upwards from the bottom of the screen to bring up hotseat - this
  2093. // should request presentation time metric to be reported.
  2094. generator->PressTouch(display_bounds.bottom_center());
  2095. HotseatWidget* const hotseat_widget = GetPrimaryShelf()->hotseat_widget();
  2096. int last_hotseat_y = hotseat_widget->GetWindowBoundsInScreen().y();
  2097. // Returns whether the hotseat vertical position has changed comapred to
  2098. // |last_hotseat_y|, and updates |last_hotseat_y| to match the current hotseat
  2099. // position.
  2100. auto hotseat_moved = [&last_hotseat_y, &hotseat_widget]() -> bool {
  2101. const int hotseat_y = hotseat_widget->GetWindowBoundsInScreen().y();
  2102. const bool y_changed = hotseat_y != last_hotseat_y;
  2103. last_hotseat_y = hotseat_y;
  2104. return y_changed;
  2105. };
  2106. base::HistogramTester histogram_tester;
  2107. auto check_bucket_size = [&histogram_tester](int expected_size) {
  2108. histogram_tester.ExpectTotalCount(
  2109. "Ash.HotseatTransition.Drag.PresentationTime", expected_size);
  2110. histogram_tester.ExpectTotalCount(
  2111. "Ash.HotseatTransition.Drag.PresentationTime.MaxLatency", 0);
  2112. };
  2113. int expected_bucket_size = 0;
  2114. {
  2115. SCOPED_TRACE("Initial state");
  2116. check_bucket_size(expected_bucket_size);
  2117. }
  2118. const int shelf_height = GetShelfWidget()->GetWindowBoundsInScreen().height();
  2119. {
  2120. SCOPED_TRACE("Upward drag with move - 1");
  2121. generator->MoveTouchBy(0, -shelf_height / 2);
  2122. ASSERT_TRUE(hotseat_moved());
  2123. check_bucket_size(++expected_bucket_size);
  2124. }
  2125. {
  2126. SCOPED_TRACE("Upward drag with move - 2");
  2127. generator->MoveTouchBy(0, -shelf_height / 2);
  2128. ASSERT_TRUE(hotseat_moved());
  2129. check_bucket_size(++expected_bucket_size);
  2130. }
  2131. {
  2132. SCOPED_TRACE("Downward drag with move");
  2133. generator->MoveTouchBy(0, shelf_height / 2);
  2134. ASSERT_TRUE(hotseat_moved());
  2135. check_bucket_size(++expected_bucket_size);
  2136. }
  2137. {
  2138. SCOPED_TRACE("Upward drag with move - 3");
  2139. generator->MoveTouchBy(0, -shelf_height / 2);
  2140. ASSERT_TRUE(hotseat_moved());
  2141. check_bucket_size(++expected_bucket_size);
  2142. }
  2143. const int hotseat_height =
  2144. GetPrimaryShelf()->hotseat_widget()->GetWindowBoundsInScreen().height();
  2145. {
  2146. SCOPED_TRACE("Upward drag with move above shelf - 1");
  2147. generator->MoveTouchBy(0, -hotseat_height / 2);
  2148. ASSERT_TRUE(hotseat_moved());
  2149. check_bucket_size(++expected_bucket_size);
  2150. }
  2151. {
  2152. SCOPED_TRACE("Upward drag with move above shelf - 2");
  2153. generator->MoveTouchBy(0, -hotseat_height / 2);
  2154. ASSERT_TRUE(hotseat_moved());
  2155. check_bucket_size(++expected_bucket_size);
  2156. }
  2157. {
  2158. SCOPED_TRACE("Downward drag with move above shelf");
  2159. generator->MoveTouchBy(0, hotseat_height / 2);
  2160. ASSERT_TRUE(hotseat_moved());
  2161. check_bucket_size(++expected_bucket_size);
  2162. }
  2163. {
  2164. SCOPED_TRACE("Upward drag with move above shelf - 3");
  2165. generator->MoveTouchBy(0, -hotseat_height - hotseat_height / 2);
  2166. ASSERT_TRUE(hotseat_moved());
  2167. check_bucket_size(++expected_bucket_size);
  2168. }
  2169. // Once the hotseat has been fully extended, presentation time metric should
  2170. // stop being reported, as the hotseat is expected to stop moving.
  2171. {
  2172. SCOPED_TRACE("Upward drag without moving - 1");
  2173. generator->MoveTouchBy(0, -hotseat_height);
  2174. ASSERT_FALSE(hotseat_moved());
  2175. check_bucket_size(expected_bucket_size);
  2176. }
  2177. {
  2178. SCOPED_TRACE("Upward drag without moving - 2");
  2179. generator->MoveTouchBy(0, -hotseat_height / 2);
  2180. ASSERT_FALSE(hotseat_moved());
  2181. check_bucket_size(expected_bucket_size);
  2182. }
  2183. // Move hotseat downwards - the presentation time should not get reported
  2184. // until the hotseat starts moving downwards.
  2185. {
  2186. SCOPED_TRACE("Downward drag without moving - 1");
  2187. generator->MoveTouchBy(0, hotseat_height / 2);
  2188. ASSERT_FALSE(hotseat_moved());
  2189. check_bucket_size(expected_bucket_size);
  2190. }
  2191. {
  2192. SCOPED_TRACE("Downward drag without moving - 2");
  2193. generator->MoveTouchBy(0, hotseat_height);
  2194. ASSERT_FALSE(hotseat_moved());
  2195. check_bucket_size(expected_bucket_size);
  2196. }
  2197. generator->ReleaseTouch();
  2198. window.reset();
  2199. {
  2200. SCOPED_TRACE("Drag ended.");
  2201. histogram_tester.ExpectTotalCount(
  2202. "Ash.HotseatTransition.Drag.PresentationTime", expected_bucket_size);
  2203. histogram_tester.ExpectTotalCount(
  2204. "Ash.HotseatTransition.Drag.PresentationTime.MaxLatency", 1);
  2205. }
  2206. }
  2207. // TODO(manucornet): Enable this test once the new API for layer animation
  2208. // sequence observers is available.
  2209. TEST_P(HotseatWidgetTest, DISABLED_OverviewToHomeAnimationAndBackIsSmooth) {
  2210. // Go into tablet mode and make sure animations are over.
  2211. HotseatWidget* hotseat = GetPrimaryShelf()->hotseat_widget();
  2212. views::WidgetAnimationWaiter waiter(hotseat);
  2213. TabletModeControllerTestApi().EnterTabletMode();
  2214. waiter.WaitForAnimation();
  2215. ui::ScopedAnimationDurationScaleMode regular_animations(
  2216. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  2217. // Go into overview and back to know what to expect in terms of bounds.
  2218. const gfx::Rect shown_hotseat_bounds = hotseat->GetWindowBoundsInScreen();
  2219. {
  2220. views::WidgetAnimationWaiter waiter(hotseat);
  2221. StartOverview();
  2222. waiter.WaitForAnimation();
  2223. }
  2224. const gfx::Rect extended_hotseat_bounds = hotseat->GetWindowBoundsInScreen();
  2225. {
  2226. views::WidgetAnimationWaiter waiter(hotseat);
  2227. EndOverview();
  2228. waiter.WaitForAnimation();
  2229. }
  2230. // The extended hotseat should be higher (lower value of Y) than the
  2231. // shown hotseat.
  2232. EXPECT_GT(shown_hotseat_bounds.y(), extended_hotseat_bounds.y());
  2233. // We should start with the hotseat in its shown position again.
  2234. EXPECT_EQ(shown_hotseat_bounds, hotseat->GetWindowBoundsInScreen());
  2235. {
  2236. WidgetAnimationSmoothnessInspector inspector(hotseat);
  2237. views::WidgetAnimationWaiter waiter(hotseat);
  2238. StartOverview();
  2239. waiter.WaitForAnimation();
  2240. EXPECT_TRUE(inspector.CheckAnimation(4));
  2241. }
  2242. // The hotseat should now be extended.
  2243. EXPECT_EQ(extended_hotseat_bounds, hotseat->GetWindowBoundsInScreen());
  2244. {
  2245. WidgetAnimationSmoothnessInspector inspector(hotseat);
  2246. views::WidgetAnimationWaiter waiter(hotseat);
  2247. EndOverview();
  2248. waiter.WaitForAnimation();
  2249. EXPECT_TRUE(inspector.CheckAnimation(4));
  2250. }
  2251. // And we should now be back where we started.
  2252. EXPECT_EQ(shown_hotseat_bounds, hotseat->GetWindowBoundsInScreen());
  2253. }
  2254. class HotseatWidgetRTLTest : public ShelfLayoutManagerTestBase,
  2255. public testing::WithParamInterface<bool> {
  2256. public:
  2257. // Use MOCK_TIME to increase number of commits during animation.
  2258. HotseatWidgetRTLTest()
  2259. : ShelfLayoutManagerTestBase(
  2260. base::test::TaskEnvironment::TimeSource::MOCK_TIME),
  2261. scoped_locale_(GetParam() ? "ar" : "") {}
  2262. HotseatWidgetRTLTest(const HotseatWidgetRTLTest&) = delete;
  2263. HotseatWidgetRTLTest& operator=(const HotseatWidgetRTLTest&) = delete;
  2264. ~HotseatWidgetRTLTest() override = default;
  2265. private:
  2266. base::test::ScopedRestoreICUDefaultLocale scoped_locale_;
  2267. };
  2268. INSTANTIATE_TEST_SUITE_P(RTL, HotseatWidgetRTLTest, testing::Bool());
  2269. // The test to verify the hotseat transition animation from the extended state
  2270. // to the home launcher state.
  2271. // TODO(https://crbug.com/1210530): Disable this test due to flakiness.
  2272. TEST_P(HotseatWidgetRTLTest,
  2273. DISABLED_VerifyTransitionFromExtendedModeToHomeLauncher) {
  2274. TabletModeControllerTestApi().EnterTabletMode();
  2275. const auto app_id =
  2276. ShelfTestUtil::AddAppShortcut("fake_app", TYPE_PINNED_APP);
  2277. // Open a window so the hotseat transitions to hidden state.
  2278. std::unique_ptr<aura::Window> window =
  2279. AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
  2280. wm::ActivateWindow(window.get());
  2281. // Swipe the hotseat up to enter the extended mode.
  2282. SwipeUpOnShelf();
  2283. EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
  2284. // Animation should be long enough in order to collect sufficient data.
  2285. // TODO(https://crbug.com/1208651): remove this line when we solve that issue.
  2286. ui::ScopedAnimationDurationScaleMode animation_duration(
  2287. ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
  2288. // Wait until shelf animation completes.
  2289. auto* shelf_view = GetPrimaryShelf()->GetShelfViewForTesting();
  2290. ShelfViewTestAPI shelf_test_api(shelf_view);
  2291. shelf_test_api.RunMessageLoopUntilAnimationsDone();
  2292. // Observe a shelf icon.
  2293. auto* observed_view = shelf_view->GetShelfAppButton(app_id.id);
  2294. LayerAnimationVerifier verifier(
  2295. GetPrimaryShelf()->hotseat_widget()->GetNativeView()->layer(),
  2296. observed_view);
  2297. // Transit the hotseat from the extended state to the home launcher state.
  2298. // Wait until the transition animation finishes.
  2299. views::WidgetAnimationWaiter waiter(GetPrimaryShelf()->hotseat_widget());
  2300. FlingUpOnShelf();
  2301. waiter.WaitForAnimation();
  2302. // Verify the hotseat state at the end of the animation.
  2303. EXPECT_EQ(HotseatState::kShownHomeLauncher,
  2304. GetShelfLayoutManager()->hotseat_state());
  2305. }
  2306. } // namespace ash