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.
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 "base/command_line.h"
18 #include "base/test/simple_test_tick_clock.h"
19 #include "chromeos/accelerometer/accelerometer_reader.h"
20 #include "ui/accelerometer/accelerometer_types.h"
21 #include "ui/events/event_handler.h"
22 #include "ui/events/test/event_generator.h"
23 #include "ui/gfx/geometry/vector3d_f.h"
24 #include "ui/message_center/message_center.h"
27 #include "ui/events/test/events_test_utils_x11.h"
34 const float kDegreesToRadians
= 3.1415926f
/ 180.0f
;
35 const float kMeanGravity
= 9.8066f
;
39 // Test accelerometer data taken with the lid at less than 180 degrees while
40 // shaking the device around. The data is to be interpreted in groups of 6 where
41 // each 6 values corresponds to the X, Y, and Z readings from the base and lid
42 // accelerometers in this order.
43 extern const float kAccelerometerLaptopModeTestData
[];
44 extern const size_t kAccelerometerLaptopModeTestDataLength
;
46 // Test accelerometer data taken with the lid open 360 degrees while
47 // shaking the device around. The data is to be interpreted in groups of 6 where
48 // each 6 values corresponds to the X, Y, and Z readings from the base and lid
49 // accelerometers in this order.
50 extern const float kAccelerometerFullyOpenTestData
[];
51 extern const size_t kAccelerometerFullyOpenTestDataLength
;
53 class MaximizeModeControllerTest
: public test::AshTestBase
{
55 MaximizeModeControllerTest() {}
56 ~MaximizeModeControllerTest() override
{}
58 void SetUp() override
{
59 test::AshTestBase::SetUp();
60 Shell::GetInstance()->accelerometer_reader()->RemoveObserver(
61 maximize_mode_controller());
63 // Set the first display to be the internal display for the accelerometer
64 // screen rotation tests.
65 test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
66 SetFirstDisplayAsInternalDisplay();
69 void TearDown() override
{
70 Shell::GetInstance()->accelerometer_reader()->AddObserver(
71 maximize_mode_controller());
72 test::AshTestBase::TearDown();
75 MaximizeModeController
* maximize_mode_controller() {
76 return Shell::GetInstance()->maximize_mode_controller();
79 void TriggerLidUpdate(const gfx::Vector3dF
& lid
) {
80 ui::AccelerometerUpdate update
;
81 update
.Set(ui::ACCELEROMETER_SOURCE_SCREEN
, lid
.x(), lid
.y(), lid
.z());
82 maximize_mode_controller()->OnAccelerometerUpdated(update
);
85 void TriggerBaseAndLidUpdate(const gfx::Vector3dF
& base
,
86 const gfx::Vector3dF
& lid
) {
87 ui::AccelerometerUpdate update
;
88 update
.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD
,
89 base
.x(), base
.y(), base
.z());
90 update
.Set(ui::ACCELEROMETER_SOURCE_SCREEN
,
91 lid
.x(), lid
.y(), lid
.z());
92 maximize_mode_controller()->OnAccelerometerUpdated(update
);
95 bool IsMaximizeModeStarted() {
96 return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled();
99 gfx::Display::Rotation
GetInternalDisplayRotation() const {
100 return Shell::GetInstance()->display_manager()->GetDisplayInfo(
101 gfx::Display::InternalDisplayId()).rotation();
104 void SetInternalDisplayRotation(gfx::Display::Rotation rotation
) const {
105 Shell::GetInstance()->display_manager()->
106 SetDisplayRotation(gfx::Display::InternalDisplayId(), rotation
);
109 // Attaches a SimpleTestTickClock to the MaximizeModeController with a non
110 // null value initial value.
111 void AttachTickClockForTest() {
112 scoped_ptr
<base::TickClock
> tick_clock(
113 test_tick_clock_
= new base::SimpleTestTickClock());
114 test_tick_clock_
->Advance(base::TimeDelta::FromSeconds(1));
115 maximize_mode_controller()->SetTickClockForTest(tick_clock
.Pass());
118 void AdvanceTickClock(const base::TimeDelta
& delta
) {
119 DCHECK(test_tick_clock_
);
120 test_tick_clock_
->Advance(delta
);
123 void OpenLidToAngle(float degrees
) {
124 DCHECK(degrees
>= 0.0f
);
125 DCHECK(degrees
<= 360.0f
);
127 float radians
= degrees
* kDegreesToRadians
;
128 gfx::Vector3dF
base_vector(0.0f
, -kMeanGravity
, 0.0f
);
129 gfx::Vector3dF
lid_vector(0.0f
,
130 kMeanGravity
* cos(radians
),
131 kMeanGravity
* sin(radians
));
132 TriggerBaseAndLidUpdate(base_vector
, lid_vector
);
136 maximize_mode_controller()->LidEventReceived(true /* open */,
137 maximize_mode_controller()->tick_clock_
->NowTicks());
141 maximize_mode_controller()->LidEventReceived(false /* open */,
142 maximize_mode_controller()->tick_clock_
->NowTicks());
145 bool WasLidOpenedRecently() {
146 return maximize_mode_controller()->WasLidOpenedRecently();
150 base::SimpleTestTickClock
* test_tick_clock_
;
152 DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerTest
);
155 // Verify that closing the lid will exit maximize mode.
156 TEST_F(MaximizeModeControllerTest
, CloseLidWhileInMaximizeMode
) {
157 OpenLidToAngle(315.0f
);
158 ASSERT_TRUE(IsMaximizeModeStarted());
161 EXPECT_FALSE(IsMaximizeModeStarted());
164 // Verify that maximize mode will not be entered when the lid is closed.
165 TEST_F(MaximizeModeControllerTest
,
166 HingeAnglesWithLidClosed
) {
167 AttachTickClockForTest();
171 OpenLidToAngle(270.0f
);
172 EXPECT_FALSE(IsMaximizeModeStarted());
174 OpenLidToAngle(315.0f
);
175 EXPECT_FALSE(IsMaximizeModeStarted());
177 OpenLidToAngle(355.0f
);
178 EXPECT_FALSE(IsMaximizeModeStarted());
181 // Verify the maximize mode state for unstable hinge angles when the lid was
183 TEST_F(MaximizeModeControllerTest
,
184 UnstableHingeAnglesWhenLidRecentlyOpened
) {
185 AttachTickClockForTest();
188 ASSERT_TRUE(WasLidOpenedRecently());
190 OpenLidToAngle(5.0f
);
191 EXPECT_FALSE(IsMaximizeModeStarted());
193 OpenLidToAngle(355.0f
);
194 EXPECT_FALSE(IsMaximizeModeStarted());
196 // This is a stable reading and should clear the last lid opened time.
197 OpenLidToAngle(45.0f
);
198 EXPECT_FALSE(IsMaximizeModeStarted());
199 EXPECT_FALSE(WasLidOpenedRecently());
201 OpenLidToAngle(355.0f
);
202 EXPECT_TRUE(IsMaximizeModeStarted());
205 // Verify the WasLidOpenedRecently signal with respect to time.
206 TEST_F(MaximizeModeControllerTest
, WasLidOpenedRecentlyOverTime
) {
207 AttachTickClockForTest();
209 // No lid open time initially.
210 ASSERT_FALSE(WasLidOpenedRecently());
213 EXPECT_FALSE(WasLidOpenedRecently());
216 EXPECT_TRUE(WasLidOpenedRecently());
218 // 1 second after lid open.
219 AdvanceTickClock(base::TimeDelta::FromSeconds(1));
220 EXPECT_TRUE(WasLidOpenedRecently());
222 // 3 seconds after lid open.
223 AdvanceTickClock(base::TimeDelta::FromSeconds(2));
224 EXPECT_FALSE(WasLidOpenedRecently());
227 // Verify the maximize mode enter/exit thresholds for stable angles.
228 TEST_F(MaximizeModeControllerTest
, StableHingeAnglesWithLidOpened
) {
229 ASSERT_FALSE(IsMaximizeModeStarted());
230 ASSERT_FALSE(WasLidOpenedRecently());
232 OpenLidToAngle(180.0f
);
233 EXPECT_FALSE(IsMaximizeModeStarted());
235 OpenLidToAngle(315.0f
);
236 EXPECT_TRUE(IsMaximizeModeStarted());
238 OpenLidToAngle(180.0f
);
239 EXPECT_TRUE(IsMaximizeModeStarted());
241 OpenLidToAngle(45.0f
);
242 EXPECT_FALSE(IsMaximizeModeStarted());
244 OpenLidToAngle(270.0f
);
245 EXPECT_TRUE(IsMaximizeModeStarted());
247 OpenLidToAngle(90.0f
);
248 EXPECT_FALSE(IsMaximizeModeStarted());
251 // Verify the maximize mode state for unstable hinge angles when the lid is open
253 TEST_F(MaximizeModeControllerTest
, UnstableHingeAnglesWithLidOpened
) {
254 AttachTickClockForTest();
256 ASSERT_FALSE(WasLidOpenedRecently());
257 ASSERT_FALSE(IsMaximizeModeStarted());
259 OpenLidToAngle(5.0f
);
260 EXPECT_FALSE(IsMaximizeModeStarted());
262 OpenLidToAngle(355.0f
);
263 EXPECT_TRUE(IsMaximizeModeStarted());
265 OpenLidToAngle(5.0f
);
266 EXPECT_TRUE(IsMaximizeModeStarted());
269 // Tests that when the hinge is nearly vertically aligned, the current state
270 // persists as the computed angle is highly inaccurate in this orientation.
271 TEST_F(MaximizeModeControllerTest
, HingeAligned
) {
272 // Laptop in normal orientation lid open 90 degrees.
273 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, -kMeanGravity
),
274 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
275 EXPECT_FALSE(IsMaximizeModeStarted());
277 // Completely vertical.
278 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
),
279 gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
280 EXPECT_FALSE(IsMaximizeModeStarted());
282 // Close to vertical but with hinge appearing to be open 270 degrees.
283 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, -0.1f
),
284 gfx::Vector3dF(kMeanGravity
, 0.1f
, 0.0f
));
285 EXPECT_FALSE(IsMaximizeModeStarted());
287 // Flat and open 270 degrees should start maximize mode.
288 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, -kMeanGravity
),
289 gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
290 EXPECT_TRUE(IsMaximizeModeStarted());
292 // Normal 90 degree orientation but near vertical should stay in maximize
294 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, -0.1f
),
295 gfx::Vector3dF(kMeanGravity
, -0.1f
, 0.0f
));
296 EXPECT_TRUE(IsMaximizeModeStarted());
299 // Tests that only getting a lid accelerometer update will enter maximize
300 // mode and rotate the screen.
301 TEST_F(MaximizeModeControllerTest
, LidOnlyDisplayRotation
) {
302 ASSERT_FALSE(IsMaximizeModeStarted());
303 // Test rotating in all directions.
304 TriggerLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
305 // The first update should have entered maximize mode.
306 ASSERT_TRUE(IsMaximizeModeStarted());
307 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
308 TriggerLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
309 EXPECT_EQ(gfx::Display::ROTATE_180
, GetInternalDisplayRotation());
310 TriggerLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
311 EXPECT_EQ(gfx::Display::ROTATE_270
, GetInternalDisplayRotation());
312 TriggerLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
313 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
316 // Tests that accelerometer readings in each of the screen angles will trigger a
317 // rotation of the internal display.
318 TEST_F(MaximizeModeControllerTest
, DisplayRotation
) {
319 // Trigger maximize mode by opening to 270.
320 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
321 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
322 ASSERT_TRUE(IsMaximizeModeStarted());
324 // Now test rotating in all directions.
325 TriggerBaseAndLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
),
326 gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
327 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
328 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
),
329 gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
330 EXPECT_EQ(gfx::Display::ROTATE_180
, GetInternalDisplayRotation());
331 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
),
332 gfx::Vector3dF(kMeanGravity
, 0.0f
, 0.0f
));
333 EXPECT_EQ(gfx::Display::ROTATE_270
, GetInternalDisplayRotation());
334 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
),
335 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
336 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
339 // Tests that low angles are ignored by the accelerometer (i.e. when the device
340 // is almost laying flat).
341 TEST_F(MaximizeModeControllerTest
, RotationIgnoresLowAngles
) {
342 // Trigger maximize mode by opening to 270.
343 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
344 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
345 ASSERT_TRUE(IsMaximizeModeStarted());
347 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, kMeanGravity
, kMeanGravity
),
348 gfx::Vector3dF(0.0f
, -kMeanGravity
, -kMeanGravity
));
349 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
350 TriggerBaseAndLidUpdate(gfx::Vector3dF(-2.0f
, 0.0f
, kMeanGravity
),
351 gfx::Vector3dF(-2.0f
, 0.0f
, -kMeanGravity
));
352 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
353 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, -2.0f
, kMeanGravity
),
354 gfx::Vector3dF(0.0f
, 2.0f
, -kMeanGravity
));
355 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
356 TriggerBaseAndLidUpdate(gfx::Vector3dF(2.0f
, 0.0f
, kMeanGravity
),
357 gfx::Vector3dF(2.0f
, 0.0f
, -kMeanGravity
));
358 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
359 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 2.0f
, kMeanGravity
),
360 gfx::Vector3dF(0.0f
, -2.0f
, -kMeanGravity
));
361 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
364 // Tests that the display will stick to the current orientation beyond the
365 // halfway point, preventing frequent updates back and forth.
366 TEST_F(MaximizeModeControllerTest
, RotationSticky
) {
367 // Trigger maximize mode by opening to 270.
368 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
369 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
370 ASSERT_TRUE(IsMaximizeModeStarted());
372 gfx::Vector3dF
gravity(0.0f
, -kMeanGravity
, 0.0f
);
373 TriggerBaseAndLidUpdate(gravity
, gravity
);
374 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
376 // Turn past half-way point to next direction and rotation should remain
378 float degrees
= 50.0;
379 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
380 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
381 TriggerBaseAndLidUpdate(gravity
, gravity
);
382 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
384 // Turn more and the screen should rotate.
386 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
387 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
388 TriggerBaseAndLidUpdate(gravity
, gravity
);
389 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
391 // Turn back just beyond the half-way point and the new rotation should
392 // still be in effect.
394 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
395 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
396 TriggerBaseAndLidUpdate(gravity
, gravity
);
397 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
400 // Tests that the screen only rotates when maximize mode is engaged, and will
401 // return to the standard orientation on exiting maximize mode.
402 TEST_F(MaximizeModeControllerTest
, RotationOnlyInMaximizeMode
) {
403 // Rotate on side with lid only open 90 degrees.
404 TriggerBaseAndLidUpdate(gfx::Vector3dF(-9.5f
, 0.0f
, -3.5f
),
405 gfx::Vector3dF(-9.5f
, -3.5f
, 0.0f
));
406 ASSERT_FALSE(IsMaximizeModeStarted());
407 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
409 // Open lid, screen should now rotate to match orientation.
410 TriggerBaseAndLidUpdate(gfx::Vector3dF(-9.5f
, 0.0f
, 3.5f
),
411 gfx::Vector3dF(-9.5f
, -3.5f
, 0.0f
));
412 ASSERT_TRUE(IsMaximizeModeStarted());
413 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
415 // Close lid back to 90, screen should rotate back.
416 TriggerBaseAndLidUpdate(gfx::Vector3dF(-9.5f
, 0.0f
, -3.5f
),
417 gfx::Vector3dF(-9.5f
, -3.5f
, 0.0f
));
418 ASSERT_FALSE(IsMaximizeModeStarted());
419 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
423 TEST_F(MaximizeModeControllerTest
, LaptopTest
) {
424 // Feeds in sample accelerometer data and verifies that there are no
425 // transitions into touchview / maximize mode while shaking the device around
426 // with the hinge at less than 180 degrees. Note the conversion from device
427 // data to accelerometer updates consistent with accelerometer_reader.cc.
428 ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength
% 6);
429 for (size_t i
= 0; i
< kAccelerometerLaptopModeTestDataLength
/ 6; ++i
) {
430 gfx::Vector3dF
base(-kAccelerometerLaptopModeTestData
[i
* 6 + 1],
431 -kAccelerometerLaptopModeTestData
[i
* 6],
432 -kAccelerometerLaptopModeTestData
[i
* 6 + 2]);
433 base
.Scale(kMeanGravity
);
434 gfx::Vector3dF
lid(-kAccelerometerLaptopModeTestData
[i
* 6 + 4],
435 kAccelerometerLaptopModeTestData
[i
* 6 + 3],
436 kAccelerometerLaptopModeTestData
[i
* 6 + 5]);
437 lid
.Scale(kMeanGravity
);
438 TriggerBaseAndLidUpdate(base
, lid
);
439 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
440 // one failure rather than potentially hundreds.
441 ASSERT_FALSE(IsMaximizeModeStarted());
445 TEST_F(MaximizeModeControllerTest
, MaximizeModeTest
) {
446 // Trigger maximize mode by opening to 270 to begin the test in maximize mode.
447 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
448 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
449 ASSERT_TRUE(IsMaximizeModeStarted());
451 // Feeds in sample accelerometer data and verifies that there are no
452 // transitions out of touchview / maximize mode while shaking the device
453 // around. Note the conversion from device data to accelerometer updates
454 // consistent with accelerometer_reader.cc.
455 ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength
% 6);
456 for (size_t i
= 0; i
< kAccelerometerFullyOpenTestDataLength
/ 6; ++i
) {
457 gfx::Vector3dF
base(-kAccelerometerFullyOpenTestData
[i
* 6 + 1],
458 -kAccelerometerFullyOpenTestData
[i
* 6],
459 -kAccelerometerFullyOpenTestData
[i
* 6 + 2]);
460 base
.Scale(kMeanGravity
);
461 gfx::Vector3dF
lid(-kAccelerometerFullyOpenTestData
[i
* 6 + 4],
462 kAccelerometerFullyOpenTestData
[i
* 6 + 3],
463 kAccelerometerFullyOpenTestData
[i
* 6 + 5]);
464 lid
.Scale(kMeanGravity
);
465 TriggerBaseAndLidUpdate(base
, lid
);
466 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
467 // one failure rather than potentially hundreds.
468 ASSERT_TRUE(IsMaximizeModeStarted());
472 // Tests that the display will stick to its current orientation when the
473 // rotation lock has been set.
474 TEST_F(MaximizeModeControllerTest
, RotationLockPreventsRotation
) {
475 // Trigger maximize mode by opening to 270.
476 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
477 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
478 ASSERT_TRUE(IsMaximizeModeStarted());
480 gfx::Vector3dF
gravity(-kMeanGravity
, 0.0f
, 0.0f
);
482 maximize_mode_controller()->SetRotationLocked(true);
484 // Turn past the threshold for rotation.
485 float degrees
= 90.0;
486 gravity
.set_x(-sin(degrees
* kDegreesToRadians
) * kMeanGravity
);
487 gravity
.set_y(-cos(degrees
* kDegreesToRadians
) * kMeanGravity
);
488 TriggerBaseAndLidUpdate(gravity
, gravity
);
489 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
491 maximize_mode_controller()->SetRotationLocked(false);
492 TriggerBaseAndLidUpdate(gravity
, gravity
);
493 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
496 // Tests that when MaximizeModeController turns off MaximizeMode that on the
497 // next accelerometer update the rotation lock is cleared.
498 TEST_F(MaximizeModeControllerTest
, ExitingMaximizeModeClearRotationLock
) {
499 // Trigger maximize mode by opening to 270.
500 OpenLidToAngle(270.0f
);
501 ASSERT_TRUE(IsMaximizeModeStarted());
503 maximize_mode_controller()->SetRotationLocked(true);
505 OpenLidToAngle(90.0f
);
506 EXPECT_FALSE(IsMaximizeModeStarted());
508 // Send an update that would not relaunch MaximizeMode.
509 OpenLidToAngle(90.0f
);
510 EXPECT_FALSE(maximize_mode_controller()->rotation_locked());
513 // The TrayDisplay class that is responsible for adding/updating MessageCenter
514 // notifications is only added to the SystemTray on ChromeOS.
515 // Tests that the screen rotation notifications are suppressed when
516 // triggered by the accelerometer.
517 TEST_F(MaximizeModeControllerTest
, BlockRotationNotifications
) {
518 test::TestSystemTrayDelegate
* tray_delegate
=
519 static_cast<test::TestSystemTrayDelegate
*>(
520 Shell::GetInstance()->system_tray_delegate());
521 tray_delegate
->set_should_show_display_notification(true);
523 message_center::MessageCenter
* message_center
=
524 message_center::MessageCenter::Get();
526 // Make sure notifications are still displayed when
527 // adjusting the screen rotation directly when not in maximize mode
528 ASSERT_FALSE(IsMaximizeModeStarted());
529 ASSERT_NE(gfx::Display::ROTATE_180
, GetInternalDisplayRotation());
530 ASSERT_EQ(0u, message_center
->NotificationCount());
531 ASSERT_FALSE(message_center
->HasPopupNotifications());
532 SetInternalDisplayRotation(gfx::Display::ROTATE_180
);
533 EXPECT_EQ(gfx::Display::ROTATE_180
, GetInternalDisplayRotation());
534 EXPECT_EQ(1u, message_center
->NotificationCount());
535 EXPECT_TRUE(message_center
->HasPopupNotifications());
537 // Reset the screen rotation.
538 SetInternalDisplayRotation(gfx::Display::ROTATE_0
);
539 // Clear all notifications
540 message_center
->RemoveAllNotifications(false);
541 // Trigger maximize mode by opening to 270.
542 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
543 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
544 EXPECT_TRUE(IsMaximizeModeStarted());
545 EXPECT_EQ(0u, message_center
->NotificationCount());
546 EXPECT_FALSE(message_center
->HasPopupNotifications());
548 // Make sure notifications are still displayed when
549 // adjusting the screen rotation directly when in maximize mode
550 ASSERT_NE(gfx::Display::ROTATE_270
, GetInternalDisplayRotation());
551 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
552 maximize_mode_controller()->SetRotationLocked(false);
553 EXPECT_EQ(gfx::Display::ROTATE_270
, GetInternalDisplayRotation());
554 EXPECT_EQ(1u, message_center
->NotificationCount());
555 EXPECT_TRUE(message_center
->HasPopupNotifications());
557 // Clear all notifications
558 message_center
->RemoveAllNotifications(false);
559 EXPECT_EQ(0u, message_center
->NotificationCount());
560 EXPECT_FALSE(message_center
->HasPopupNotifications());
562 // Make sure notifications are blocked when adjusting the screen rotation
563 // via the accelerometer while in maximize mode
564 // Rotate the screen 90 degrees
565 ASSERT_NE(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
566 TriggerBaseAndLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
),
567 gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
568 ASSERT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
569 EXPECT_EQ(0u, message_center
->NotificationCount());
570 EXPECT_FALSE(message_center
->HasPopupNotifications());
573 // Tests that if a user has set a display rotation that it is restored upon
574 // exiting maximize mode.
575 TEST_F(MaximizeModeControllerTest
, ResetUserRotationUponExit
) {
576 DisplayManager
* display_manager
= Shell::GetInstance()->display_manager();
577 display_manager
->SetDisplayRotation(gfx::Display::InternalDisplayId(),
578 gfx::Display::ROTATE_90
);
580 // Trigger maximize mode
581 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
582 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
583 ASSERT_TRUE(IsMaximizeModeStarted());
585 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
),
586 gfx::Vector3dF(0.0f
, kMeanGravity
, 0.0f
));
587 EXPECT_EQ(gfx::Display::ROTATE_180
, GetInternalDisplayRotation());
589 // Exit maximize mode
590 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, -kMeanGravity
),
591 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
592 EXPECT_FALSE(IsMaximizeModeStarted());
593 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());
596 // Tests that if a user sets a display rotation that accelerometer rotation
598 TEST_F(MaximizeModeControllerTest
,
599 NonAccelerometerRotationChangesLockRotation
) {
600 // Trigger maximize mode by opening to 270.
601 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
602 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
603 ASSERT_FALSE(maximize_mode_controller()->rotation_locked());
604 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
605 EXPECT_TRUE(maximize_mode_controller()->rotation_locked());
608 // Tests that if a user changes the display rotation, while rotation is locked,
609 // that the updates are recorded. Upon exiting maximize mode the latest user
610 // rotation should be applied.
611 TEST_F(MaximizeModeControllerTest
, UpdateUserRotationWhileRotationLocked
) {
612 // Trigger maximize mode by opening to 270.
613 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, kMeanGravity
),
614 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
615 SetInternalDisplayRotation(gfx::Display::ROTATE_270
);
616 // User sets rotation to the same rotation that the display was at when
617 // maximize mode was activated.
618 SetInternalDisplayRotation(gfx::Display::ROTATE_0
);
619 // Exit maximize mode
620 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f
, 0.0f
, -kMeanGravity
),
621 gfx::Vector3dF(0.0f
, -kMeanGravity
, 0.0f
));
622 EXPECT_EQ(gfx::Display::ROTATE_0
, GetInternalDisplayRotation());
625 class MaximizeModeControllerSwitchesTest
: public MaximizeModeControllerTest
{
627 MaximizeModeControllerSwitchesTest() {}
628 ~MaximizeModeControllerSwitchesTest() override
{}
630 void SetUp() override
{
631 base::CommandLine::ForCurrentProcess()->AppendSwitch(
632 switches::kAshEnableTouchViewTesting
);
633 MaximizeModeControllerTest::SetUp();
636 DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerSwitchesTest
);
639 // Tests that when the command line switch for testing maximize mode is on, that
640 // accelerometer updates which would normally cause it to exit do not, and that
641 // screen rotations still occur.
642 TEST_F(MaximizeModeControllerSwitchesTest
, IgnoreHingeAngles
) {
643 maximize_mode_controller()->EnableMaximizeModeWindowManager(true);
645 // Would normally trigger an exit from maximize mode.
646 OpenLidToAngle(90.0f
);
647 EXPECT_TRUE(IsMaximizeModeStarted());
649 TriggerBaseAndLidUpdate(gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
),
650 gfx::Vector3dF(-kMeanGravity
, 0.0f
, 0.0f
));
651 EXPECT_EQ(gfx::Display::ROTATE_90
, GetInternalDisplayRotation());