OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ash/wm/maximize_mode/maximize_mode_controller.h" | |
6 | |
7 #include <math.h> | |
8 #include <utility> | |
9 #include <vector> | |
10 | |
11 #include "ash/ash_switches.h" | |
12 #include "ash/display/screen_orientation_controller_chromeos.h" | |
13 #include "ash/shell.h" | |
14 #include "ash/system/tray/system_tray_delegate.h" | |
15 #include "ash/test/ash_test_base.h" | |
16 #include "ash/test/test_system_tray_delegate.h" | |
17 #include "ash/wm/overview/window_selector_controller.h" | |
18 #include "base/command_line.h" | |
19 #include "base/run_loop.h" | |
20 #include "base/test/simple_test_tick_clock.h" | |
21 #include "base/test/user_action_tester.h" | |
22 #include "chromeos/accelerometer/accelerometer_reader.h" | |
23 #include "chromeos/accelerometer/accelerometer_types.h" | |
24 #include "chromeos/dbus/dbus_thread_manager.h" | |
25 #include "chromeos/dbus/fake_power_manager_client.h" | |
26 #include "ui/display/manager/display_manager.h" | |
27 #include "ui/display/screen.h" | |
28 #include "ui/display/test/display_manager_test_api.h" | |
29 #include "ui/events/event_handler.h" | |
30 #include "ui/events/test/event_generator.h" | |
31 #include "ui/gfx/geometry/vector3d_f.h" | |
32 #include "ui/message_center/message_center.h" | |
33 | |
34 #if defined(USE_X11) | |
35 #include "ui/events/test/events_test_utils_x11.h" | |
36 #endif | |
37 | |
38 namespace ash { | |
39 | |
40 namespace { | |
41 | |
42 const float kDegreesToRadians = 3.1415926f / 180.0f; | |
43 const float kMeanGravity = 9.8066f; | |
44 | |
45 const char kTouchViewInitiallyDisabled[] = "Touchview_Initially_Disabled"; | |
46 const char kTouchViewEnabled[] = "Touchview_Enabled"; | |
47 const char kTouchViewDisabled[] = "Touchview_Disabled"; | |
48 | |
49 } // namespace | |
50 | |
51 // Test accelerometer data taken with the lid at less than 180 degrees while | |
52 // shaking the device around. The data is to be interpreted in groups of 6 where | |
53 // each 6 values corresponds to the base accelerometer (-y / g, -x / g, -z / g) | |
54 // followed by the lid accelerometer (-y / g , x / g, z / g). | |
55 extern const float kAccelerometerLaptopModeTestData[]; | |
56 extern const size_t kAccelerometerLaptopModeTestDataLength; | |
57 | |
58 // Test accelerometer data taken with the lid open 360 degrees while | |
59 // shaking the device around. The data is to be interpreted in groups of 6 where | |
60 // each 6 values corresponds to the base accelerometer (-y / g, -x / g, -z / g) | |
61 // followed by the lid accelerometer (-y / g , x / g, z / g). | |
62 extern const float kAccelerometerFullyOpenTestData[]; | |
63 extern const size_t kAccelerometerFullyOpenTestDataLength; | |
64 | |
65 // Test accelerometer data taken with the lid open 360 degrees while the device | |
66 // hinge was nearly vertical, while shaking the device around. The data is to be | |
67 // interpreted in groups of 6 where each 6 values corresponds to the X, Y, and Z | |
68 // readings from the base and lid accelerometers in this order. | |
69 extern const float kAccelerometerVerticalHingeTestData[]; | |
70 extern const size_t kAccelerometerVerticalHingeTestDataLength; | |
71 extern const float kAccelerometerVerticalHingeUnstableAnglesTestData[]; | |
72 extern const size_t kAccelerometerVerticalHingeUnstableAnglesTestDataLength; | |
73 | |
74 class MaximizeModeControllerTest : public test::AshTestBase { | |
75 public: | |
76 MaximizeModeControllerTest() {} | |
77 ~MaximizeModeControllerTest() override {} | |
78 | |
79 void SetUp() override { | |
80 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
81 switches::kAshEnableTouchView); | |
82 test::AshTestBase::SetUp(); | |
83 chromeos::AccelerometerReader::GetInstance()->RemoveObserver( | |
84 maximize_mode_controller()); | |
85 | |
86 // Set the first display to be the internal display for the accelerometer | |
87 // screen rotation tests. | |
88 display::test::DisplayManagerTestApi(Shell::Get()->display_manager()) | |
89 .SetFirstDisplayAsInternalDisplay(); | |
90 } | |
91 | |
92 void TearDown() override { | |
93 chromeos::AccelerometerReader::GetInstance()->AddObserver( | |
94 maximize_mode_controller()); | |
95 test::AshTestBase::TearDown(); | |
96 } | |
97 | |
98 MaximizeModeController* maximize_mode_controller() { | |
99 return Shell::Get()->maximize_mode_controller(); | |
100 } | |
101 | |
102 void TriggerLidUpdate(const gfx::Vector3dF& lid) { | |
103 scoped_refptr<chromeos::AccelerometerUpdate> update( | |
104 new chromeos::AccelerometerUpdate()); | |
105 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), | |
106 lid.z()); | |
107 maximize_mode_controller()->OnAccelerometerUpdated(update); | |
108 } | |
109 | |
110 void TriggerBaseAndLidUpdate(const gfx::Vector3dF& base, | |
111 const gfx::Vector3dF& lid) { | |
112 scoped_refptr<chromeos::AccelerometerUpdate> update( | |
113 new chromeos::AccelerometerUpdate()); | |
114 update->Set(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, base.x(), | |
115 base.y(), base.z()); | |
116 update->Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, lid.x(), lid.y(), | |
117 lid.z()); | |
118 maximize_mode_controller()->OnAccelerometerUpdated(update); | |
119 } | |
120 | |
121 bool IsMaximizeModeStarted() { | |
122 return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled(); | |
123 } | |
124 | |
125 // Attaches a SimpleTestTickClock to the MaximizeModeController with a non | |
126 // null value initial value. | |
127 void AttachTickClockForTest() { | |
128 std::unique_ptr<base::TickClock> tick_clock( | |
129 test_tick_clock_ = new base::SimpleTestTickClock()); | |
130 test_tick_clock_->Advance(base::TimeDelta::FromSeconds(1)); | |
131 maximize_mode_controller()->SetTickClockForTest(std::move(tick_clock)); | |
132 } | |
133 | |
134 void AdvanceTickClock(const base::TimeDelta& delta) { | |
135 DCHECK(test_tick_clock_); | |
136 test_tick_clock_->Advance(delta); | |
137 } | |
138 | |
139 void OpenLidToAngle(float degrees) { | |
140 DCHECK(degrees >= 0.0f); | |
141 DCHECK(degrees <= 360.0f); | |
142 | |
143 float radians = degrees * kDegreesToRadians; | |
144 gfx::Vector3dF base_vector(0.0f, -kMeanGravity, 0.0f); | |
145 gfx::Vector3dF lid_vector(0.0f, kMeanGravity * cos(radians), | |
146 kMeanGravity * sin(radians)); | |
147 TriggerBaseAndLidUpdate(base_vector, lid_vector); | |
148 } | |
149 | |
150 void HoldDeviceVertical() { | |
151 gfx::Vector3dF base_vector(9.8f, 0.0f, 0.0f); | |
152 gfx::Vector3dF lid_vector(9.8f, 0.0f, 0.0f); | |
153 TriggerBaseAndLidUpdate(base_vector, lid_vector); | |
154 } | |
155 | |
156 void OpenLid() { | |
157 maximize_mode_controller()->LidEventReceived( | |
158 chromeos::PowerManagerClient::LidState::OPEN, | |
159 maximize_mode_controller()->tick_clock_->NowTicks()); | |
160 } | |
161 | |
162 void CloseLid() { | |
163 maximize_mode_controller()->LidEventReceived( | |
164 chromeos::PowerManagerClient::LidState::CLOSED, | |
165 maximize_mode_controller()->tick_clock_->NowTicks()); | |
166 } | |
167 | |
168 bool WasLidOpenedRecently() { | |
169 return maximize_mode_controller()->WasLidOpenedRecently(); | |
170 } | |
171 | |
172 void SetTabletMode(bool on) { | |
173 maximize_mode_controller()->TabletModeEventReceived( | |
174 on ? chromeos::PowerManagerClient::TabletMode::ON | |
175 : chromeos::PowerManagerClient::TabletMode::OFF, | |
176 maximize_mode_controller()->tick_clock_->NowTicks()); | |
177 } | |
178 | |
179 bool AreEventsBlocked() { | |
180 return !!maximize_mode_controller()->event_blocker_.get(); | |
181 } | |
182 | |
183 MaximizeModeController::ForceTabletMode forced_tablet_mode() { | |
184 return maximize_mode_controller()->force_tablet_mode_; | |
185 } | |
186 | |
187 base::UserActionTester* user_action_tester() { return &user_action_tester_; } | |
188 | |
189 private: | |
190 base::SimpleTestTickClock* test_tick_clock_; | |
191 | |
192 // Tracks user action counts. | |
193 base::UserActionTester user_action_tester_; | |
194 | |
195 DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerTest); | |
196 }; | |
197 | |
198 // Verify TouchView enabled/disabled user action metrics are recorded. | |
199 TEST_F(MaximizeModeControllerTest, VerifyTouchViewEnabledDisabledCounts) { | |
200 ASSERT_EQ(1, | |
201 user_action_tester()->GetActionCount(kTouchViewInitiallyDisabled)); | |
202 ASSERT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled)); | |
203 ASSERT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled)); | |
204 | |
205 user_action_tester()->ResetCounts(); | |
206 maximize_mode_controller()->EnableMaximizeModeWindowManager(true); | |
207 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewEnabled)); | |
208 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled)); | |
209 maximize_mode_controller()->EnableMaximizeModeWindowManager(true); | |
210 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewEnabled)); | |
211 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled)); | |
212 | |
213 user_action_tester()->ResetCounts(); | |
214 maximize_mode_controller()->EnableMaximizeModeWindowManager(false); | |
215 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled)); | |
216 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewDisabled)); | |
217 maximize_mode_controller()->EnableMaximizeModeWindowManager(false); | |
218 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled)); | |
219 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewDisabled)); | |
220 } | |
221 | |
222 // Verify that closing the lid will exit maximize mode. | |
223 TEST_F(MaximizeModeControllerTest, CloseLidWhileInMaximizeMode) { | |
224 OpenLidToAngle(315.0f); | |
225 ASSERT_TRUE(IsMaximizeModeStarted()); | |
226 | |
227 CloseLid(); | |
228 EXPECT_FALSE(IsMaximizeModeStarted()); | |
229 } | |
230 | |
231 // Verify that maximize mode will not be entered when the lid is closed. | |
232 TEST_F(MaximizeModeControllerTest, HingeAnglesWithLidClosed) { | |
233 AttachTickClockForTest(); | |
234 | |
235 CloseLid(); | |
236 | |
237 OpenLidToAngle(270.0f); | |
238 EXPECT_FALSE(IsMaximizeModeStarted()); | |
239 | |
240 OpenLidToAngle(315.0f); | |
241 EXPECT_FALSE(IsMaximizeModeStarted()); | |
242 | |
243 OpenLidToAngle(355.0f); | |
244 EXPECT_FALSE(IsMaximizeModeStarted()); | |
245 } | |
246 | |
247 // Verify the maximize mode state for unstable hinge angles when the lid was | |
248 // recently open. | |
249 TEST_F(MaximizeModeControllerTest, UnstableHingeAnglesWhenLidRecentlyOpened) { | |
250 AttachTickClockForTest(); | |
251 | |
252 OpenLid(); | |
253 ASSERT_TRUE(WasLidOpenedRecently()); | |
254 | |
255 OpenLidToAngle(5.0f); | |
256 EXPECT_FALSE(IsMaximizeModeStarted()); | |
257 | |
258 OpenLidToAngle(355.0f); | |
259 EXPECT_FALSE(IsMaximizeModeStarted()); | |
260 | |
261 // This is a stable reading and should clear the last lid opened time. | |
262 OpenLidToAngle(45.0f); | |
263 EXPECT_FALSE(IsMaximizeModeStarted()); | |
264 EXPECT_FALSE(WasLidOpenedRecently()); | |
265 | |
266 OpenLidToAngle(355.0f); | |
267 EXPECT_TRUE(IsMaximizeModeStarted()); | |
268 } | |
269 | |
270 // Verify the WasLidOpenedRecently signal with respect to time. | |
271 TEST_F(MaximizeModeControllerTest, WasLidOpenedRecentlyOverTime) { | |
272 AttachTickClockForTest(); | |
273 | |
274 // No lid open time initially. | |
275 ASSERT_FALSE(WasLidOpenedRecently()); | |
276 | |
277 CloseLid(); | |
278 EXPECT_FALSE(WasLidOpenedRecently()); | |
279 | |
280 OpenLid(); | |
281 EXPECT_TRUE(WasLidOpenedRecently()); | |
282 | |
283 // 1 second after lid open. | |
284 AdvanceTickClock(base::TimeDelta::FromSeconds(1)); | |
285 EXPECT_TRUE(WasLidOpenedRecently()); | |
286 | |
287 // 3 seconds after lid open. | |
288 AdvanceTickClock(base::TimeDelta::FromSeconds(2)); | |
289 EXPECT_FALSE(WasLidOpenedRecently()); | |
290 } | |
291 | |
292 TEST_F(MaximizeModeControllerTest, TabletModeTransition) { | |
293 OpenLidToAngle(90.0f); | |
294 EXPECT_FALSE(IsMaximizeModeStarted()); | |
295 | |
296 // Unstable reading. This should not trigger maximize mode. | |
297 HoldDeviceVertical(); | |
298 EXPECT_FALSE(IsMaximizeModeStarted()); | |
299 | |
300 // When tablet mode switch is on it should force maximize mode even if the | |
301 // reading is not stable. | |
302 SetTabletMode(true); | |
303 EXPECT_TRUE(IsMaximizeModeStarted()); | |
304 | |
305 // After tablet mode switch is off it should stay in maximize mode if the | |
306 // reading is not stable. | |
307 SetTabletMode(false); | |
308 EXPECT_TRUE(IsMaximizeModeStarted()); | |
309 | |
310 // Should leave maximize mode when the lid angle is small enough. | |
311 OpenLidToAngle(90.0f); | |
312 EXPECT_FALSE(IsMaximizeModeStarted()); | |
313 | |
314 OpenLidToAngle(300.0f); | |
315 EXPECT_TRUE(IsMaximizeModeStarted()); | |
316 } | |
317 | |
318 // When there is no keyboard accelerometer available maximize mode should solely | |
319 // rely on the tablet mode switch. | |
320 TEST_F(MaximizeModeControllerTest, | |
321 TabletModeTransitionNoKeyboardAccelerometer) { | |
322 ASSERT_FALSE(IsMaximizeModeStarted()); | |
323 TriggerLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity)); | |
324 ASSERT_FALSE(IsMaximizeModeStarted()); | |
325 | |
326 SetTabletMode(true); | |
327 EXPECT_TRUE(IsMaximizeModeStarted()); | |
328 | |
329 // Single sensor reading should not change mode. | |
330 TriggerLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity)); | |
331 EXPECT_TRUE(IsMaximizeModeStarted()); | |
332 | |
333 // With a single sensor we should exit immediately on the tablet mode switch | |
334 // rather than waiting for stabilized accelerometer readings. | |
335 SetTabletMode(false); | |
336 EXPECT_FALSE(IsMaximizeModeStarted()); | |
337 } | |
338 | |
339 // Verify the maximize mode enter/exit thresholds for stable angles. | |
340 TEST_F(MaximizeModeControllerTest, StableHingeAnglesWithLidOpened) { | |
341 ASSERT_FALSE(IsMaximizeModeStarted()); | |
342 ASSERT_FALSE(WasLidOpenedRecently()); | |
343 | |
344 OpenLidToAngle(180.0f); | |
345 EXPECT_FALSE(IsMaximizeModeStarted()); | |
346 | |
347 OpenLidToAngle(315.0f); | |
348 EXPECT_TRUE(IsMaximizeModeStarted()); | |
349 | |
350 OpenLidToAngle(180.0f); | |
351 EXPECT_TRUE(IsMaximizeModeStarted()); | |
352 | |
353 OpenLidToAngle(45.0f); | |
354 EXPECT_FALSE(IsMaximizeModeStarted()); | |
355 | |
356 OpenLidToAngle(270.0f); | |
357 EXPECT_TRUE(IsMaximizeModeStarted()); | |
358 | |
359 OpenLidToAngle(90.0f); | |
360 EXPECT_FALSE(IsMaximizeModeStarted()); | |
361 } | |
362 | |
363 // Verify the maximize mode state for unstable hinge angles when the lid is open | |
364 // but not recently. | |
365 TEST_F(MaximizeModeControllerTest, UnstableHingeAnglesWithLidOpened) { | |
366 AttachTickClockForTest(); | |
367 | |
368 ASSERT_FALSE(WasLidOpenedRecently()); | |
369 ASSERT_FALSE(IsMaximizeModeStarted()); | |
370 | |
371 OpenLidToAngle(5.0f); | |
372 EXPECT_FALSE(IsMaximizeModeStarted()); | |
373 | |
374 OpenLidToAngle(355.0f); | |
375 EXPECT_TRUE(IsMaximizeModeStarted()); | |
376 | |
377 OpenLidToAngle(5.0f); | |
378 EXPECT_TRUE(IsMaximizeModeStarted()); | |
379 } | |
380 | |
381 // Tests that when the hinge is nearly vertically aligned, the current state | |
382 // persists as the computed angle is highly inaccurate in this orientation. | |
383 TEST_F(MaximizeModeControllerTest, HingeAligned) { | |
384 // Laptop in normal orientation lid open 90 degrees. | |
385 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity), | |
386 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f)); | |
387 EXPECT_FALSE(IsMaximizeModeStarted()); | |
388 | |
389 // Completely vertical. | |
390 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f), | |
391 gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f)); | |
392 EXPECT_FALSE(IsMaximizeModeStarted()); | |
393 | |
394 // Close to vertical but with hinge appearing to be open 270 degrees. | |
395 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f), | |
396 gfx::Vector3dF(kMeanGravity, 0.1f, 0.0f)); | |
397 EXPECT_FALSE(IsMaximizeModeStarted()); | |
398 | |
399 // Flat and open 270 degrees should start maximize mode. | |
400 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity), | |
401 gfx::Vector3dF(0.0f, kMeanGravity, 0.0f)); | |
402 EXPECT_TRUE(IsMaximizeModeStarted()); | |
403 | |
404 // Normal 90 degree orientation but near vertical should stay in maximize | |
405 // mode. | |
406 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f), | |
407 gfx::Vector3dF(kMeanGravity, -0.1f, 0.0f)); | |
408 EXPECT_TRUE(IsMaximizeModeStarted()); | |
409 } | |
410 | |
411 TEST_F(MaximizeModeControllerTest, LaptopTest) { | |
412 // Feeds in sample accelerometer data and verifies that there are no | |
413 // transitions into touchview / maximize mode while shaking the device around | |
414 // with the hinge at less than 180 degrees. Note the conversion from device | |
415 // data to accelerometer updates consistent with accelerometer_reader.cc. | |
416 ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength % 6); | |
417 for (size_t i = 0; i < kAccelerometerLaptopModeTestDataLength / 6; ++i) { | |
418 gfx::Vector3dF base(-kAccelerometerLaptopModeTestData[i * 6 + 1], | |
419 -kAccelerometerLaptopModeTestData[i * 6], | |
420 -kAccelerometerLaptopModeTestData[i * 6 + 2]); | |
421 base.Scale(kMeanGravity); | |
422 gfx::Vector3dF lid(-kAccelerometerLaptopModeTestData[i * 6 + 4], | |
423 kAccelerometerLaptopModeTestData[i * 6 + 3], | |
424 kAccelerometerLaptopModeTestData[i * 6 + 5]); | |
425 lid.Scale(kMeanGravity); | |
426 TriggerBaseAndLidUpdate(base, lid); | |
427 // There are a lot of samples, so ASSERT rather than EXPECT to only generate | |
428 // one failure rather than potentially hundreds. | |
429 ASSERT_FALSE(IsMaximizeModeStarted()); | |
430 } | |
431 } | |
432 | |
433 TEST_F(MaximizeModeControllerTest, MaximizeModeTest) { | |
434 // Trigger maximize mode by opening to 270 to begin the test in maximize mode. | |
435 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity), | |
436 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f)); | |
437 ASSERT_TRUE(IsMaximizeModeStarted()); | |
438 | |
439 // Feeds in sample accelerometer data and verifies that there are no | |
440 // transitions out of touchview / maximize mode while shaking the device | |
441 // around. Note the conversion from device data to accelerometer updates | |
442 // consistent with accelerometer_reader.cc. | |
443 ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength % 6); | |
444 for (size_t i = 0; i < kAccelerometerFullyOpenTestDataLength / 6; ++i) { | |
445 gfx::Vector3dF base(-kAccelerometerFullyOpenTestData[i * 6 + 1], | |
446 -kAccelerometerFullyOpenTestData[i * 6], | |
447 -kAccelerometerFullyOpenTestData[i * 6 + 2]); | |
448 base.Scale(kMeanGravity); | |
449 gfx::Vector3dF lid(-kAccelerometerFullyOpenTestData[i * 6 + 4], | |
450 kAccelerometerFullyOpenTestData[i * 6 + 3], | |
451 kAccelerometerFullyOpenTestData[i * 6 + 5]); | |
452 lid.Scale(kMeanGravity); | |
453 TriggerBaseAndLidUpdate(base, lid); | |
454 // There are a lot of samples, so ASSERT rather than EXPECT to only generate | |
455 // one failure rather than potentially hundreds. | |
456 ASSERT_TRUE(IsMaximizeModeStarted()); | |
457 } | |
458 } | |
459 | |
460 TEST_F(MaximizeModeControllerTest, VerticalHingeTest) { | |
461 // Feeds in sample accelerometer data and verifies that there are no | |
462 // transitions out of touchview / maximize mode while shaking the device | |
463 // around, while the hinge is nearly vertical. The data was captured from | |
464 // maxmimize_mode_controller.cc and does not require conversion. | |
465 ASSERT_EQ(0u, kAccelerometerVerticalHingeTestDataLength % 6); | |
466 for (size_t i = 0; i < kAccelerometerVerticalHingeTestDataLength / 6; ++i) { | |
467 gfx::Vector3dF base(kAccelerometerVerticalHingeTestData[i * 6], | |
468 kAccelerometerVerticalHingeTestData[i * 6 + 1], | |
469 kAccelerometerVerticalHingeTestData[i * 6 + 2]); | |
470 gfx::Vector3dF lid(kAccelerometerVerticalHingeTestData[i * 6 + 3], | |
471 kAccelerometerVerticalHingeTestData[i * 6 + 4], | |
472 kAccelerometerVerticalHingeTestData[i * 6 + 5]); | |
473 TriggerBaseAndLidUpdate(base, lid); | |
474 // There are a lot of samples, so ASSERT rather than EXPECT to only generate | |
475 // one failure rather than potentially hundreds. | |
476 ASSERT_TRUE(IsMaximizeModeStarted()); | |
477 } | |
478 } | |
479 | |
480 // Test if this case does not crash. See http://crbug.com/462806 | |
481 TEST_F(MaximizeModeControllerTest, DisplayDisconnectionDuringOverview) { | |
482 UpdateDisplay("800x600,800x600"); | |
483 std::unique_ptr<aura::Window> w1( | |
484 CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 100, 100))); | |
485 std::unique_ptr<aura::Window> w2( | |
486 CreateTestWindowInShellWithBounds(gfx::Rect(800, 0, 100, 100))); | |
487 ASSERT_NE(w1->GetRootWindow(), w2->GetRootWindow()); | |
488 | |
489 maximize_mode_controller()->EnableMaximizeModeWindowManager(true); | |
490 EXPECT_TRUE(Shell::Get()->window_selector_controller()->ToggleOverview()); | |
491 | |
492 UpdateDisplay("800x600"); | |
493 EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting()); | |
494 EXPECT_EQ(w1->GetRootWindow(), w2->GetRootWindow()); | |
495 } | |
496 | |
497 // Test that the disabling of the internal display exits maximize mode, and that | |
498 // while disabled we do not re-enter maximize mode. | |
499 TEST_F(MaximizeModeControllerTest, NoMaximizeModeWithDisabledInternalDisplay) { | |
500 UpdateDisplay("200x200, 200x200"); | |
501 const int64_t internal_display_id = | |
502 display::test::DisplayManagerTestApi(display_manager()) | |
503 .SetFirstDisplayAsInternalDisplay(); | |
504 ASSERT_FALSE(IsMaximizeModeStarted()); | |
505 | |
506 OpenLidToAngle(270.0f); | |
507 EXPECT_TRUE(IsMaximizeModeStarted()); | |
508 EXPECT_TRUE(AreEventsBlocked()); | |
509 | |
510 // Deactivate internal display to simulate Docked Mode. | |
511 std::vector<display::ManagedDisplayInfo> secondary_only; | |
512 secondary_only.push_back(display_manager()->GetDisplayInfo( | |
513 display_manager()->GetDisplayAt(1).id())); | |
514 display_manager()->OnNativeDisplaysChanged(secondary_only); | |
515 ASSERT_FALSE(display_manager()->IsActiveDisplayId(internal_display_id)); | |
516 EXPECT_FALSE(IsMaximizeModeStarted()); | |
517 EXPECT_FALSE(AreEventsBlocked()); | |
518 | |
519 OpenLidToAngle(270.0f); | |
520 EXPECT_FALSE(IsMaximizeModeStarted()); | |
521 EXPECT_FALSE(AreEventsBlocked()); | |
522 | |
523 // Tablet mode signal should also be ignored. | |
524 SetTabletMode(true); | |
525 EXPECT_FALSE(IsMaximizeModeStarted()); | |
526 EXPECT_FALSE(AreEventsBlocked()); | |
527 } | |
528 | |
529 // Tests that is a tablet mode signal is received while docked, that maximize | |
530 // mode is enabled upon exiting docked mode. | |
531 TEST_F(MaximizeModeControllerTest, MaximizeModeAfterExitingDockedMode) { | |
532 UpdateDisplay("200x200, 200x200"); | |
533 const int64_t internal_display_id = | |
534 display::test::DisplayManagerTestApi(display_manager()) | |
535 .SetFirstDisplayAsInternalDisplay(); | |
536 ASSERT_FALSE(IsMaximizeModeStarted()); | |
537 | |
538 // Deactivate internal display to simulate Docked Mode. | |
539 std::vector<display::ManagedDisplayInfo> all_displays; | |
540 all_displays.push_back(display_manager()->GetDisplayInfo( | |
541 display_manager()->GetDisplayAt(0).id())); | |
542 std::vector<display::ManagedDisplayInfo> secondary_only; | |
543 display::ManagedDisplayInfo secondary_display = | |
544 display_manager()->GetDisplayInfo( | |
545 display_manager()->GetDisplayAt(1).id()); | |
546 all_displays.push_back(secondary_display); | |
547 secondary_only.push_back(secondary_display); | |
548 display_manager()->OnNativeDisplaysChanged(secondary_only); | |
549 ASSERT_FALSE(display_manager()->IsActiveDisplayId(internal_display_id)); | |
550 | |
551 // Tablet mode signal should also be ignored. | |
552 SetTabletMode(true); | |
553 EXPECT_FALSE(IsMaximizeModeStarted()); | |
554 EXPECT_FALSE(AreEventsBlocked()); | |
555 | |
556 // Exiting docked state | |
557 display_manager()->OnNativeDisplaysChanged(all_displays); | |
558 display::test::DisplayManagerTestApi(display_manager()) | |
559 .SetFirstDisplayAsInternalDisplay(); | |
560 EXPECT_TRUE(IsMaximizeModeStarted()); | |
561 } | |
562 | |
563 // Verify that the device won't exit touchview / maximize mode for unstable | |
564 // angles when hinge is nearly vertical | |
565 TEST_F(MaximizeModeControllerTest, VerticalHingeUnstableAnglesTest) { | |
566 // Trigger maximize mode by opening to 270 to begin the test in maximize mode. | |
567 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity), | |
568 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f)); | |
569 ASSERT_TRUE(IsMaximizeModeStarted()); | |
570 | |
571 // Feeds in sample accelerometer data and verifies that there are no | |
572 // transitions out of touchview / maximize mode while shaking the device | |
573 // around, while the hinge is nearly vertical. The data was captured | |
574 // from maxmimize_mode_controller.cc and does not require conversion. | |
575 ASSERT_EQ(0u, kAccelerometerVerticalHingeUnstableAnglesTestDataLength % 6); | |
576 for (size_t i = 0; | |
577 i < kAccelerometerVerticalHingeUnstableAnglesTestDataLength / 6; ++i) { | |
578 gfx::Vector3dF base( | |
579 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6], | |
580 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 1], | |
581 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 2]); | |
582 gfx::Vector3dF lid( | |
583 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 3], | |
584 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 4], | |
585 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 5]); | |
586 TriggerBaseAndLidUpdate(base, lid); | |
587 // There are a lot of samples, so ASSERT rather than EXPECT to only generate | |
588 // one failure rather than potentially hundreds. | |
589 ASSERT_TRUE(IsMaximizeModeStarted()); | |
590 } | |
591 } | |
592 | |
593 // Tests that when a MaximizeModeController is created that cached tablet mode | |
594 // state will trigger a mode update. | |
595 TEST_F(MaximizeModeControllerTest, InitializedWhileTabletModeSwitchOn) { | |
596 base::RunLoop().RunUntilIdle(); | |
597 // FakePowerManagerClient is always installed for tests | |
598 chromeos::FakePowerManagerClient* power_manager_client = | |
599 static_cast<chromeos::FakePowerManagerClient*>( | |
600 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()); | |
601 power_manager_client->set_tablet_mode( | |
602 chromeos::PowerManagerClient::TabletMode::ON); | |
603 MaximizeModeController controller; | |
604 EXPECT_FALSE(controller.IsMaximizeModeWindowManagerEnabled()); | |
605 // PowerManagerClient callback is a posted task. | |
606 base::RunLoop().RunUntilIdle(); | |
607 EXPECT_TRUE(controller.IsMaximizeModeWindowManagerEnabled()); | |
608 } | |
609 | |
610 // Verify when the force clamshell mode flag is turned on, opening the lid past | |
611 // 180 degrees or setting tablet mode to true will no turn on maximize mode. | |
612 TEST_F(MaximizeModeControllerTest, ForceClamshellModeTest) { | |
613 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
614 switches::kAshForceTabletMode, switches::kAshForceTabletModeClamshell); | |
615 maximize_mode_controller()->OnShellInitialized(); | |
616 EXPECT_EQ(MaximizeModeController::ForceTabletMode::CLAMSHELL, | |
617 forced_tablet_mode()); | |
618 EXPECT_FALSE(IsMaximizeModeStarted()); | |
619 | |
620 OpenLidToAngle(300.0f); | |
621 EXPECT_FALSE(IsMaximizeModeStarted()); | |
622 EXPECT_FALSE(AreEventsBlocked()); | |
623 | |
624 SetTabletMode(true); | |
625 EXPECT_FALSE(IsMaximizeModeStarted()); | |
626 EXPECT_FALSE(AreEventsBlocked()); | |
627 } | |
628 | |
629 // Verify when the force touch view mode flag is turned on, maximize mode is on | |
630 // intially, and opening the lid to less than 180 degress or setting tablet mode | |
631 // to off will not turn off maximize mode. | |
632 TEST_F(MaximizeModeControllerTest, ForceTouchViewModeTest) { | |
633 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
634 switches::kAshForceTabletMode, switches::kAshForceTabletModeTouchView); | |
635 maximize_mode_controller()->OnShellInitialized(); | |
636 EXPECT_EQ(MaximizeModeController::ForceTabletMode::TOUCHVIEW, | |
637 forced_tablet_mode()); | |
638 EXPECT_TRUE(IsMaximizeModeStarted()); | |
639 EXPECT_TRUE(AreEventsBlocked()); | |
640 | |
641 OpenLidToAngle(30.0f); | |
642 EXPECT_TRUE(IsMaximizeModeStarted()); | |
643 EXPECT_TRUE(AreEventsBlocked()); | |
644 | |
645 SetTabletMode(false); | |
646 EXPECT_TRUE(IsMaximizeModeStarted()); | |
647 EXPECT_TRUE(AreEventsBlocked()); | |
648 } | |
649 | |
650 TEST_F(MaximizeModeControllerTest, RestoreAfterExit) { | |
651 UpdateDisplay("1000x600"); | |
652 std::unique_ptr<aura::Window> w1( | |
653 CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 900, 300))); | |
654 maximize_mode_controller()->EnableMaximizeModeWindowManager(true); | |
655 Shell::Get()->screen_orientation_controller()->SetLockToRotation( | |
656 display::Display::ROTATE_90); | |
657 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); | |
658 EXPECT_EQ(display::Display::ROTATE_90, display.rotation()); | |
659 EXPECT_LT(display.size().width(), display.size().height()); | |
660 maximize_mode_controller()->EnableMaximizeModeWindowManager(false); | |
661 display = display::Screen::GetScreen()->GetPrimaryDisplay(); | |
662 // Sanity checks. | |
663 EXPECT_EQ(display::Display::ROTATE_0, display.rotation()); | |
664 EXPECT_GT(display.size().width(), display.size().height()); | |
665 | |
666 // The bounds should be restored to the original bounds, and | |
667 // should not be clamped by the portrait display in touch view. | |
668 EXPECT_EQ(gfx::Rect(10, 10, 900, 300), w1->bounds()); | |
669 } | |
670 | |
671 } // namespace ash | |
OLD | NEW |