1 // Copyright 2013 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.
5 #include "ash/system/tray/tray_details_view.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf_widget.h"
10 #include "ash/system/status_area_widget.h"
11 #include "ash/system/tray/hover_highlight_view.h"
12 #include "ash/system/tray/special_popup_row.h"
13 #include "ash/system/tray/system_tray.h"
14 #include "ash/system/tray/system_tray_item.h"
15 #include "ash/system/tray/tray_details_view.h"
16 #include "ash/system/tray/view_click_listener.h"
17 #include "ash/test/ash_test_base.h"
18 #include "base/command_line.h"
19 #include "base/run_loop.h"
20 #include "grit/ash_strings.h"
21 #include "ui/aura/window.h"
22 #include "ui/base/ui_base_switches.h"
23 #include "ui/events/test/event_generator.h"
24 #include "ui/views/view.h"
25 #include "ui/views/widget/widget.h"
32 SystemTray* GetSystemTray() {
33 return Shell::GetPrimaryRootWindowController()->shelf()->
34 status_area_widget()->system_tray();
37 class TestDetailsView : public TrayDetailsView, public ViewClickListener {
39 explicit TestDetailsView(SystemTrayItem* owner) : TrayDetailsView(owner) {
40 // Uses bluetooth label for testing purpose. It can be changed to any
42 CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this);
45 ~TestDetailsView() override {}
48 footer()->content()->RequestFocus();
51 // Overridden from ViewClickListener:
52 void OnViewClicked(views::View* sender) override {}
55 DISALLOW_COPY_AND_ASSIGN(TestDetailsView);
58 // Trivial item implementation that tracks its views for testing.
59 class TestItem : public SystemTrayItem {
61 TestItem() : SystemTrayItem(GetSystemTray()), tray_view_(NULL) {}
63 // Overridden from SystemTrayItem:
64 views::View* CreateTrayView(user::LoginStatus status) override {
65 tray_view_ = new views::View;
68 views::View* CreateDefaultView(user::LoginStatus status) override {
69 default_view_ = new views::View;
70 default_view_->SetFocusable(true);
73 views::View* CreateDetailedView(user::LoginStatus status) override {
74 detailed_view_ = new TestDetailsView(this);
75 return detailed_view_;
77 void DestroyTrayView() override { tray_view_ = NULL; }
78 void DestroyDefaultView() override { default_view_ = NULL; }
79 void DestroyDetailedView() override { detailed_view_ = NULL; }
81 views::View* tray_view() const { return tray_view_; }
82 views::View* default_view() const { return default_view_; }
83 TestDetailsView* detailed_view() const { return detailed_view_; }
86 views::View* tray_view_;
87 views::View* default_view_;
88 TestDetailsView* detailed_view_;
90 DISALLOW_COPY_AND_ASSIGN(TestItem);
95 class TrayDetailsViewTest : public AshTestBase {
97 TrayDetailsViewTest() {}
98 ~TrayDetailsViewTest() override {}
100 HoverHighlightView* CreateAndShowHoverHighlightView() {
101 SystemTray* tray = GetSystemTray();
102 TestItem* test_item = new TestItem;
103 tray->AddTrayItem(test_item);
104 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
105 RunAllPendingInMessageLoop();
106 tray->ShowDetailedView(test_item, 0, true, BUBBLE_USE_EXISTING);
107 RunAllPendingInMessageLoop();
109 return static_cast<HoverHighlightView*>(test_item->detailed_view()->
110 footer()->content());
113 void SetUp() override {
114 base::CommandLine::ForCurrentProcess()->AppendSwitch(
115 switches::kEnableTouchFeedback);
116 test::AshTestBase::SetUp();
120 DISALLOW_COPY_AND_ASSIGN(TrayDetailsViewTest);
123 TEST_F(TrayDetailsViewTest, TransitionToDefaultViewTest) {
124 SystemTray* tray = GetSystemTray();
125 ASSERT_TRUE(tray->GetWidget());
127 TestItem* test_item_1 = new TestItem;
128 TestItem* test_item_2 = new TestItem;
129 tray->AddTrayItem(test_item_1);
130 tray->AddTrayItem(test_item_2);
132 // Ensure the tray views are created.
133 ASSERT_TRUE(test_item_1->tray_view() != NULL);
134 ASSERT_TRUE(test_item_2->tray_view() != NULL);
136 // Show the default view.
137 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
138 RunAllPendingInMessageLoop();
140 // Show the detailed view of item 2.
141 tray->ShowDetailedView(test_item_2, 0, true, BUBBLE_USE_EXISTING);
142 EXPECT_TRUE(test_item_2->detailed_view());
143 RunAllPendingInMessageLoop();
144 EXPECT_FALSE(test_item_2->default_view());
146 // Transition back to default view, the default view of item 2 should have
148 test_item_2->detailed_view()->FocusFooter();
149 test_item_2->detailed_view()->TransitionToDefaultView();
150 RunAllPendingInMessageLoop();
152 EXPECT_TRUE(test_item_2->default_view());
153 EXPECT_FALSE(test_item_2->detailed_view());
154 EXPECT_TRUE(test_item_2->default_view()->HasFocus());
156 // Show the detailed view of item 2 again.
157 tray->ShowDetailedView(test_item_2, 0, true, BUBBLE_USE_EXISTING);
158 EXPECT_TRUE(test_item_2->detailed_view());
159 RunAllPendingInMessageLoop();
160 EXPECT_FALSE(test_item_2->default_view());
162 // Transition back to default view, the default view of item 2 should NOT have
164 test_item_2->detailed_view()->TransitionToDefaultView();
165 RunAllPendingInMessageLoop();
167 EXPECT_TRUE(test_item_2->default_view());
168 EXPECT_FALSE(test_item_2->detailed_view());
169 EXPECT_FALSE(test_item_2->default_view()->HasFocus());
172 // Tests that HoverHighlightView enters hover state in response to touch.
173 TEST_F(TrayDetailsViewTest, HoverHighlightViewTouchFeedback) {
174 HoverHighlightView* view = CreateAndShowHoverHighlightView();
175 EXPECT_FALSE(view->hover());
177 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
178 generator.set_current_location(view->GetBoundsInScreen().CenterPoint());
179 generator.PressTouch();
180 RunAllPendingInMessageLoop();
181 EXPECT_TRUE(view->hover());
183 generator.ReleaseTouch();
184 RunAllPendingInMessageLoop();
185 EXPECT_FALSE(view->hover());
188 // Tests that touch events leaving HoverHighlightView cancel the hover state.
189 TEST_F(TrayDetailsViewTest, HoverHighlightViewTouchFeedbackCancellation) {
190 HoverHighlightView* view = CreateAndShowHoverHighlightView();
191 EXPECT_FALSE(view->hover());
193 gfx::Rect view_bounds = view->GetBoundsInScreen();
194 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
195 generator.set_current_location(view_bounds.CenterPoint());
196 generator.PressTouch();
197 RunAllPendingInMessageLoop();
198 EXPECT_TRUE(view->hover());
200 gfx::Point move_point(view_bounds.x(), view_bounds.CenterPoint().y());
201 generator.MoveTouch(move_point);
202 RunAllPendingInMessageLoop();
203 EXPECT_FALSE(view->hover());
205 generator.set_current_location(move_point);
206 generator.ReleaseTouch();
207 RunAllPendingInMessageLoop();
208 EXPECT_FALSE(view->hover());