Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: ash/wm/tablet_mode/tablet_mode_controller_unittest.cc

Issue 2909763002: Revert of Rename MaximizeMode to TabletMode (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/tablet_mode/tablet_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 TabletModeControllerTest : public test::AshTestBase {
75 public:
76 TabletModeControllerTest() {}
77 ~TabletModeControllerTest() override {}
78
79 void SetUp() override {
80 base::CommandLine::ForCurrentProcess()->AppendSwitch(
81 switches::kAshEnableTouchView);
82 test::AshTestBase::SetUp();
83 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(
84 tablet_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 tablet_mode_controller());
95 test::AshTestBase::TearDown();
96 }
97
98 TabletModeController* tablet_mode_controller() {
99 return Shell::Get()->tablet_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 tablet_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 tablet_mode_controller()->OnAccelerometerUpdated(update);
119 }
120
121 bool IsTabletModeStarted() {
122 return tablet_mode_controller()->IsTabletModeWindowManagerEnabled();
123 }
124
125 // Attaches a SimpleTestTickClock to the TabletModeController 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 tablet_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 tablet_mode_controller()->LidEventReceived(
158 chromeos::PowerManagerClient::LidState::OPEN,
159 tablet_mode_controller()->tick_clock_->NowTicks());
160 }
161
162 void CloseLid() {
163 tablet_mode_controller()->LidEventReceived(
164 chromeos::PowerManagerClient::LidState::CLOSED,
165 tablet_mode_controller()->tick_clock_->NowTicks());
166 }
167
168 bool WasLidOpenedRecently() {
169 return tablet_mode_controller()->WasLidOpenedRecently();
170 }
171
172 void SetTabletMode(bool on) {
173 tablet_mode_controller()->TabletModeEventReceived(
174 on ? chromeos::PowerManagerClient::TabletMode::ON
175 : chromeos::PowerManagerClient::TabletMode::OFF,
176 tablet_mode_controller()->tick_clock_->NowTicks());
177 }
178
179 bool AreEventsBlocked() {
180 return !!tablet_mode_controller()->event_blocker_.get();
181 }
182
183 TabletModeController::ForceTabletMode forced_tablet_mode() {
184 return tablet_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(TabletModeControllerTest);
196 };
197
198 // Verify TouchView enabled/disabled user action metrics are recorded.
199 TEST_F(TabletModeControllerTest, 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 tablet_mode_controller()->EnableTabletModeWindowManager(true);
207 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewEnabled));
208 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewDisabled));
209 tablet_mode_controller()->EnableTabletModeWindowManager(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 tablet_mode_controller()->EnableTabletModeWindowManager(false);
215 EXPECT_EQ(0, user_action_tester()->GetActionCount(kTouchViewEnabled));
216 EXPECT_EQ(1, user_action_tester()->GetActionCount(kTouchViewDisabled));
217 tablet_mode_controller()->EnableTabletModeWindowManager(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 tablet mode.
223 TEST_F(TabletModeControllerTest, CloseLidWhileInTabletMode) {
224 OpenLidToAngle(315.0f);
225 ASSERT_TRUE(IsTabletModeStarted());
226
227 CloseLid();
228 EXPECT_FALSE(IsTabletModeStarted());
229 }
230
231 // Verify that tablet mode will not be entered when the lid is closed.
232 TEST_F(TabletModeControllerTest, HingeAnglesWithLidClosed) {
233 AttachTickClockForTest();
234
235 CloseLid();
236
237 OpenLidToAngle(270.0f);
238 EXPECT_FALSE(IsTabletModeStarted());
239
240 OpenLidToAngle(315.0f);
241 EXPECT_FALSE(IsTabletModeStarted());
242
243 OpenLidToAngle(355.0f);
244 EXPECT_FALSE(IsTabletModeStarted());
245 }
246
247 // Verify the tablet mode state for unstable hinge angles when the lid was
248 // recently open.
249 TEST_F(TabletModeControllerTest, UnstableHingeAnglesWhenLidRecentlyOpened) {
250 AttachTickClockForTest();
251
252 OpenLid();
253 ASSERT_TRUE(WasLidOpenedRecently());
254
255 OpenLidToAngle(5.0f);
256 EXPECT_FALSE(IsTabletModeStarted());
257
258 OpenLidToAngle(355.0f);
259 EXPECT_FALSE(IsTabletModeStarted());
260
261 // This is a stable reading and should clear the last lid opened time.
262 OpenLidToAngle(45.0f);
263 EXPECT_FALSE(IsTabletModeStarted());
264 EXPECT_FALSE(WasLidOpenedRecently());
265
266 OpenLidToAngle(355.0f);
267 EXPECT_TRUE(IsTabletModeStarted());
268 }
269
270 // Verify the WasLidOpenedRecently signal with respect to time.
271 TEST_F(TabletModeControllerTest, 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(TabletModeControllerTest, TabletModeTransition) {
293 OpenLidToAngle(90.0f);
294 EXPECT_FALSE(IsTabletModeStarted());
295
296 // Unstable reading. This should not trigger tablet mode.
297 HoldDeviceVertical();
298 EXPECT_FALSE(IsTabletModeStarted());
299
300 // When tablet mode switch is on it should force tablet mode even if the
301 // reading is not stable.
302 SetTabletMode(true);
303 EXPECT_TRUE(IsTabletModeStarted());
304
305 // After tablet mode switch is off it should stay in tablet mode if the
306 // reading is not stable.
307 SetTabletMode(false);
308 EXPECT_TRUE(IsTabletModeStarted());
309
310 // Should leave tablet mode when the lid angle is small enough.
311 OpenLidToAngle(90.0f);
312 EXPECT_FALSE(IsTabletModeStarted());
313
314 OpenLidToAngle(300.0f);
315 EXPECT_TRUE(IsTabletModeStarted());
316 }
317
318 // When there is no keyboard accelerometer available tablet mode should solely
319 // rely on the tablet mode switch.
320 TEST_F(TabletModeControllerTest, TabletModeTransitionNoKeyboardAccelerometer) {
321 ASSERT_FALSE(IsTabletModeStarted());
322 TriggerLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity));
323 ASSERT_FALSE(IsTabletModeStarted());
324
325 SetTabletMode(true);
326 EXPECT_TRUE(IsTabletModeStarted());
327
328 // Single sensor reading should not change mode.
329 TriggerLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity));
330 EXPECT_TRUE(IsTabletModeStarted());
331
332 // With a single sensor we should exit immediately on the tablet mode switch
333 // rather than waiting for stabilized accelerometer readings.
334 SetTabletMode(false);
335 EXPECT_FALSE(IsTabletModeStarted());
336 }
337
338 // Verify the tablet mode enter/exit thresholds for stable angles.
339 TEST_F(TabletModeControllerTest, StableHingeAnglesWithLidOpened) {
340 ASSERT_FALSE(IsTabletModeStarted());
341 ASSERT_FALSE(WasLidOpenedRecently());
342
343 OpenLidToAngle(180.0f);
344 EXPECT_FALSE(IsTabletModeStarted());
345
346 OpenLidToAngle(315.0f);
347 EXPECT_TRUE(IsTabletModeStarted());
348
349 OpenLidToAngle(180.0f);
350 EXPECT_TRUE(IsTabletModeStarted());
351
352 OpenLidToAngle(45.0f);
353 EXPECT_FALSE(IsTabletModeStarted());
354
355 OpenLidToAngle(270.0f);
356 EXPECT_TRUE(IsTabletModeStarted());
357
358 OpenLidToAngle(90.0f);
359 EXPECT_FALSE(IsTabletModeStarted());
360 }
361
362 // Verify the tablet mode state for unstable hinge angles when the lid is open
363 // but not recently.
364 TEST_F(TabletModeControllerTest, UnstableHingeAnglesWithLidOpened) {
365 AttachTickClockForTest();
366
367 ASSERT_FALSE(WasLidOpenedRecently());
368 ASSERT_FALSE(IsTabletModeStarted());
369
370 OpenLidToAngle(5.0f);
371 EXPECT_FALSE(IsTabletModeStarted());
372
373 OpenLidToAngle(355.0f);
374 EXPECT_TRUE(IsTabletModeStarted());
375
376 OpenLidToAngle(5.0f);
377 EXPECT_TRUE(IsTabletModeStarted());
378 }
379
380 // Tests that when the hinge is nearly vertically aligned, the current state
381 // persists as the computed angle is highly inaccurate in this orientation.
382 TEST_F(TabletModeControllerTest, HingeAligned) {
383 // Laptop in normal orientation lid open 90 degrees.
384 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
385 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
386 EXPECT_FALSE(IsTabletModeStarted());
387
388 // Completely vertical.
389 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
390 gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
391 EXPECT_FALSE(IsTabletModeStarted());
392
393 // Close to vertical but with hinge appearing to be open 270 degrees.
394 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
395 gfx::Vector3dF(kMeanGravity, 0.1f, 0.0f));
396 EXPECT_FALSE(IsTabletModeStarted());
397
398 // Flat and open 270 degrees should start tablet mode.
399 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
400 gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
401 EXPECT_TRUE(IsTabletModeStarted());
402
403 // Normal 90 degree orientation but near vertical should stay in maximize
404 // mode.
405 TriggerBaseAndLidUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
406 gfx::Vector3dF(kMeanGravity, -0.1f, 0.0f));
407 EXPECT_TRUE(IsTabletModeStarted());
408 }
409
410 TEST_F(TabletModeControllerTest, LaptopTest) {
411 // Feeds in sample accelerometer data and verifies that there are no
412 // transitions into touchview / tablet mode while shaking the device around
413 // with the hinge at less than 180 degrees. Note the conversion from device
414 // data to accelerometer updates consistent with accelerometer_reader.cc.
415 ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength % 6);
416 for (size_t i = 0; i < kAccelerometerLaptopModeTestDataLength / 6; ++i) {
417 gfx::Vector3dF base(-kAccelerometerLaptopModeTestData[i * 6 + 1],
418 -kAccelerometerLaptopModeTestData[i * 6],
419 -kAccelerometerLaptopModeTestData[i * 6 + 2]);
420 base.Scale(kMeanGravity);
421 gfx::Vector3dF lid(-kAccelerometerLaptopModeTestData[i * 6 + 4],
422 kAccelerometerLaptopModeTestData[i * 6 + 3],
423 kAccelerometerLaptopModeTestData[i * 6 + 5]);
424 lid.Scale(kMeanGravity);
425 TriggerBaseAndLidUpdate(base, lid);
426 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
427 // one failure rather than potentially hundreds.
428 ASSERT_FALSE(IsTabletModeStarted());
429 }
430 }
431
432 TEST_F(TabletModeControllerTest, TabletModeTest) {
433 // Trigger tablet mode by opening to 270 to begin the test in tablet mode.
434 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
435 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
436 ASSERT_TRUE(IsTabletModeStarted());
437
438 // Feeds in sample accelerometer data and verifies that there are no
439 // transitions out of touchview / tablet mode while shaking the device
440 // around. Note the conversion from device data to accelerometer updates
441 // consistent with accelerometer_reader.cc.
442 ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength % 6);
443 for (size_t i = 0; i < kAccelerometerFullyOpenTestDataLength / 6; ++i) {
444 gfx::Vector3dF base(-kAccelerometerFullyOpenTestData[i * 6 + 1],
445 -kAccelerometerFullyOpenTestData[i * 6],
446 -kAccelerometerFullyOpenTestData[i * 6 + 2]);
447 base.Scale(kMeanGravity);
448 gfx::Vector3dF lid(-kAccelerometerFullyOpenTestData[i * 6 + 4],
449 kAccelerometerFullyOpenTestData[i * 6 + 3],
450 kAccelerometerFullyOpenTestData[i * 6 + 5]);
451 lid.Scale(kMeanGravity);
452 TriggerBaseAndLidUpdate(base, lid);
453 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
454 // one failure rather than potentially hundreds.
455 ASSERT_TRUE(IsTabletModeStarted());
456 }
457 }
458
459 TEST_F(TabletModeControllerTest, VerticalHingeTest) {
460 // Feeds in sample accelerometer data and verifies that there are no
461 // transitions out of touchview / tablet mode while shaking the device
462 // around, while the hinge is nearly vertical. The data was captured from
463 // maxmimize_mode_controller.cc and does not require conversion.
464 ASSERT_EQ(0u, kAccelerometerVerticalHingeTestDataLength % 6);
465 for (size_t i = 0; i < kAccelerometerVerticalHingeTestDataLength / 6; ++i) {
466 gfx::Vector3dF base(kAccelerometerVerticalHingeTestData[i * 6],
467 kAccelerometerVerticalHingeTestData[i * 6 + 1],
468 kAccelerometerVerticalHingeTestData[i * 6 + 2]);
469 gfx::Vector3dF lid(kAccelerometerVerticalHingeTestData[i * 6 + 3],
470 kAccelerometerVerticalHingeTestData[i * 6 + 4],
471 kAccelerometerVerticalHingeTestData[i * 6 + 5]);
472 TriggerBaseAndLidUpdate(base, lid);
473 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
474 // one failure rather than potentially hundreds.
475 ASSERT_TRUE(IsTabletModeStarted());
476 }
477 }
478
479 // Test if this case does not crash. See http://crbug.com/462806
480 TEST_F(TabletModeControllerTest, DisplayDisconnectionDuringOverview) {
481 UpdateDisplay("800x600,800x600");
482 std::unique_ptr<aura::Window> w1(
483 CreateTestWindowInShellWithBounds(gfx::Rect(0, 0, 100, 100)));
484 std::unique_ptr<aura::Window> w2(
485 CreateTestWindowInShellWithBounds(gfx::Rect(800, 0, 100, 100)));
486 ASSERT_NE(w1->GetRootWindow(), w2->GetRootWindow());
487
488 tablet_mode_controller()->EnableTabletModeWindowManager(true);
489 EXPECT_TRUE(Shell::Get()->window_selector_controller()->ToggleOverview());
490
491 UpdateDisplay("800x600");
492 EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
493 EXPECT_EQ(w1->GetRootWindow(), w2->GetRootWindow());
494 }
495
496 // Test that the disabling of the internal display exits tablet mode, and that
497 // while disabled we do not re-enter tablet mode.
498 TEST_F(TabletModeControllerTest, NoTabletModeWithDisabledInternalDisplay) {
499 UpdateDisplay("200x200, 200x200");
500 const int64_t internal_display_id =
501 display::test::DisplayManagerTestApi(display_manager())
502 .SetFirstDisplayAsInternalDisplay();
503 ASSERT_FALSE(IsTabletModeStarted());
504
505 OpenLidToAngle(270.0f);
506 EXPECT_TRUE(IsTabletModeStarted());
507 EXPECT_TRUE(AreEventsBlocked());
508
509 // Deactivate internal display to simulate Docked Mode.
510 std::vector<display::ManagedDisplayInfo> secondary_only;
511 secondary_only.push_back(display_manager()->GetDisplayInfo(
512 display_manager()->GetDisplayAt(1).id()));
513 display_manager()->OnNativeDisplaysChanged(secondary_only);
514 ASSERT_FALSE(display_manager()->IsActiveDisplayId(internal_display_id));
515 EXPECT_FALSE(IsTabletModeStarted());
516 EXPECT_FALSE(AreEventsBlocked());
517
518 OpenLidToAngle(270.0f);
519 EXPECT_FALSE(IsTabletModeStarted());
520 EXPECT_FALSE(AreEventsBlocked());
521
522 // Tablet mode signal should also be ignored.
523 SetTabletMode(true);
524 EXPECT_FALSE(IsTabletModeStarted());
525 EXPECT_FALSE(AreEventsBlocked());
526 }
527
528 // Tests that is a tablet mode signal is received while docked, that maximize
529 // mode is enabled upon exiting docked mode.
530 TEST_F(TabletModeControllerTest, TabletModeAfterExitingDockedMode) {
531 UpdateDisplay("200x200, 200x200");
532 const int64_t internal_display_id =
533 display::test::DisplayManagerTestApi(display_manager())
534 .SetFirstDisplayAsInternalDisplay();
535 ASSERT_FALSE(IsTabletModeStarted());
536
537 // Deactivate internal display to simulate Docked Mode.
538 std::vector<display::ManagedDisplayInfo> all_displays;
539 all_displays.push_back(display_manager()->GetDisplayInfo(
540 display_manager()->GetDisplayAt(0).id()));
541 std::vector<display::ManagedDisplayInfo> secondary_only;
542 display::ManagedDisplayInfo secondary_display =
543 display_manager()->GetDisplayInfo(
544 display_manager()->GetDisplayAt(1).id());
545 all_displays.push_back(secondary_display);
546 secondary_only.push_back(secondary_display);
547 display_manager()->OnNativeDisplaysChanged(secondary_only);
548 ASSERT_FALSE(display_manager()->IsActiveDisplayId(internal_display_id));
549
550 // Tablet mode signal should also be ignored.
551 SetTabletMode(true);
552 EXPECT_FALSE(IsTabletModeStarted());
553 EXPECT_FALSE(AreEventsBlocked());
554
555 // Exiting docked state
556 display_manager()->OnNativeDisplaysChanged(all_displays);
557 display::test::DisplayManagerTestApi(display_manager())
558 .SetFirstDisplayAsInternalDisplay();
559 EXPECT_TRUE(IsTabletModeStarted());
560 }
561
562 // Verify that the device won't exit touchview / tablet mode for unstable
563 // angles when hinge is nearly vertical
564 TEST_F(TabletModeControllerTest, VerticalHingeUnstableAnglesTest) {
565 // Trigger tablet mode by opening to 270 to begin the test in tablet mode.
566 TriggerBaseAndLidUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
567 gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
568 ASSERT_TRUE(IsTabletModeStarted());
569
570 // Feeds in sample accelerometer data and verifies that there are no
571 // transitions out of touchview / tablet mode while shaking the device
572 // around, while the hinge is nearly vertical. The data was captured
573 // from maxmimize_mode_controller.cc and does not require conversion.
574 ASSERT_EQ(0u, kAccelerometerVerticalHingeUnstableAnglesTestDataLength % 6);
575 for (size_t i = 0;
576 i < kAccelerometerVerticalHingeUnstableAnglesTestDataLength / 6; ++i) {
577 gfx::Vector3dF base(
578 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6],
579 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 1],
580 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 2]);
581 gfx::Vector3dF lid(
582 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 3],
583 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 4],
584 kAccelerometerVerticalHingeUnstableAnglesTestData[i * 6 + 5]);
585 TriggerBaseAndLidUpdate(base, lid);
586 // There are a lot of samples, so ASSERT rather than EXPECT to only generate
587 // one failure rather than potentially hundreds.
588 ASSERT_TRUE(IsTabletModeStarted());
589 }
590 }
591
592 // Tests that when a TabletModeController is created that cached tablet mode
593 // state will trigger a mode update.
594 TEST_F(TabletModeControllerTest, InitializedWhileTabletModeSwitchOn) {
595 base::RunLoop().RunUntilIdle();
596 // FakePowerManagerClient is always installed for tests
597 chromeos::FakePowerManagerClient* power_manager_client =
598 static_cast<chromeos::FakePowerManagerClient*>(
599 chromeos::DBusThreadManager::Get()->GetPowerManagerClient());
600 power_manager_client->set_tablet_mode(
601 chromeos::PowerManagerClient::TabletMode::ON);
602 TabletModeController controller;
603 EXPECT_FALSE(controller.IsTabletModeWindowManagerEnabled());
604 // PowerManagerClient callback is a posted task.
605 base::RunLoop().RunUntilIdle();
606 EXPECT_TRUE(controller.IsTabletModeWindowManagerEnabled());
607 }
608
609 // Verify when the force clamshell mode flag is turned on, opening the lid past
610 // 180 degrees or setting tablet mode to true will no turn on tablet mode.
611 TEST_F(TabletModeControllerTest, ForceClamshellModeTest) {
612 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
613 switches::kAshForceTabletMode, switches::kAshForceTabletModeClamshell);
614 tablet_mode_controller()->OnShellInitialized();
615 EXPECT_EQ(TabletModeController::ForceTabletMode::CLAMSHELL,
616 forced_tablet_mode());
617 EXPECT_FALSE(IsTabletModeStarted());
618
619 OpenLidToAngle(300.0f);
620 EXPECT_FALSE(IsTabletModeStarted());
621 EXPECT_FALSE(AreEventsBlocked());
622
623 SetTabletMode(true);
624 EXPECT_FALSE(IsTabletModeStarted());
625 EXPECT_FALSE(AreEventsBlocked());
626 }
627
628 // Verify when the force touch view mode flag is turned on, tablet mode is on
629 // intially, and opening the lid to less than 180 degress or setting tablet mode
630 // to off will not turn off tablet mode.
631 TEST_F(TabletModeControllerTest, ForceTouchViewModeTest) {
632 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
633 switches::kAshForceTabletMode, switches::kAshForceTabletModeTouchView);
634 tablet_mode_controller()->OnShellInitialized();
635 EXPECT_EQ(TabletModeController::ForceTabletMode::TOUCHVIEW,
636 forced_tablet_mode());
637 EXPECT_TRUE(IsTabletModeStarted());
638 EXPECT_TRUE(AreEventsBlocked());
639
640 OpenLidToAngle(30.0f);
641 EXPECT_TRUE(IsTabletModeStarted());
642 EXPECT_TRUE(AreEventsBlocked());
643
644 SetTabletMode(false);
645 EXPECT_TRUE(IsTabletModeStarted());
646 EXPECT_TRUE(AreEventsBlocked());
647 }
648
649 TEST_F(TabletModeControllerTest, RestoreAfterExit) {
650 UpdateDisplay("1000x600");
651 std::unique_ptr<aura::Window> w1(
652 CreateTestWindowInShellWithBounds(gfx::Rect(10, 10, 900, 300)));
653 tablet_mode_controller()->EnableTabletModeWindowManager(true);
654 Shell::Get()->screen_orientation_controller()->SetLockToRotation(
655 display::Display::ROTATE_90);
656 display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
657 EXPECT_EQ(display::Display::ROTATE_90, display.rotation());
658 EXPECT_LT(display.size().width(), display.size().height());
659 tablet_mode_controller()->EnableTabletModeWindowManager(false);
660 display = display::Screen::GetScreen()->GetPrimaryDisplay();
661 // Sanity checks.
662 EXPECT_EQ(display::Display::ROTATE_0, display.rotation());
663 EXPECT_GT(display.size().width(), display.size().height());
664
665 // The bounds should be restored to the original bounds, and
666 // should not be clamped by the portrait display in touch view.
667 EXPECT_EQ(gfx::Rect(10, 10, 900, 300), w1->bounds());
668 }
669
670 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/tablet_mode/tablet_mode_controller.cc ('k') | ash/wm/tablet_mode/tablet_mode_event_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698