Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / ash / wm / maximize_mode / maximize_mode_controller_unittest.cc
blob0bc86347f02d0941be73fab6de56d2ce20c11f0e
1 // Copyright 2014 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 <math.h>
7 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/shell.h"
12 #include "ash/system/tray/system_tray_delegate.h"
13 #include "ash/test/ash_test_base.h"
14 #include "ash/test/display_manager_test_api.h"
15 #include "ash/test/test_system_tray_delegate.h"
16 #include "ash/test/test_volume_control_delegate.h"
17 #include "ash/wm/overview/window_selector_controller.h"
18 #include "base/command_line.h"
19 #include "base/test/simple_test_tick_clock.h"
20 #include "base/test/user_action_tester.h"
21 #include "chromeos/accelerometer/accelerometer_reader.h"
22 #include "chromeos/accelerometer/accelerometer_types.h"
23 #include "ui/events/event_handler.h"
24 #include "ui/events/test/event_generator.h"
25 #include "ui/gfx/geometry/vector3d_f.h"
26 #include "ui/message_center/message_center.h"
28 #if defined(USE_X11)
29 #include "ui/events/test/events_test_utils_x11.h"
30 #endif
32 namespace ash {
34 namespace {
36 const float kDegreesToRadians = 3.1415926f / 180.0f;
37 const float kMeanGravity = 9.8066f;
39 const char kTouchViewInitiallyDisabled[] = "Touchview_Initially_Disabled";
40 const char kTouchViewEnabled[] = "Touchview_Enabled";
41 const char kTouchViewDisabled[] = "Touchview_Disabled";
43 } // namespace
45 // Test accelerometer data taken with the lid at less than 180 degrees while
46 // shaking the device around. The data is to be interpreted in groups of 6 where
47 // each 6 values corresponds to the base accelerometer (-y / g, -x / g, -z / g)
48 // followed by the lid accelerometer (-y / g , x / g, z / g).
49 extern const float kAccelerometerLaptopModeTestData[];
50 extern const size_t kAccelerometerLaptopModeTestDataLength;
52 // Test accelerometer data taken with the lid open 360 degrees while
53 // shaking the device around. The data is to be interpreted in groups of 6 where
54 // each 6 values corresponds to the base accelerometer (-y / g, -x / g, -z / g)
55 // followed by the lid accelerometer (-y / g , x / g, z / g).
56 extern const float kAccelerometerFullyOpenTestData[];
57 extern const size_t kAccelerometerFullyOpenTestDataLength;
59 // Test accelerometer data taken with the lid open 360 degrees while the device
60 // hinge was nearly vertical, while shaking the device around. The data is to be
61 // interpreted in groups of 6 where each 6 values corresponds to the X, Y, and Z
62 // readings from the base and lid accelerometers in this order.
63 extern const float kAccelerometerVerticalHingeTestData[];
64 extern const size_t kAccelerometerVerticalHingeTestDataLength;
66 class MaximizeModeControllerTest : public test::AshTestBase {
67 public:
68 MaximizeModeControllerTest() {}
69 ~MaximizeModeControllerTest() override {}
71 void SetUp() override {
72 test::AshTestBase::SetUp();
73 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(
74 maximize_mode_controller());
76 // Set the first display to be the internal display for the accelerometer
77 // screen rotation tests.
78 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
81 void TearDown() override {
82 chromeos::AccelerometerReader::GetInstance()->AddObserver(
83 maximize_mode_controller());
84 test::AshTestBase::TearDown();
87 MaximizeModeController* maximize_mode_controller() {
88 return Shell::GetInstance()->maximize_mode_controller();
91 void TriggerLidUpdate(const gfx::Vector3dF& lid) {
92 scoped_refptr<chromeos::AccelerometerUpdate> update(
93 new chromeos::AccelerometerUpdate());
94 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(),
95 lid.z());
96 maximize_mode_controller()->OnAccelerometerUpdated(update);
99 void TriggerBaseAndLidUpdate(const gfx::Vector3dF& base,
100 const gfx::Vector3dF& lid) {
101 scoped_refptr<chromeos::AccelerometerUpdate> update(
102 new chromeos::AccelerometerUpdate());
103 update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, base.x(),
104 base.y(), base.z());
105 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(),
106 lid.z());
107 maximize_mode_controller()->OnAccelerometerUpdated(update);
110 bool IsMaximizeModeStarted() {
111 return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled();
114 // Attaches a SimpleTestTickClock to the MaximizeModeController with a non
115 // null value initial value.
116 void AttachTickClockForTest() {
117 scoped_ptr<base::TickClock> tick_clock(
118 test_tick_clock_ = new base::SimpleTestTickClock());
119 test_tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
120 maximize_mode_controller()->SetTickClockForTest(tick_clock.Pass());
123 void AdvanceTickClock(const base::TimeDelta& delta) {
124 DCHECK(test_tick_clock_);
125 test_tick_clock_->Advance(delta);
128 void OpenLidToAngle(float degrees) {
129 DCHECK(degrees >= 0.0f);
130 DCHECK(degrees <= 360.0f);
132 float radians = degrees * kDegreesToRadians;
133 gfx::Vector3dF base_vector(0.0f, -kMeanGravity, 0.0f);
134 gfx::Vector3dF lid_vector(0.0f,
135 kMeanGravity * cos(radians),
136 kMeanGravity * sin(radians));
137 TriggerBaseAndLidUpdate(base_vector, lid_vector);
140 void OpenLid() {
141 maximize_mode_controller()->LidEventReceived(true /* open */,
142 maximize_mode_controller()->tick_clock_->NowTicks());
145 void CloseLid() {
146 maximize_mode_controller()->LidEventReceived(false /* open */,
147 maximize_mode_controller()->tick_clock_->NowTicks());
150 bool WasLidOpenedRecently() {
151 return maximize_mode_controller()->WasLidOpenedRecently();
154 base::UserActionTester* user_action_tester() { return &user_action_tester_; }
156 private:
157 base::SimpleTestTickClock* test_tick_clock_;
159 // Tracks user action counts.
160 base::UserActionTester user_action_tester_;
162 DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerTest);
165 // Verify TouchView enabled/disabled user action metrics are recorded.
166 TEST_F(MaximizeModeControllerTest, VerifyTouchViewEnabledDisabledCounts) {
167 ASSERT_EQ(1,
168 user_action_tester()->GetActionCount(kTouchViewInitiallyDisabled));
169 ASSERT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled));
170 ASSERT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled));
172 user_action_tester()->ResetCounts();
173 maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
174 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewEnabled));
175 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled));
176 maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
177 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewEnabled));
178 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled));
180 user_action_tester()->ResetCounts();
181 maximize_mode_controller()->EnableMaximizeModeWindowManager(false);
182 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled));
183 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewDisabled));
184 maximize_mode_controller()->EnableMaximizeModeWindowManager(false);
185 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled));
186 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewDisabled));
189 // Verify that closing the lid will exit maximize mode.
190 TEST_F(MaximizeModeControllerTest, CloseLidWhileInMaximizeMode) {
191 OpenLidToAngle(315.0f);
192 ASSERT_TRUE(IsMaximizeModeStarted());
194 CloseLid();
195 EXPECT_FALSE(IsMaximizeModeStarted());
198 // Verify that maximize mode will not be entered when the lid is closed.
199 TEST_F(MaximizeModeControllerTest,
200 HingeAnglesWithLidClosed) {
201 AttachTickClockForTest();
203 CloseLid();
205 OpenLidToAngle(270.0f);
206 EXPECT_FALSE(IsMaximizeModeStarted());
208 OpenLidToAngle(315.0f);
209 EXPECT_FALSE(IsMaximizeModeStarted());
211 OpenLidToAngle(355.0f);
212 EXPECT_FALSE(IsMaximizeModeStarted());
215 // Verify the maximize mode state for unstable hinge angles when the lid was
216 // recently open.
217 TEST_F(MaximizeModeControllerTest,
218 UnstableHingeAnglesWhenLidRecentlyOpened) {
219 AttachTickClockForTest();
221 OpenLid();
222 ASSERT_TRUE(WasLidOpenedRecently());
224 OpenLidToAngle(5.0f);
225 EXPECT_FALSE(IsMaximizeModeStarted());
227 OpenLidToAngle(355.0f);
228 EXPECT_FALSE(IsMaximizeModeStarted());
230 // This is a stable reading and should clear the last lid opened time.
231 OpenLidToAngle(45.0f);
232 EXPECT_FALSE(IsMaximizeModeStarted());
233 EXPECT_FALSE(WasLidOpenedRecently());
235 OpenLidToAngle(355.0f);
236 EXPECT_TRUE(IsMaximizeModeStarted());
239 // Verify the WasLidOpenedRecently signal with respect to time.
240 TEST_F(MaximizeModeControllerTest, WasLidOpenedRecentlyOverTime) {
241 AttachTickClockForTest();
243 // No lid open time initially.
244 ASSERT_FALSE(WasLidOpenedRecently());
246 CloseLid();
247 EXPECT_FALSE(WasLidOpenedRecently());
249 OpenLid();
250 EXPECT_TRUE(WasLidOpenedRecently());
252 // 1 second after lid open.
253 AdvanceTickClock(base::TimeDelta::FromSeconds(1));
254 EXPECT_TRUE(WasLidOpenedRecently());
256 // 3 seconds after lid open.
257 AdvanceTickClock(base::TimeDelta::FromSeconds(2));
258 EXPECT_FALSE(WasLidOpenedRecently());
261 // Verify the maximize mode enter/exit thresholds for stable angles.
262 TEST_F(MaximizeModeControllerTest, StableHingeAnglesWithLidOpened) {
263 ASSERT_FALSE(IsMaximizeModeStarted());
264 ASSERT_FALSE(WasLidOpenedRecently());
266 OpenLidToAngle(180.0f);
267 EXPECT_FALSE(IsMaximizeModeStarted());
269 OpenLidToAngle(315.0f);
270 EXPECT_TRUE(IsMaximizeModeStarted());
272 OpenLidToAngle(180.0f);
273 EXPECT_TRUE(IsMaximizeModeStarted());
275 OpenLidToAngle(45.0f);
276 EXPECT_FALSE(IsMaximizeModeStarted());
278 OpenLidToAngle(270.0f);
279 EXPECT_TRUE(IsMaximizeModeStarted());
281 OpenLidToAngle(90.0f);
282 EXPECT_FALSE(IsMaximizeModeStarted());
285 // Verify the maximize mode state for unstable hinge angles when the lid is open
286 // but not recently.
287 TEST_F(MaximizeModeControllerTest, UnstableHingeAnglesWithLidOpened) {
288 AttachTickClockForTest();
290 ASSERT_FALSE(WasLidOpenedRecently());
291 ASSERT_FALSE(IsMaximizeModeStarted());
293 OpenLidToAngle(5.0f);
294 EXPECT_FALSE(IsMaximizeModeStarted());
296 OpenLidToAngle(355.0f);
297 EXPECT_TRUE(IsMaximizeModeStarted());
299 OpenLidToAngle(5.0f);
300 EXPECT_TRUE(IsMaximizeModeStarted());
303 // Tests that when the hinge is nearly vertically aligned, the current state
304 // persists as the computed angle is highly inaccurate in this orientation.
305 TEST_F(MaximizeModeControllerTest, HingeAligned) {
306 // Laptop in normal orientation lid open 90 degrees.
307 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
308 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
309 EXPECT_FALSE(IsMaximizeModeStarted());
311 // Completely vertical.
312 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
313 gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
314 EXPECT_FALSE(IsMaximizeModeStarted());
316 // Close to vertical but with hinge appearing to be open 270 degrees.
317 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
318 gfx::Vector3dF(kMeanGravity, 0.1f, 0.0f));
319 EXPECT_FALSE(IsMaximizeModeStarted());
321 // Flat and open 270 degrees should start maximize mode.
322 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
323 gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
324 EXPECT_TRUE(IsMaximizeModeStarted());
326 // Normal 90 degree orientation but near vertical should stay in maximize
327 // mode.
328 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
329 gfx::Vector3dF(kMeanGravity, -0.1f, 0.0f));
330 EXPECT_TRUE(IsMaximizeModeStarted());
333 TEST_F(MaximizeModeControllerTest, LaptopTest) {
334 // Feeds in sample accelerometer data and verifies that there are no
335 // transitions into touchview / maximize mode while shaking the device around
336 // with the hinge at less than 180 degrees. Note the conversion from device
337 // data to accelerometer updates consistent with accelerometer_reader.cc.
338 ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength % 6);
339 for (size_t i = 0; i < kAccelerometerLaptopModeTestDataLength / 6; ++i) {
340 gfx::Vector3dF base(-kAccelerometerLaptopModeTestData[i * 6 + 1],
341 -kAccelerometerLaptopModeTestData[i * 6],
342 -kAccelerometerLaptopModeTestData[i * 6 + 2]);
343 base.Scale(kMeanGravity);
344 gfx::Vector3dF lid(-kAccelerometerLaptopModeTestData[i * 6 + 4],
345 kAccelerometerLaptopModeTestData[i * 6 + 3],
346 kAccelerometerLaptopModeTestData[i * 6 + 5]);
347 lid.Scale(kMeanGravity);
348 TriggerBaseAndLidUpdate(base, lid);
349 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
350 // one failure rather than potentially hundreds.
351 ASSERT_FALSE(IsMaximizeModeStarted());
355 TEST_F(MaximizeModeControllerTest, MaximizeModeTest) {
356 // Trigger maximize mode by opening to 270 to begin the test in maximize mode.
357 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
358 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
359 ASSERT_TRUE(IsMaximizeModeStarted());
361 // Feeds in sample accelerometer data and verifies that there are no
362 // transitions out of touchview / maximize mode while shaking the device
363 // around. Note the conversion from device data to accelerometer updates
364 // consistent with accelerometer_reader.cc.
365 ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength % 6);
366 for (size_t i = 0; i < kAccelerometerFullyOpenTestDataLength / 6; ++i) {
367 gfx::Vector3dF base(-kAccelerometerFullyOpenTestData[i * 6 + 1],
368 -kAccelerometerFullyOpenTestData[i * 6],
369 -kAccelerometerFullyOpenTestData[i * 6 + 2]);
370 base.Scale(kMeanGravity);
371 gfx::Vector3dF lid(-kAccelerometerFullyOpenTestData[i * 6 + 4],
372 kAccelerometerFullyOpenTestData[i * 6 + 3],
373 kAccelerometerFullyOpenTestData[i * 6 + 5]);
374 lid.Scale(kMeanGravity);
375 TriggerBaseAndLidUpdate(base, lid);
376 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
377 // one failure rather than potentially hundreds.
378 ASSERT_TRUE(IsMaximizeModeStarted());
382 TEST_F(MaximizeModeControllerTest, VerticalHingeTest) {
383 // Feeds in sample accelerometer data and verifies that there are no
384 // transitions out of touchview / maximize mode while shaking the device
385 // around, while the hinge is nearly vertical. The data was captured from
386 // maxmimize_mode_controller.cc and does not require conversion.
387 ASSERT_EQ(0u, kAccelerometerVerticalHingeTestDataLength % 6);
388 for (size_t i = 0; i < kAccelerometerVerticalHingeTestDataLength / 6; ++i) {
389 gfx::Vector3dF base(kAccelerometerVerticalHingeTestData[i * 6],
390 kAccelerometerVerticalHingeTestData[i * 6 + 1],
391 kAccelerometerVerticalHingeTestData[i * 6 + 2]);
392 gfx::Vector3dF lid(kAccelerometerVerticalHingeTestData[i * 6 + 3],
393 kAccelerometerVerticalHingeTestData[i * 6 + 4],
394 kAccelerometerVerticalHingeTestData[i * 6 + 5]);
395 TriggerBaseAndLidUpdate(base, lid);
396 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
397 // one failure rather than potentially hundreds.
398 ASSERT_TRUE(IsMaximizeModeStarted());
402 // Tests that CanEnterMaximizeMode returns false until a valid accelerometer
403 // event has been received, and that it returns true afterwards.
404 TEST_F(MaximizeModeControllerTest,
405 CanEnterMaximizeModeRequiresValidAccelerometerUpdate) {
406 // Should be false until an accelerometer event is sent.
407 ASSERT_FALSE(maximize_mode_controller()->CanEnterMaximizeMode());
408 OpenLidToAngle(90.0f);
409 EXPECT_TRUE(maximize_mode_controller()->CanEnterMaximizeMode());
412 // Tests that when an accelerometer event is received which has no keyboard that
413 // we enter maximize mode.
414 TEST_F(MaximizeModeControllerTest,
415 NoKeyboardAccelerometerTriggersMaximizeMode) {
416 ASSERT_FALSE(IsMaximizeModeStarted());
417 TriggerLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity));
418 ASSERT_TRUE(IsMaximizeModeStarted());
421 // Test if this case does not crash. See http://crbug.com/462806
422 TEST_F(MaximizeModeControllerTest, DisplayDisconnectionDuringOverview) {
423 if (!SupportsMultipleDisplays())
424 return;
426 UpdateDisplay("800x600,800x600");
427 scoped_ptr<aura::Window> w1(
428 CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 100, 100)));
429 scoped_ptr<aura::Window> w2(
430 CreateTestWindowInShellWithBounds(gfx::Rect(800, 0, 100, 100)));
431 ASSERT_NE(w1->GetRootWindow(), w2->GetRootWindow());
433 maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
434 Shell::GetInstance()->window_selector_controller()->ToggleOverview();
436 UpdateDisplay("800x600");
437 EXPECT_FALSE(
438 Shell::GetInstance()->window_selector_controller()->IsSelecting());
439 EXPECT_EQ(w1->GetRootWindow(), w2->GetRootWindow());
442 class MaximizeModeControllerSwitchesTest : public MaximizeModeControllerTest {
443 public:
444 MaximizeModeControllerSwitchesTest() {}
445 ~MaximizeModeControllerSwitchesTest() override {}
447 void SetUp() override {
448 base::CommandLine::ForCurrentProcess()->AppendSwitch(
449 switches::kAshEnableTouchViewTesting);
450 MaximizeModeControllerTest::SetUp();
452 private:
453 DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerSwitchesTest);
456 // Tests that when the command line switch for testing maximize mode is on, that
457 // accelerometer updates which would normally cause it to exit do not.
458 TEST_F(MaximizeModeControllerSwitchesTest, IgnoreHingeAngles) {
459 maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
461 // Would normally trigger an exit from maximize mode.
462 OpenLidToAngle(90.0f);
463 EXPECT_TRUE(IsMaximizeModeStarted());
466 } // namespace ash