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. 4 5 #include <vector> 6 7 #include "ash/root_window_controller.h" 8 #include "ash/shelf/shelf_layout_manager.h" 9 #include "ash/shell.h" 10 #include "ash/shell_delegate.h" 11 #include "ash/system/tray/system_tray.h" 12 #include "ash/system/user/tray_user.h" 13 #include "ash/test/ash_test_base.h" 14 #include "ash/test/test_session_state_delegate.h" 15 #include "ash/test/test_shell_delegate.h" 16 #include "ui/aura/test/event_generator.h" 17 #include "ui/base/animation/animation_container_element.h" 18 #include "ui/views/view.h" 19 #include "ui/views/widget/widget.h" 20 21 namespace ash { 22 namespace internal { 23 24 class TrayUserTest : public ash::test::AshTestBase { 25 public: 26 TrayUserTest(); 27 28 // testing::Test: 29 virtual void SetUp() OVERRIDE; 30 31 // This has to be called prior to first use with the proper configuration. 32 void InitializeParameters(int users_logged_in, bool multiprofile); 33 34 // Show the system tray menu using the provided event generator. 35 void ShowTrayMenu(aura::test::EventGenerator* generator); 36 37 // Move the mouse over the user item. 38 void MoveOverUserItem(aura::test::EventGenerator* generator, int index); 39 40 // Click on the user item. Note that the tray menu needs to be shown. 41 void ClickUserItem(aura::test::EventGenerator* generator, int index); 42 43 // Accessors to various system components. 44 ShelfLayoutManager* shelf() { return shelf_; } 45 SystemTray* tray() { return tray_; } 46 ash::test::TestSessionStateDelegate* delegate() { return delegate_; } 47 ash::internal::TrayUser* tray_user(int index) { return tray_user_[index]; } 48 49 private: 50 ShelfLayoutManager* shelf_; 51 SystemTray* tray_; 52 ash::test::TestSessionStateDelegate* delegate_; 53 // Note that the ownership of these items is on the shelf. 54 std::vector<ash::internal::TrayUser*> tray_user_; 55 56 DISALLOW_COPY_AND_ASSIGN(TrayUserTest); 57 }; 58 59 TrayUserTest::TrayUserTest() 60 : shelf_(NULL), 61 tray_(NULL), 62 delegate_(NULL) { 63 } 64 65 void TrayUserTest::SetUp() { 66 ash::test::AshTestBase::SetUp(); 67 shelf_ = Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); 68 tray_ = Shell::GetPrimaryRootWindowController()->GetSystemTray(); 69 delegate_ = static_cast<ash::test::TestSessionStateDelegate*>( 70 ash::Shell::GetInstance()->session_state_delegate()); 71 } 72 73 void TrayUserTest::InitializeParameters(int users_logged_in, 74 bool multiprofile) { 75 // Show the shelf. 76 shelf()->LayoutShelf(); 77 shelf()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 78 79 // Set our default assumptions. Note that it is sufficient to set these 80 // after everything was created. 81 delegate_->set_logged_in_users(users_logged_in); 82 ash::test::TestShellDelegate* shell_delegate = 83 static_cast<ash::test::TestShellDelegate*>( 84 ash::Shell::GetInstance()->delegate()); 85 shell_delegate->set_multi_profiles_enabled(multiprofile); 86 87 // Instead of using the existing tray panels we create new ones which makes 88 // the access easier. 89 // Note that we create one more element then there can be users to show a 90 // separator. 91 for (int i = 0; i <= delegate_->GetMaximumNumberOfLoggedInUsers(); i++) { 92 tray_user_.push_back(new ash::internal::TrayUser(tray_, i)); 93 tray_->AddTrayItem(tray_user_[i]); 94 } 95 } 96 97 void TrayUserTest::ShowTrayMenu(aura::test::EventGenerator* generator) { 98 gfx::Point center = tray()->GetBoundsInScreen().CenterPoint(); 99 100 generator->MoveMouseTo(center.x(), center.y()); 101 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 102 generator->ClickLeftButton(); 103 } 104 105 void TrayUserTest::MoveOverUserItem(aura::test::EventGenerator* generator, 106 int index) { 107 gfx::Point center = 108 tray_user(index)->GetUserPanelBoundsInScreenForTest().CenterPoint(); 109 110 generator->MoveMouseTo(center.x(), center.y()); 111 } 112 113 void TrayUserTest::ClickUserItem(aura::test::EventGenerator* generator, 114 int index) { 115 MoveOverUserItem(generator, index); 116 generator->ClickLeftButton(); 117 } 118 119 // Make sure that in single user mode the user panel cannot be activated and no 120 // separators are being created. 121 TEST_F(TrayUserTest, SingleUserModeDoesNotAllowAddingUser) { 122 InitializeParameters(1, false); 123 124 // Move the mouse over the status area and click to open the status menu. 125 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 126 127 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 128 129 for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 130 EXPECT_EQ(ash::internal::TrayUser::HIDDEN, 131 tray_user(i)->GetStateForTest()); 132 133 ShowTrayMenu(&generator); 134 135 EXPECT_TRUE(tray()->HasSystemBubble()); 136 EXPECT_TRUE(tray()->IsAnyBubbleVisible()); 137 138 for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 139 EXPECT_EQ(i == 0 ? ash::internal::TrayUser::SHOWN : 140 ash::internal::TrayUser::HIDDEN, 141 tray_user(i)->GetStateForTest()); 142 143 tray()->CloseSystemBubble(); 144 } 145 146 // Make sure that in multi user mode the user panel can be activated and there 147 // will be one panel for each user plus a separator. 148 // Note: the mouse watcher (for automatic closing upon leave) cannot be tested 149 // here since it does not work with the event system in unit tests. 150 TEST_F(TrayUserTest, MutiUserModeDoesNotAllowToAddUser) { 151 InitializeParameters(1, true); 152 153 // Move the mouse over the status area and click to open the status menu. 154 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 155 generator.set_async(false); 156 157 int max_users = delegate()->GetMaximumNumberOfLoggedInUsers(); 158 // Checking now for each amount of users that the correct is done. 159 for (int j = 1; j < max_users; j++) { 160 // Set the number of logged in users. 161 delegate()->set_logged_in_users(j); 162 163 // Verify that nothing is shown. 164 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 165 for (int i = 0; i <= max_users; i++) 166 EXPECT_FALSE(tray_user(i)->GetStateForTest()); 167 168 // After clicking on the tray the menu should get shown and for each logged 169 // in user we should get a visible item. In addition, the separator should 170 // show up when we reach more then one user. 171 ShowTrayMenu(&generator); 172 173 EXPECT_TRUE(tray()->HasSystemBubble()); 174 EXPECT_TRUE(tray()->IsAnyBubbleVisible()); 175 for (int i = 0; i < max_users; i++) { 176 EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN : 177 ash::internal::TrayUser::HIDDEN, 178 tray_user(i)->GetStateForTest()); 179 } 180 181 // Check the visibility of the separator. 182 EXPECT_EQ(j > 1 ? ash::internal::TrayUser::SEPARATOR : 183 ash::internal::TrayUser::HIDDEN, 184 tray_user(max_users)->GetStateForTest()); 185 186 // Move the mouse over the user item and it should hover. 187 MoveOverUserItem(&generator, 0); 188 EXPECT_EQ(ash::internal::TrayUser::HOVERED, 189 tray_user(0)->GetStateForTest()); 190 for (int i = 1; i < max_users; i++) { 191 EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN : 192 ash::internal::TrayUser::HIDDEN, 193 tray_user(i)->GetStateForTest()); 194 } 195 196 // Check that clicking the button allows to add item if we have still room 197 // for one more user. 198 ClickUserItem(&generator, 0); 199 EXPECT_EQ(j == max_users ? 200 ash::internal::TrayUser::ACTIVE_BUT_DISABLED : 201 ash::internal::TrayUser::ACTIVE, 202 tray_user(0)->GetStateForTest()); 203 204 // Click the button again to see that the menu goes away. 205 ClickUserItem(&generator, 0); 206 EXPECT_EQ(ash::internal::TrayUser::HOVERED, 207 tray_user(0)->GetStateForTest()); 208 209 // Close and check that everything is deleted. 210 tray()->CloseSystemBubble(); 211 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 212 for (int i = 0; i < delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 213 EXPECT_EQ(ash::internal::TrayUser::HIDDEN, 214 tray_user(i)->GetStateForTest()); 215 } 216 } 217 218 // Make sure that user changing gets properly executed. 219 TEST_F(TrayUserTest, MutiUserModeButtonClicks) { 220 // Have two users. 221 InitializeParameters(2, true); 222 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 223 ShowTrayMenu(&generator); 224 225 // Switch to a new user. 226 ClickUserItem(&generator, 1); 227 228 EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserEmail(1)); 229 tray()->CloseSystemBubble(); 230 } 231 232 } // namespace internal 233 } // namespace ash 234