12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/app_list/views/continue_section_view.h"
- #include <memory>
- #include <set>
- #include <string>
- #include <utility>
- #include <vector>
- #include "ash/app_list/app_list_controller_impl.h"
- #include "ash/app_list/app_list_metrics.h"
- #include "ash/app_list/app_list_test_view_delegate.h"
- #include "ash/app_list/model/search/search_model.h"
- #include "ash/app_list/model/search/test_search_result.h"
- #include "ash/app_list/test/app_list_test_helper.h"
- #include "ash/app_list/views/app_list_bubble_apps_page.h"
- #include "ash/app_list/views/app_list_toast_container_view.h"
- #include "ash/app_list/views/app_list_toast_view.h"
- #include "ash/app_list/views/apps_container_view.h"
- #include "ash/app_list/views/apps_grid_view_test_api.h"
- #include "ash/app_list/views/continue_task_view.h"
- #include "ash/app_list/views/recent_apps_view.h"
- #include "ash/app_list/views/scrollable_apps_grid_view.h"
- #include "ash/app_list/views/search_box_view.h"
- #include "ash/constants/ash_features.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/public/cpp/app_list/app_list_features.h"
- #include "ash/public/cpp/app_list/app_list_types.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/test/layer_animation_stopped_waiter.h"
- #include "base/run_loop.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/compositor/layer.h"
- #include "ui/compositor/scoped_animation_duration_scale_mode.h"
- #include "ui/events/event.h"
- #include "ui/events/keycodes/keyboard_codes.h"
- #include "ui/views/animation/ink_drop.h"
- #include "ui/views/controls/button/label_button.h"
- #include "ui/views/controls/button/radio_button.h"
- #include "ui/views/controls/scroll_view.h"
- #include "ui/views/controls/textfield/textfield.h"
- #include "ui/views/widget/widget_delegate.h"
- namespace ash {
- namespace {
- using test::AppListTestViewDelegate;
- std::unique_ptr<TestSearchResult> CreateTestResult(const std::string& id,
- AppListSearchResultType type,
- const std::string& title) {
- auto result = std::make_unique<TestSearchResult>();
- result->set_result_id(id);
- result->SetTitle(base::ASCIIToUTF16(title));
- result->set_result_type(type);
- result->set_display_type(SearchResultDisplayType::kContinue);
- return result;
- }
- void AddSearchResultToModel(const std::string& id,
- AppListSearchResultType type,
- SearchModel* model,
- const std::string& title) {
- model->results()->Add(CreateTestResult(id, type, title));
- }
- void WaitForAllChildrenAnimationsToComplete(views::View* view) {
- while (true) {
- bool found_animation = false;
- for (views::View* child : view->children()) {
- if (child->layer() && child->layer()->GetAnimator()->is_animating()) {
- LayerAnimationStoppedWaiter waiter;
- waiter.Wait(child->layer());
- found_animation = true;
- break;
- }
- }
- if (!found_animation)
- return;
- }
- }
- class ContinueSectionViewTestBase : public AshTestBase {
- public:
- explicit ContinueSectionViewTestBase(bool tablet_mode)
- : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
- tablet_mode_(tablet_mode) {
- scoped_feature_list_.InitWithFeatures(
- {features::kLauncherAppSort, features::kProductivityLauncher}, {});
- }
- ~ContinueSectionViewTestBase() override = default;
- void TearDown() override {
- AshTestBase::TearDown();
- // Clean up global variables used for metrics on continue section removals.
- ContinueSectionView::ResetContinueSectionFileRemovalMetricEnabledForTest();
- ResetContinueSectionFileRemovedCountForTest();
- }
- // Whether we should run the test in tablet mode.
- bool tablet_mode_param() { return tablet_mode_; }
- // Sets up the continue section view (and app list) state for testing continue
- // section update animations. `result_count` is the number of continue tasks
- // that should initially be added to search model.
- // Returns the list of current task view layer bounds.
- std::vector<gfx::RectF> InitializeForAnimationTest(int result_count) {
- // Ensure display is large enough to display 4 chips in tablet mode.
- UpdateDisplay("1200x800");
- AddTestSearchResults(result_count);
- EnsureLauncherShown();
- base::RunLoop().RunUntilIdle();
- base::OneShotTimer* animations_timer = GetContinueSectionView()
- ->suggestions_container()
- ->animations_timer_for_test();
- if (animations_timer)
- animations_timer->FireNow();
- animation_duration_.emplace(
- ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
- return GetCurrentLayerBoundsForAllTaskViews();
- }
- ContinueSectionView* GetContinueSectionView() {
- if (Shell::Get()->tablet_mode_controller()->InTabletMode())
- return GetAppListTestHelper()->GetFullscreenContinueSectionView();
- return GetAppListTestHelper()->GetBubbleContinueSectionView();
- }
- AppListNudgeController* GetAppListNudgeController() {
- return GetContinueSectionView()->nudge_controller_for_test();
- }
- views::View* GetRecentAppsView() {
- if (Shell::Get()->tablet_mode_controller()->InTabletMode())
- return GetAppListTestHelper()->GetFullscreenRecentAppsView();
- return GetAppListTestHelper()->GetBubbleRecentAppsView();
- }
- views::View* GetAppsGridView() {
- if (Shell::Get()->tablet_mode_controller()->InTabletMode())
- return GetAppListTestHelper()->GetRootPagedAppsGridView();
- return GetAppListTestHelper()->GetScrollableAppsGridView();
- }
- void AddTestSearchResults(int count) {
- for (int i = 0; i < count; ++i)
- AddSearchResult(base::StringPrintf("id_%d", i),
- AppListSearchResultType::kZeroStateFile);
- }
- void AddSearchResult(const std::string& id, AppListSearchResultType type) {
- AddSearchResultToModel(
- id, type, AppListModelProvider::Get()->search_model(), "Fake Title");
- }
- void AddSearchResultWithTitle(const std::string& id,
- AppListSearchResultType type,
- const std::string& title) {
- AddSearchResultToModel(id, type,
- AppListModelProvider::Get()->search_model(), title);
- }
- void RemoveSearchResultAt(size_t index) {
- GetAppListTestHelper()->GetSearchResults()->RemoveAt(index);
- }
- SearchModel::SearchResults* GetResults() {
- return GetAppListTestHelper()->GetSearchResults();
- }
- std::vector<SearchResult*> GetContinueResults() {
- auto continue_filter = [](const SearchResult& r) -> bool {
- return r.display_type() == SearchResultDisplayType::kContinue;
- };
- std::vector<SearchResult*> continue_results;
- continue_results = SearchModel::FilterSearchResultsByFunction(
- GetResults(), base::BindRepeating(continue_filter),
- /*max_results=*/4);
- return continue_results;
- }
- SearchBoxView* GetSearchBoxView() {
- if (Shell::Get()->tablet_mode_controller()->InTabletMode())
- return GetAppListTestHelper()->GetSearchBoxView();
- return GetAppListTestHelper()->GetBubbleSearchBoxView();
- }
- ContinueTaskView* GetResultViewAt(int index) {
- return GetContinueSectionView()->GetTaskViewAtForTesting(index);
- }
- std::vector<std::string> GetResultIds() {
- const size_t result_count =
- GetContinueSectionView()->GetTasksSuggestionsCount();
- std::vector<std::string> ids;
- for (size_t i = 0; i < result_count; ++i)
- ids.push_back(GetResultViewAt(i)->result()->id());
- return ids;
- }
- void VerifyResultViewsUpdated() {
- // Wait for the view to update any pending SearchResults.
- base::RunLoop().RunUntilIdle();
- std::vector<SearchResult*> results = GetContinueResults();
- for (size_t i = 0; i < results.size(); ++i)
- EXPECT_EQ(results[i], GetResultViewAt(i)->result()) << i;
- }
- void EnsureLauncherShown() {
- if (tablet_mode_param()) {
- // Convert to tablet mode to show fullscren launcher.
- Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
- Shell::Get()->app_list_controller()->ShowAppList();
- test_api_ = std::make_unique<test::AppsGridViewTestApi>(
- GetAppListTestHelper()->GetRootPagedAppsGridView());
- } else {
- Shell::Get()->app_list_controller()->ShowAppList();
- test_api_ = std::make_unique<test::AppsGridViewTestApi>(
- GetAppListTestHelper()->GetScrollableAppsGridView());
- }
- ASSERT_TRUE(GetAppsGridView());
- }
- void HideLauncher() { Shell::Get()->app_list_controller()->DismissAppList(); }
- void ResetPrivacyNoticePref() {
- AppListNudgeController::SetPrivacyNoticeAcceptedForTest(false);
- }
- void SimulateRightClickOrLongPressOn(const views::View* view) {
- gfx::Point location = view->GetBoundsInScreen().CenterPoint();
- if (tablet_mode_param()) {
- ui::test::EventGenerator* generator = GetEventGenerator();
- generator->set_current_screen_location(location);
- generator->PressTouch();
- ui::GestureEventDetails event_details(ui::ET_GESTURE_LONG_PRESS);
- ui::GestureEvent long_press(location.x(), location.y(), 0,
- base::TimeTicks::Now(), event_details);
- generator->Dispatch(&long_press);
- generator->ReleaseTouch();
- GetAppListTestHelper()->WaitUntilIdle();
- } else {
- RightClickOn(view);
- }
- }
- bool IsPrivacyNoticeVisible() {
- auto* privacy_notice = GetContinueSectionView()->GetPrivacyNoticeForTest();
- return privacy_notice && privacy_notice->GetVisible();
- }
- gfx::RectF GetTargetLayerBounds(views::View* view) {
- gfx::RectF bounds(view->layer()->GetTargetBounds());
- view->layer()->GetTargetTransform().TransformRect(&bounds);
- return bounds;
- }
- gfx::RectF GetCurrentLayerBounds(views::View* view) {
- gfx::RectF bounds(view->layer()->bounds());
- view->layer()->transform().TransformRect(&bounds);
- return bounds;
- }
- std::vector<gfx::RectF> GetCurrentLayerBoundsForAllTaskViews() {
- std::vector<gfx::RectF> bounds;
- const size_t count = GetContinueSectionView()->GetTasksSuggestionsCount();
- bounds.reserve(count);
- for (size_t i = 0; i < count; ++i) {
- views::View* result_view = GetResultViewAt(i);
- bounds.push_back(GetCurrentLayerBounds(result_view));
- }
- return bounds;
- }
- void RemoveSearchResultWithContextMenuAt(int index) {
- ContinueTaskView* continue_task_view = GetResultViewAt(index);
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing()) << index;
- continue_task_view->ExecuteCommand(ContinueTaskCommandId::kRemoveResult,
- ui::EF_NONE);
- EXPECT_FALSE(continue_task_view->IsMenuShowing());
- }
- test::AppsGridViewTestApi* test_api() { return test_api_.get(); }
- private:
- bool tablet_mode_ = false;
- absl::optional<ui::ScopedAnimationDurationScaleMode> animation_duration_;
- std::unique_ptr<test::AppsGridViewTestApi> test_api_;
- base::test::ScopedFeatureList scoped_feature_list_;
- };
- class ContinueSectionViewTest : public ContinueSectionViewTestBase,
- public testing::WithParamInterface<bool> {
- public:
- ContinueSectionViewTest()
- : ContinueSectionViewTestBase(/*tablet_mode=*/GetParam()) {}
- ~ContinueSectionViewTest() override = default;
- };
- class ContinueSectionViewClamshellModeTest
- : public ContinueSectionViewTestBase {
- public:
- ContinueSectionViewClamshellModeTest()
- : ContinueSectionViewTestBase(/*tablet_mode=*/false) {}
- ~ContinueSectionViewClamshellModeTest() override = default;
- };
- class ContinueSectionViewTabletModeTest : public ContinueSectionViewTestBase {
- public:
- ContinueSectionViewTabletModeTest()
- : ContinueSectionViewTestBase(/*tablet_mode=*/true) {}
- ~ContinueSectionViewTabletModeTest() override = default;
- };
- class ContinueSectionViewWithReorderNudgeTest
- : public ContinueSectionViewTestBase,
- public testing::WithParamInterface<bool> {
- public:
- ContinueSectionViewWithReorderNudgeTest()
- : ContinueSectionViewTestBase(/*tablet_mode=*/GetParam()) {}
- ~ContinueSectionViewWithReorderNudgeTest() override = default;
- // AshTestBase:
- void SetUp() override {
- AshTestBase::SetUp();
- GetAppListTestHelper()->DisableAppListNudge(false);
- }
- AppListToastContainerView* GetToastContainerView() {
- if (!Shell::Get()->tablet_mode_controller()->InTabletMode()) {
- return GetAppListTestHelper()
- ->GetBubbleAppsPage()
- ->toast_container_for_test();
- }
- return GetAppListTestHelper()->GetAppsContainerView()->toast_container();
- }
- };
- // Instantiate the values in the parameterized tests. Used to toggle tablet
- // mode.
- INSTANTIATE_TEST_SUITE_P(All, ContinueSectionViewTest, testing::Bool());
- INSTANTIATE_TEST_SUITE_P(All,
- ContinueSectionViewWithReorderNudgeTest,
- testing::Bool());
- TEST_P(ContinueSectionViewTest, CreatesViewsForTasks) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- ContinueSectionView* view = GetContinueSectionView();
- EXPECT_EQ(view->GetTasksSuggestionsCount(), 2u);
- }
- TEST_P(ContinueSectionViewTest, VerifyAddedViewsOrder) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueSectionView* view = GetContinueSectionView();
- ASSERT_EQ(view->GetTasksSuggestionsCount(), 3u);
- EXPECT_EQ(GetResultViewAt(0)->result()->id(), "id1");
- EXPECT_EQ(GetResultViewAt(1)->result()->id(), "id2");
- EXPECT_EQ(GetResultViewAt(2)->result()->id(), "id3");
- }
- TEST_P(ContinueSectionViewTest, ShowsHelpAppResults) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateHelpApp);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(GetContinueSectionView()->GetVisible());
- ContinueSectionView* view = GetContinueSectionView();
- ASSERT_EQ(view->GetTasksSuggestionsCount(), 4u);
- EXPECT_EQ(GetResultViewAt(0)->result()->id(), "id1");
- EXPECT_EQ(GetResultViewAt(1)->result()->id(), "id2");
- EXPECT_EQ(GetResultViewAt(2)->result()->id(), "id3");
- EXPECT_EQ(GetResultViewAt(3)->result()->id(), "id4");
- }
- TEST_P(ContinueSectionViewTest, HelpAppResultNotShownWithoutEnoughOtherFiles) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateHelpApp);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueSectionView* view = GetContinueSectionView();
- ASSERT_EQ(view->GetTasksSuggestionsCount(), 2u);
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, HelpAppShownInTabletModeWith2FileResults) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateHelpApp);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateFile);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueSectionView* view = GetContinueSectionView();
- ASSERT_EQ(view->GetTasksSuggestionsCount(), 3u);
- EXPECT_EQ(GetParam(), GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, ModelObservers) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // Remove from end.
- GetResults()->DeleteAt(2);
- VerifyResultViewsUpdated();
- // Insert a new result.
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- VerifyResultViewsUpdated();
- // Delete from start.
- GetResults()->DeleteAt(0);
- VerifyResultViewsUpdated();
- }
- TEST_P(ContinueSectionViewTest, HideContinueSectionWhenResultRemoved) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- // Minimum files for clamshell mode are 3.
- if (!tablet_mode_param())
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(GetContinueSectionView()->GetVisible());
- RemoveSearchResultAt(1);
- VerifyResultViewsUpdated();
- ASSERT_LE(GetContinueSectionView()->GetTasksSuggestionsCount(), 2u);
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, ShowContinueSectionWhenResultAdded) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- // Minimum files for clamshell mode are 3.
- if (!tablet_mode_param())
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- VerifyResultViewsUpdated();
- EXPECT_TRUE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, ClickOpensSearchResult) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- LeftClickOn(continue_task_view);
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id1", client->last_opened_search_result());
- }
- TEST_P(ContinueSectionViewTest, TapOpensSearchResult) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- GestureTapOn(continue_task_view);
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id1", client->last_opened_search_result());
- }
- TEST_F(ContinueSectionViewClamshellModeTest, PressEnterOpensSearchResult) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- SearchBoxView* search_box_view = GetSearchBoxView();
- EXPECT_TRUE(search_box_view->search_box()->HasFocus());
- PressAndReleaseKey(ui::VKEY_DOWN);
- EXPECT_TRUE(continue_task_view->HasFocus());
- PressAndReleaseKey(ui::VKEY_RETURN);
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id1", client->last_opened_search_result());
- }
- TEST_F(ContinueSectionViewClamshellModeTest, DownArrowMovesFocusVertically) {
- AddSearchResult("id0", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* task0 = GetResultViewAt(0);
- ContinueTaskView* task1 = GetResultViewAt(1);
- ContinueTaskView* task2 = GetResultViewAt(2);
- ContinueTaskView* task3 = GetResultViewAt(3);
- ASSERT_FALSE(task0->HasFocus());
- ASSERT_FALSE(task1->HasFocus());
- ASSERT_FALSE(task2->HasFocus());
- ASSERT_FALSE(task3->HasFocus());
- // Down arrow from search box moves to first continue task.
- PressAndReleaseKey(ui::VKEY_DOWN);
- EXPECT_TRUE(task0->HasFocus());
- EXPECT_FALSE(task1->HasFocus());
- EXPECT_FALSE(task2->HasFocus());
- EXPECT_FALSE(task3->HasFocus());
- // Down arrow from first continue task moves down by one row, focusing
- // `task2` instead of the next task in tab order (`task1`).
- PressAndReleaseKey(ui::VKEY_DOWN);
- EXPECT_FALSE(task0->HasFocus());
- EXPECT_FALSE(task1->HasFocus());
- EXPECT_TRUE(task2->HasFocus());
- EXPECT_FALSE(task3->HasFocus());
- // Down again moves focus out of continue section.
- PressAndReleaseKey(ui::VKEY_DOWN);
- EXPECT_FALSE(task0->HasFocus());
- EXPECT_FALSE(task1->HasFocus());
- EXPECT_FALSE(task2->HasFocus());
- EXPECT_FALSE(task3->HasFocus());
- }
- TEST_F(ContinueSectionViewClamshellModeTest, UpArrowMovesFocusVertically) {
- AddSearchResult("id0", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* task0 = GetResultViewAt(0);
- ContinueTaskView* task1 = GetResultViewAt(1);
- ContinueTaskView* task2 = GetResultViewAt(2);
- ContinueTaskView* task3 = GetResultViewAt(3);
- ASSERT_FALSE(task0->HasFocus());
- ASSERT_FALSE(task1->HasFocus());
- ASSERT_FALSE(task2->HasFocus());
- ASSERT_FALSE(task3->HasFocus());
- // Focus the last task (in the second row, second column).
- task3->RequestFocus();
- EXPECT_FALSE(task0->HasFocus());
- EXPECT_FALSE(task1->HasFocus());
- EXPECT_FALSE(task2->HasFocus());
- EXPECT_TRUE(task3->HasFocus());
- // Up arrow moves up by one row, focusing `task1` instead of the previous
- // task in tab order (`task2`).
- PressAndReleaseKey(ui::VKEY_UP);
- EXPECT_FALSE(task0->HasFocus());
- EXPECT_TRUE(task1->HasFocus());
- EXPECT_FALSE(task2->HasFocus());
- EXPECT_FALSE(task3->HasFocus());
- // Up again moves focus out of continue section.
- PressAndReleaseKey(ui::VKEY_UP);
- EXPECT_FALSE(task0->HasFocus());
- EXPECT_FALSE(task1->HasFocus());
- EXPECT_FALSE(task2->HasFocus());
- EXPECT_FALSE(task3->HasFocus());
- }
- TEST_F(ContinueSectionViewClamshellModeTest, FocusingChipScrollsToShowLabel) {
- auto* helper = GetAppListTestHelper();
- helper->AddContinueSuggestionResults(4);
- // Add enough apps to allow the apps page to scroll.
- helper->AddAppItems(50);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // Up arrow moves focus to the last row of the apps grid, forcing the apps
- // page to scroll.
- PressAndReleaseKey(ui::VKEY_UP);
- auto* scroll_view = helper->GetBubbleAppsPage()->scroll_view();
- const int initial_scroll_offset = scroll_view->GetVisibleRect().y();
- ASSERT_GT(initial_scroll_offset, 0);
- // Down arrow twice moves focus to search box, then to continue section.
- PressAndReleaseKey(ui::VKEY_DOWN);
- PressAndReleaseKey(ui::VKEY_DOWN);
- ASSERT_TRUE(GetResultViewAt(0)->HasFocus());
- // Scroll view has scrolled to the top to reveal the label.
- const int final_scroll_offset = scroll_view->GetVisibleRect().y();
- EXPECT_EQ(final_scroll_offset, 0);
- }
- TEST_F(ContinueSectionViewClamshellModeTest,
- FocusingPrivacyNoticeScrollsToShowNotice) {
- auto* helper = GetAppListTestHelper();
- helper->AddContinueSuggestionResults(4);
- // Add enough apps to allow the apps page to scroll.
- helper->AddAppItems(50);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ASSERT_TRUE(IsPrivacyNoticeVisible());
- // Up arrow moves focus to the last row of the apps grid, forcing the apps
- // page to scroll.
- PressAndReleaseKey(ui::VKEY_UP);
- auto* scroll_view = helper->GetBubbleAppsPage()->scroll_view();
- const int initial_scroll_offset = scroll_view->GetVisibleRect().y();
- ASSERT_GT(initial_scroll_offset, 0);
- // Down arrow twice moves focus to search box, then to privacy notice.
- PressAndReleaseKey(ui::VKEY_DOWN);
- PressAndReleaseKey(ui::VKEY_DOWN);
- auto* privacy_notice = GetContinueSectionView()->GetPrivacyNoticeForTest();
- ASSERT_TRUE(privacy_notice->toast_button()->HasFocus());
- // Scroll view has scrolled to the top to reveal the whole notice.
- const int final_scroll_offset = scroll_view->GetVisibleRect().y();
- EXPECT_EQ(final_scroll_offset, 0);
- }
- // Regression test for https://crbug.com/1273170.
- TEST_F(ContinueSectionViewClamshellModeTest, SearchAndCancelDoesNotChangeSize) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- auto* apps_grid_view = GetAppListTestHelper()->GetScrollableAppsGridView();
- const gfx::Point apps_grid_origin = apps_grid_view->origin();
- auto* continue_section_view = GetContinueSectionView();
- const gfx::Rect continue_section_bounds = continue_section_view->bounds();
- auto* widget = continue_section_view->GetWidget();
- // Start a search.
- PressAndReleaseKey(ui::VKEY_A);
- // Simulate the suggestions changing.
- GetResults()->RemoveAll();
- AddSearchResult("id3", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id5", AppListSearchResultType::kZeroStateDrive);
- // Cancel the search.
- PressAndReleaseKey(ui::VKEY_ESCAPE);
- base::RunLoop().RunUntilIdle(); // Wait for SearchResult updates to views.
- widget->LayoutRootViewIfNecessary();
- // Continue section bounds did not grow.
- EXPECT_EQ(continue_section_bounds, continue_section_view->bounds());
- // Apps grid view position did not change.
- EXPECT_EQ(apps_grid_origin, apps_grid_view->origin());
- }
- TEST_P(ContinueSectionViewTest, RightClickOpensContextMenu) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing());
- }
- TEST_P(ContinueSectionViewTest, OpenWithContextMenuOption) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing());
- continue_task_view->ExecuteCommand(ContinueTaskCommandId::kOpenResult,
- ui::EF_NONE);
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id1", client->last_opened_search_result());
- }
- TEST_P(ContinueSectionViewTest, RemoveWithContextMenuOption) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_EQ(GetResultViewAt(0)->result()->id(), "id1");
- RemoveSearchResultWithContextMenuAt(0);
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- std::vector<TestAppListClient::SearchResultActionId> expected_actions = {
- {"id1", SearchResultActionType::kRemove}};
- std::vector<TestAppListClient::SearchResultActionId> invoked_actions =
- client->GetAndResetInvokedResultActions();
- EXPECT_EQ(expected_actions, invoked_actions);
- }
- TEST_P(ContinueSectionViewTest, ResultRemovedLogsMetricInBucket) {
- base::HistogramTester histogram_tester;
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // Remove two results.
- EXPECT_EQ(GetResultViewAt(0)->result()->id(), "id1");
- RemoveSearchResultWithContextMenuAt(0);
- EXPECT_EQ(GetResultViewAt(1)->result()->id(), "id2");
- RemoveSearchResultWithContextMenuAt(1);
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- std::vector<TestAppListClient::SearchResultActionId> expected_actions = {
- {"id1", SearchResultActionType::kRemove},
- {"id2", SearchResultActionType::kRemove}};
- std::vector<TestAppListClient::SearchResultActionId> invoked_actions =
- client->GetAndResetInvokedResultActions();
- EXPECT_EQ(expected_actions, invoked_actions);
- EXPECT_EQ(1, histogram_tester.GetBucketCount(
- kContinueSectionFilesRemovedInSessionHistogram, 1));
- EXPECT_EQ(1, histogram_tester.GetBucketCount(
- kContinueSectionFilesRemovedInSessionHistogram, 2));
- histogram_tester.ExpectTotalCount(
- kContinueSectionFilesRemovedInSessionHistogram, 2);
- }
- TEST_P(ContinueSectionViewTest, ResultRemovedContextMenuCloses) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(1);
- EXPECT_EQ(continue_task_view->result()->id(), "id2");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing());
- RemoveSearchResultAt(1);
- VerifyResultViewsUpdated();
- ASSERT_EQ(std::vector<std::string>({"id1", "id3", "id4"}), GetResultIds());
- // Click on another result and verify it activates the item to confirm the
- // event is not consumed by a context menu.
- EXPECT_EQ(GetResultViewAt(0)->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- LeftClickOn(GetResultViewAt(0));
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id1", client->last_opened_search_result());
- }
- TEST_P(ContinueSectionViewTest, UpdateAppsOnModelChange) {
- AddSearchResult("id11", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id12", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id13", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id14", AppListSearchResultType::kZeroStateFile);
- UpdateDisplay("1200x800");
- EnsureLauncherShown();
- EXPECT_EQ(std::vector<std::string>({"id11", "id12", "id13", "id14"}),
- GetResultIds());
- // Update active model, and make sure the shown results view get updated
- // accordingly.
- auto model_override = std::make_unique<test::AppListTestModel>();
- auto search_model_override = std::make_unique<SearchModel>();
- AddSearchResultToModel("id21", AppListSearchResultType::kZeroStateFile,
- search_model_override.get(), "Fake Title");
- AddSearchResultToModel("id22", AppListSearchResultType::kZeroStateFile,
- search_model_override.get(), "Fake Title");
- AddSearchResultToModel("id23", AppListSearchResultType::kZeroStateFile,
- search_model_override.get(), "Fake Title");
- Shell::Get()->app_list_controller()->SetActiveModel(
- /*profile_id=*/1, model_override.get(), search_model_override.get());
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- EXPECT_EQ(std::vector<std::string>({"id21", "id22", "id23"}), GetResultIds());
- // Tap a result, and verify it gets activated.
- GestureTapOn(GetResultViewAt(2));
- // The item was activated.
- TestAppListClient* client = GetAppListTestHelper()->app_list_client();
- EXPECT_EQ("id23", client->last_opened_search_result());
- // Results should be cleared if app list models get reset.
- Shell::Get()->app_list_controller()->ClearActiveModel();
- EXPECT_EQ(std::vector<std::string>{}, GetResultIds());
- }
- TEST_F(ContinueSectionViewTabletModeTest,
- TabletModeLayoutWithThreeSuggestions) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- UpdateDisplay("1200x800");
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ASSERT_TRUE(GetContinueSectionView()->GetVisible());
- ASSERT_EQ(3u, GetContinueSectionView()->GetTasksSuggestionsCount());
- const gfx::Size size = GetResultViewAt(0)->size();
- const int vertical_position = GetResultViewAt(0)->y();
- for (int i = 1; i < 3; i++) {
- const ContinueTaskView* task_view = GetResultViewAt(i);
- EXPECT_TRUE(task_view->GetVisible());
- EXPECT_EQ(size, task_view->size());
- EXPECT_EQ(vertical_position, task_view->y());
- EXPECT_GT(task_view->x(), GetResultViewAt(i - 1)->bounds().right());
- }
- views::View* parent_view = GetResultViewAt(0)->parent();
- EXPECT_EQ(std::abs(parent_view->GetContentsBounds().x() -
- GetResultViewAt(0)->bounds().x()),
- std::abs(parent_view->GetContentsBounds().right() -
- GetResultViewAt(2)->bounds().right()));
- }
- TEST_F(ContinueSectionViewTabletModeTest, TabletModeLayoutWithFourSuggestions) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- UpdateDisplay("1200x800");
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- ASSERT_TRUE(GetContinueSectionView()->GetVisible());
- ASSERT_EQ(4u, GetContinueSectionView()->GetTasksSuggestionsCount());
- const gfx::Size size = GetResultViewAt(0)->size();
- const int vertical_position = GetResultViewAt(0)->y();
- for (int i = 1; i < 4; i++) {
- const ContinueTaskView* task_view = GetResultViewAt(i);
- EXPECT_TRUE(task_view->GetVisible());
- EXPECT_EQ(size, task_view->size());
- EXPECT_EQ(vertical_position, task_view->y());
- EXPECT_GT(task_view->x(), GetResultViewAt(i - 1)->bounds().right());
- }
- views::View* parent_view = GetResultViewAt(0)->parent();
- EXPECT_EQ(std::abs(parent_view->GetContentsBounds().x() -
- GetResultViewAt(0)->bounds().x()),
- std::abs(parent_view->GetContentsBounds().right() -
- GetResultViewAt(3)->bounds().right()));
- }
- TEST_P(ContinueSectionViewTest, NoOverlapsWithRecentApps) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- GetAppListTestHelper()->AddRecentApps(5);
- GetAppListTestHelper()->AddAppItems(5);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- EXPECT_FALSE(GetContinueSectionView()->bounds().Intersects(
- GetRecentAppsView()->bounds()));
- }
- TEST_P(ContinueSectionViewTest, NoOverlapsWithAppsGridItems) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- GetAppListTestHelper()->AddAppItems(5);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- gfx::Rect continue_bounds = GetContinueSectionView()->GetBoundsInScreen();
- for (size_t i = 0; i < test_api()->GetItemList()->item_count(); i++) {
- gfx::Rect app_bounds =
- test_api()->GetViewAtModelIndex(i)->GetBoundsInScreen();
- EXPECT_FALSE(continue_bounds.Intersects(app_bounds)) << i;
- }
- }
- // Tests that number of shown continue section items is reduced if they don't
- // all fit into the available space (while maintaining min width).
- TEST_F(ContinueSectionViewTabletModeTest,
- TabletModeLayoutWithFourSuggestionsWithRestrictedSpace) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id4", AppListSearchResultType::kZeroStateFile);
- // Set the display width so only 2 continue section tasks fit into available
- // space.
- UpdateDisplay("600x800");
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ASSERT_EQ(4u, GetContinueSectionView()->GetTasksSuggestionsCount());
- // Only first two tasks are visible.
- for (int i = 0; i < 4; ++i)
- EXPECT_EQ(i <= 1, GetResultViewAt(i)->GetVisible()) << i;
- const ContinueTaskView* first_task = GetResultViewAt(0);
- const ContinueTaskView* second_task = GetResultViewAt(1);
- EXPECT_EQ(first_task->size(), second_task->size());
- EXPECT_EQ(first_task->y(), second_task->y());
- EXPECT_GT(second_task->x(), first_task->bounds().right());
- }
- TEST_P(ContinueSectionViewTest, AllTasksShareTheSameWidth) {
- AddSearchResultWithTitle("id1", AppListSearchResultType::kZeroStateFile,
- "title");
- AddSearchResultWithTitle(
- "id2", AppListSearchResultType::kZeroStateDrive,
- "Really really really long title text for the label");
- AddSearchResultWithTitle("id3", AppListSearchResultType::kZeroStateDrive,
- "-");
- AddSearchResultWithTitle("id4", AppListSearchResultType::kZeroStateFile,
- "medium title");
- UpdateDisplay("1200x800");
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ASSERT_EQ(4u, GetContinueSectionView()->GetTasksSuggestionsCount());
- const gfx::Size size = GetResultViewAt(0)->size();
- for (int i = 1; i < 4; i++) {
- const ContinueTaskView* task_view = GetResultViewAt(i);
- EXPECT_TRUE(task_view->GetVisible());
- EXPECT_EQ(size, task_view->size());
- }
- }
- TEST_P(ContinueSectionViewTest, HideContinueSectionWhithLessThanMinimumFiles) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- // Minimum files for clamshell mode are 3.
- if (!tablet_mode_param())
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- // Wait for the view to update any pending SearchResults.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, ShowContinueSectionWhithMinimumFiles) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- // Minimum files for clamshell mode are 3.
- if (!tablet_mode_param())
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- // Wait for the view to update any pending SearchResults.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, TaskViewHasRippleWithMenuOpen) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing());
- EXPECT_EQ(views::InkDropState::ACTIVATED,
- views::InkDrop::Get(continue_task_view)
- ->GetInkDrop()
- ->GetTargetInkDropState());
- }
- TEST_P(ContinueSectionViewTest, TaskViewHidesRippleAfterMenuCloses) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ContinueTaskView* continue_task_view = GetResultViewAt(0);
- EXPECT_EQ(continue_task_view->result()->id(), "id1");
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(continue_task_view);
- EXPECT_TRUE(continue_task_view->IsMenuShowing());
- // Click on other task view to hide context menu.
- GetContinueSectionView()->GetWidget()->LayoutRootViewIfNecessary();
- SimulateRightClickOrLongPressOn(GetResultViewAt(2));
- EXPECT_FALSE(continue_task_view->IsMenuShowing());
- // Wait for the view to update the ink drop.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(views::InkDropState::HIDDEN, views::InkDrop::Get(continue_task_view)
- ->GetInkDrop()
- ->GetTargetInkDropState());
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest, ShowPrivacyNotice) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest, AcceptPrivacyNotice) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- GestureTapOn(
- GetContinueSectionView()->GetPrivacyNoticeForTest()->toast_button());
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- HideLauncher();
- EnsureLauncherShown();
- EXPECT_FALSE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest, TimeDismissPrivacyNotice) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- ASSERT_TRUE(GetContinueSectionView()->FirePrivacyNoticeShownTimerForTest());
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- }
- // TODO(crbug.com/1317428): Switch to ContinueSectionViewWithReorderNudgeTest
- // when this feature works in tablet mode.
- TEST_F(ContinueSectionViewClamshellModeTest,
- HidingContinueSectionHidesPrivacyNotice) {
- base::test::ScopedFeatureList feature_list(
- features::kLauncherHideContinueSection);
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- ASSERT_TRUE(IsPrivacyNoticeVisible());
- ASSERT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- // Simulate the user hiding the continue section.
- Shell::Get()->app_list_controller()->SetHideContinueSection(true);
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- // The privacy notice is suppressed.
- EXPECT_FALSE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kNone);
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest,
- DoNotShowPrivacyNoticeAndReorderNudgeAlternitively) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Close the launcher without waiting long enough for the privacy notice to be
- // considered shown.
- HideLauncher();
- // The privacy notice should be showing instead of the reorder nudge when the
- // next time the launcher is open.
- EnsureLauncherShown();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest,
- DoNotShowPrivacyNoticeAndReorderNudgeAlternitively2) {
- // Open the launcher without any search result added.
- EnsureLauncherShown();
- // Reorder nudge should be showing and privacy notice should not.
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- // After hiding the launcher, add some search results and open the launcher
- // again.
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // If the reorder nudge was shown and hasn't reached the shown times limit,
- // keep showing the reorder nudge instead of the privacy notice.
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- EnsureLauncherShown();
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- EnsureLauncherShown();
- // After the reorder nudge has been shown for three times, starts showing the
- // privacy notice and removes the reorder nudge.
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- }
- TEST_P(ContinueSectionViewWithReorderNudgeTest,
- SearchResultsFetchedAfterLauncherShown) {
- ResetPrivacyNoticePref();
- // Open the launcher without any search result added.
- EnsureLauncherShown();
- // Reorder nudge should be showing and privacy notice should not.
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Add some search results while the launcher is open.
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- VerifyResultViewsUpdated();
- // Neither the privacy notice nor the search results should show.
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowFilesSection());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kReorderNudge);
- EXPECT_EQ(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- // Open the launcher, wait for the reorder nudge to be shown and close it two
- // more times. After the reorder nudge has been shown for three times, starts
- // showing the privacy notice and removes the reorder nudge.
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- // Wait for long enough for the reorder nudge to be considered shown.
- task_environment()->AdvanceClock(base::Seconds(1));
- HideLauncher();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- EXPECT_NE(GetToastContainerView()->current_toast(),
- AppListToastType::kReorderNudge);
- HideLauncher();
- }
- TEST_F(ContinueSectionViewTabletModeTest, PrivacyNoticeIsShownInBackground) {
- AddSearchResult("id1", AppListSearchResultType::kZeroStateFile);
- AddSearchResult("id2", AppListSearchResultType::kZeroStateDrive);
- AddSearchResult("id3", AppListSearchResultType::kZeroStateDrive);
- ResetPrivacyNoticePref();
- EnsureLauncherShown();
- VerifyResultViewsUpdated();
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- // Activate the search box. The privacy notice will become inactive but the
- // view still exists.
- auto* search_box = GetAppListTestHelper()->GetSearchBoxView();
- search_box->SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED);
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- // The privacy notice is not considered as shown when the search box is
- // active. Therefore the privacy notice timer should not be running.
- EXPECT_FALSE(GetContinueSectionView()->FirePrivacyNoticeShownTimerForTest());
- // Reopen the app list.
- HideLauncher();
- EnsureLauncherShown();
- // As the privacy notice was not active during the last shown, shows the
- // notice again.
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- // Activate the search box and then deactivate it.
- search_box->SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED);
- search_box->SetSearchBoxActive(false, ui::ET_MOUSE_PRESSED);
- // The privacy notice timer should be restarted after the search box becomes
- // inactive.
- EXPECT_TRUE(GetContinueSectionView()->FirePrivacyNoticeShownTimerForTest());
- // Reopen the app list. The privacy notice should be removed.
- HideLauncher();
- EnsureLauncherShown();
- EXPECT_FALSE(GetContinueSectionView()->ShouldShowPrivacyNotice());
- EXPECT_FALSE(GetContinueSectionView()->GetPrivacyNoticeForTest());
- }
- TEST_P(ContinueSectionViewTest, InitialShowDoesNotAnimate) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- std::vector<views::View*> container_children =
- GetContinueSectionView()->suggestions_container()->children();
- ASSERT_EQ(4u, container_children.size());
- for (int i = 0; i < 4; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->layer()->GetAnimator()->is_animating());
- }
- }
- TEST_P(ContinueSectionViewTest, UpdateWithNoChangesDoesNotAnimate) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- GetContinueSectionView()->suggestions_container()->Update();
- base::RunLoop().RunUntilIdle();
- std::vector<views::View*> container_children =
- GetContinueSectionView()->suggestions_container()->children();
- ASSERT_EQ(4u, container_children.size());
- for (int i = 0; i < 4; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->layer()->GetAnimator()->is_animating());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenLastItemReplaced) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(3);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[3];
- EXPECT_EQ(initial_bounds[3], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify views for results that are not changing do not animate.
- for (int i : std::set<int>{0, 1, 2}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[i + new_views_start];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenFirstItemRemoved) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(0);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[0];
- EXPECT_EQ(initial_bounds[0], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{0, 1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenSecondItemRemoved) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(1);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[0];
- EXPECT_EQ(initial_bounds[0], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(1.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify the view for the result that's not changing does not animate.
- EXPECT_FALSE(container_children[0]->GetVisible());
- views::View* stationary_view = container_children[new_views_start];
- EXPECT_FALSE(stationary_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[0], GetCurrentLayerBounds(stationary_view));
- EXPECT_EQ(1.0f, stationary_view->layer()->opacity());
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenThirdItemRemoved) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/5);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(2);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[2];
- EXPECT_EQ(initial_bounds[2], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify views for results that are not changing do not animate.
- for (int i : std::set<int>{0, 1}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[i + new_views_start];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenItemInserted) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/4);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->AddAt(
- 1, CreateTestResult("id5", AppListSearchResultType::kZeroStateDrive,
- "new result"));
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[3];
- EXPECT_EQ(initial_bounds[3], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify views for results that are not changing do not animate.
- for (int i : std::set<int>{0}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[i + new_views_start];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- if (tablet_mode_param() && i > 1) {
- EXPECT_GT(initial_bounds[i].x(), current_bounds.x());
- } else {
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- }
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{1, 2}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenTwoItemsRemoved) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/6);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(1);
- GetResults()->DeleteAt(1);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // Removed views should fade out.
- for (int i : std::set<int>{1, 2}) {
- views::View* view_fading_out = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- }
- // Verify views for results that are not changing do not animate.
- for (int i : std::set<int>{0}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[i + new_views_start];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 4; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, ResultRemovedMidAnimation) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/6);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(1);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- // Remove another result after update (which triggers an update animation).
- GetResults()->DeleteAt(1);
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 4, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[1];
- EXPECT_EQ(initial_bounds[1], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // Verify views for results that are not changing do not animate.
- for (int i : std::set<int>{0}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[i + new_views_start];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // Verify views that are expected to slide in.
- for (int i : std::set<int>{1, 2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i + new_views_start];
- EXPECT_EQ(initial_bounds[i], GetTargetLayerBounds(result_view));
- const gfx::RectF current_bounds = GetCurrentLayerBounds(result_view);
- EXPECT_EQ(initial_bounds[i].size(), current_bounds.size());
- EXPECT_LT(initial_bounds[i].x(), current_bounds.x());
- EXPECT_EQ(0.0f, result_view->layer()->opacity());
- EXPECT_EQ(1.0f, result_view->layer()->GetTargetOpacity());
- }
- // Verify views that are expected to slide out.
- for (int i : std::set<int>{2, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(result_view);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i], target_bounds);
- } else {
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_GT(initial_bounds[i].x(), target_bounds.x());
- }
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(0.0f, result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(4u, container_children.size());
- for (int i = 0; i < 3; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- EXPECT_EQ(gfx::Rect(), result_view->layer()->clip_rect());
- }
- }
- TEST_P(ContinueSectionViewTest, ContinueSectionHiddenMidAnimation) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/4);
- ASSERT_EQ(4u, initial_bounds.size());
- // Remove one item to trigger update animation.
- GetResults()->DeleteAt(1);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- // Remove two extra results which should hide the continue section.
- GetResults()->DeleteAt(0);
- GetResults()->DeleteAt(0);
- container_view->Update();
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- std::vector<views::View*> container_children = container_view->children();
- ASSERT_EQ(1u, container_children.size());
- EXPECT_FALSE(container_children[0]->layer()->GetAnimator()->is_animating());
- }
- TEST_P(ContinueSectionViewTest, AnimatesWhenNumberOfChipsChanges) {
- std::vector<gfx::RectF> initial_bounds =
- InitializeForAnimationTest(/*result_count=*/4);
- ASSERT_EQ(4u, initial_bounds.size());
- GetResults()->DeleteAt(2);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- std::vector<views::View*> container_children = container_view->children();
- const size_t new_views_start = 4;
- ASSERT_EQ(new_views_start + 3, container_children.size());
- // The removed view should fade out.
- views::View* view_fading_out = container_children[2];
- EXPECT_EQ(initial_bounds[2], GetCurrentLayerBounds(view_fading_out));
- EXPECT_EQ(0.0f, view_fading_out->layer()->GetTargetOpacity());
- // In tablet mode, all views animate when the number of items shown in the
- // container changes.
- if (tablet_mode_param()) {
- for (int i : std::set<int>{0, 1, 3}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- const bool result_after_removed = i > 2;
- views::View* new_result_view =
- container_children[i + new_views_start -
- (result_after_removed ? 1 : 0)];
- const gfx::RectF current_bounds = GetCurrentLayerBounds(new_result_view);
- EXPECT_EQ(initial_bounds[i].y(), current_bounds.y());
- EXPECT_LT(initial_bounds[i].width(), current_bounds.width());
- const gfx::RectF new_view_target_bounds =
- GetTargetLayerBounds(new_result_view);
- EXPECT_EQ(current_bounds.size(), new_view_target_bounds.size());
- // Items after removed item should animate from the right, and items
- // before the removed item should animate from the left.
- if (i > 1) {
- EXPECT_LT(new_view_target_bounds.x(), current_bounds.x());
- } else {
- EXPECT_GT(new_view_target_bounds.x(), current_bounds.x());
- }
- EXPECT_EQ(0.0f, new_result_view->layer()->opacity());
- EXPECT_EQ(1.0f, new_result_view->layer()->GetTargetOpacity());
- views::View* old_result_view = container_children[i];
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(old_result_view));
- const gfx::RectF target_bounds = GetTargetLayerBounds(old_result_view);
- EXPECT_EQ(initial_bounds[i].size(), target_bounds.size());
- EXPECT_EQ(initial_bounds[i].x(), target_bounds.x());
- EXPECT_EQ(1.0f, old_result_view->layer()->opacity());
- EXPECT_EQ(0.0f, old_result_view->layer()->GetTargetOpacity());
- }
- } else {
- // Views before removed one should not animate.
- for (int i : std::set<int>{0, 1}) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- EXPECT_FALSE(container_children[i]->GetVisible());
- views::View* new_result_view = container_children[new_views_start + i];
- EXPECT_FALSE(new_result_view->layer()->GetAnimator()->is_animating());
- EXPECT_EQ(initial_bounds[i], GetCurrentLayerBounds(new_result_view));
- EXPECT_EQ(1.0f, new_result_view->layer()->opacity());
- }
- // The last new view should slide in.
- views::View* last_new_result_view = container_children[new_views_start + 2];
- EXPECT_EQ(initial_bounds[2], GetTargetLayerBounds(last_new_result_view));
- const gfx::RectF last_old_current_bounds =
- GetCurrentLayerBounds(last_new_result_view);
- EXPECT_EQ(initial_bounds[2].size(), last_old_current_bounds.size());
- EXPECT_LT(initial_bounds[2].x(), last_old_current_bounds.x());
- EXPECT_EQ(0.0f, last_new_result_view->layer()->opacity());
- EXPECT_EQ(1.0f, last_new_result_view->layer()->GetTargetOpacity());
- // The last old view should slide out.
- views::View* last_old_result_view = container_children[3];
- EXPECT_EQ(initial_bounds[3], GetCurrentLayerBounds(last_old_result_view));
- const gfx::RectF last_old_target_bounds =
- GetTargetLayerBounds(last_old_result_view);
- EXPECT_EQ(initial_bounds[3].size(), last_old_target_bounds.size());
- EXPECT_GT(initial_bounds[3].x(), last_old_target_bounds.x());
- EXPECT_EQ(1.0f, last_old_result_view->layer()->opacity());
- EXPECT_EQ(0.0f, last_old_result_view->layer()->GetTargetOpacity());
- }
- WaitForAllChildrenAnimationsToComplete(container_view);
- VerifyResultViewsUpdated();
- container_children = container_view->children();
- EXPECT_EQ(3u, container_children.size());
- for (int i = 0; i < 2; ++i) {
- SCOPED_TRACE(testing::Message() << "Item at " << i);
- views::View* result_view = GetResultViewAt(i);
- if (tablet_mode_param()) {
- EXPECT_EQ(initial_bounds[i].y(), result_view->layer()->bounds().y());
- } else {
- EXPECT_EQ(initial_bounds[i], gfx::RectF(result_view->layer()->bounds()));
- }
- EXPECT_EQ(gfx::Transform(), result_view->layer()->transform());
- EXPECT_EQ(1.0f, result_view->layer()->opacity());
- }
- }
- TEST_F(ContinueSectionViewClamshellModeTest, AnimatesOutAfterRemovingResults) {
- ResetPrivacyNoticePref();
- InitializeForAnimationTest(/*result_count=*/3);
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- views::View* privacy_notice =
- GetContinueSectionView()->GetPrivacyNoticeForTest();
- RemoveSearchResultAt(1);
- ContinueTaskContainerView* const container_view =
- GetContinueSectionView()->suggestions_container();
- container_view->Update();
- EXPECT_EQ(1.0f, privacy_notice->layer()->opacity());
- EXPECT_EQ(0.0f, privacy_notice->layer()->GetTargetOpacity());
- EXPECT_TRUE(privacy_notice->layer()->GetAnimator()->is_animating());
- LayerAnimationStoppedWaiter waiter;
- waiter.Wait(privacy_notice->layer());
- VerifyResultViewsUpdated();
- ASSERT_LE(GetContinueSectionView()->GetTasksSuggestionsCount(), 2u);
- EXPECT_FALSE(IsPrivacyNoticeVisible());
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- }
- TEST_P(ContinueSectionViewTest, AnimatesPrivacyNoticeAccept) {
- ResetPrivacyNoticePref();
- InitializeForAnimationTest(/*result_count=*/3);
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- AppListToastView* privacy_notice =
- GetContinueSectionView()->GetPrivacyNoticeForTest();
- GestureTapOn(privacy_notice->toast_button());
- EXPECT_EQ(1.0f, privacy_notice->layer()->opacity());
- EXPECT_EQ(0.0f, privacy_notice->layer()->GetTargetOpacity());
- EXPECT_TRUE(privacy_notice->layer()->GetAnimator()->is_animating());
- LayerAnimationStoppedWaiter waiter;
- waiter.Wait(privacy_notice->layer());
- ContinueTaskContainerView* container_view =
- GetContinueSectionView()->suggestions_container();
- EXPECT_TRUE(container_view->layer()->GetAnimator()->is_animating());
- WaitForAllChildrenAnimationsToComplete(container_view);
- EXPECT_FALSE(IsPrivacyNoticeVisible());
- EXPECT_TRUE(GetContinueSectionView()->GetVisible());
- }
- // Regression test for https://crbug.com/1326237.
- TEST_F(ContinueSectionViewClamshellModeTest,
- RemoveSearchResultWhileAnimatingContinueSection) {
- ResetPrivacyNoticePref();
- InitializeForAnimationTest(/*result_count=*/3);
- EXPECT_TRUE(IsPrivacyNoticeVisible());
- EXPECT_EQ(GetAppListNudgeController()->current_nudge(),
- AppListNudgeController::NudgeType::kPrivacyNotice);
- AppListToastView* privacy_notice =
- GetContinueSectionView()->GetPrivacyNoticeForTest();
- GestureTapOn(privacy_notice->toast_button());
- EXPECT_EQ(1.0f, privacy_notice->layer()->opacity());
- EXPECT_EQ(0.0f, privacy_notice->layer()->GetTargetOpacity());
- EXPECT_TRUE(privacy_notice->layer()->GetAnimator()->is_animating());
- RemoveSearchResultAt(0);
- EXPECT_EQ(0.0f, privacy_notice->layer()->GetTargetOpacity());
- EXPECT_TRUE(privacy_notice->layer()->GetAnimator()->is_animating());
- LayerAnimationStoppedWaiter waiter;
- waiter.Wait(privacy_notice->layer());
- WaitForAllChildrenAnimationsToComplete(
- GetContinueSectionView()->suggestions_container());
- EXPECT_FALSE(IsPrivacyNoticeVisible());
- EXPECT_FALSE(GetContinueSectionView()->GetVisible());
- }
- } // namespace
- } // namespace ash
|