Home | History | Annotate | Download | only in maximize_mode
      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 <math.h>
      6 
      7 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
      8 
      9 #include "ash/accelerometer/accelerometer_controller.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/test/simple_test_tick_clock.h"
     18 #include "ui/accelerometer/accelerometer_types.h"
     19 #include "ui/events/event_handler.h"
     20 #include "ui/events/test/event_generator.h"
     21 #include "ui/gfx/vector3d_f.h"
     22 #include "ui/message_center/message_center.h"
     23 
     24 #if defined(USE_X11)
     25 #include "ui/events/test/events_test_utils_x11.h"
     26 #endif
     27 
     28 namespace ash {
     29 
     30 namespace {
     31 
     32 const float kDegreesToRadians = 3.1415926f / 180.0f;
     33 const float kMeanGravity = 9.8066f;
     34 
     35 }  // namespace
     36 
     37 // Test accelerometer data taken with the lid at less than 180 degrees while
     38 // shaking the device around. The data is to be interpreted in groups of 6 where
     39 // each 6 values corresponds to the X, Y, and Z readings from the base and lid
     40 // accelerometers in this order.
     41 extern const float kAccelerometerLaptopModeTestData[];
     42 extern const size_t kAccelerometerLaptopModeTestDataLength;
     43 
     44 // Test accelerometer data taken with the lid open 360 degrees while
     45 // shaking the device around. The data is to be interpreted in groups of 6 where
     46 // each 6 values corresponds to the X, Y, and Z readings from the base and lid
     47 // accelerometers in this order.
     48 extern const float kAccelerometerFullyOpenTestData[];
     49 extern const size_t kAccelerometerFullyOpenTestDataLength;
     50 
     51 class MaximizeModeControllerTest : public test::AshTestBase {
     52  public:
     53   MaximizeModeControllerTest() {}
     54   virtual ~MaximizeModeControllerTest() {}
     55 
     56   virtual void SetUp() OVERRIDE {
     57     test::AshTestBase::SetUp();
     58     Shell::GetInstance()->accelerometer_controller()->RemoveObserver(
     59         maximize_mode_controller());
     60 
     61     // Set the first display to be the internal display for the accelerometer
     62     // screen rotation tests.
     63     test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
     64         SetFirstDisplayAsInternalDisplay();
     65   }
     66 
     67   virtual void TearDown() OVERRIDE {
     68     Shell::GetInstance()->accelerometer_controller()->AddObserver(
     69         maximize_mode_controller());
     70     test::AshTestBase::TearDown();
     71   }
     72 
     73   MaximizeModeController* maximize_mode_controller() {
     74     return Shell::GetInstance()->maximize_mode_controller();
     75   }
     76 
     77   void TriggerAccelerometerUpdate(const gfx::Vector3dF& base,
     78                                   const gfx::Vector3dF& lid) {
     79     ui::AccelerometerUpdate update;
     80     update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
     81         base.x(), base.y(), base.z());
     82     update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
     83         lid.x(), lid.y(), lid.z());
     84     maximize_mode_controller()->OnAccelerometerUpdated(update);
     85   }
     86 
     87   bool IsMaximizeModeStarted() {
     88     return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled();
     89   }
     90 
     91   gfx::Display::Rotation GetInternalDisplayRotation() const {
     92     return Shell::GetInstance()->display_manager()->GetDisplayInfo(
     93         gfx::Display::InternalDisplayId()).rotation();
     94   }
     95 
     96   void SetInternalDisplayRotation(gfx::Display::Rotation rotation) const {
     97     Shell::GetInstance()->display_manager()->
     98         SetDisplayRotation(gfx::Display::InternalDisplayId(), rotation);
     99   }
    100 
    101   // Attaches a SimpleTestTickClock to the MaximizeModeController with a non
    102   // null value initial value.
    103   void AttachTickClockForTest() {
    104     scoped_ptr<base::TickClock> tick_clock(
    105         test_tick_clock_ = new base::SimpleTestTickClock());
    106     test_tick_clock_->Advance(base::TimeDelta::FromSeconds(1));
    107     maximize_mode_controller()->SetTickClockForTest(tick_clock.Pass());
    108   }
    109 
    110   void AdvanceTickClock(const base::TimeDelta& delta) {
    111     DCHECK(test_tick_clock_);
    112     test_tick_clock_->Advance(delta);
    113   }
    114 
    115   void OpenLidToAngle(float degrees) {
    116     DCHECK(degrees >= 0.0f);
    117     DCHECK(degrees <= 360.0f);
    118 
    119     float radians = degrees * kDegreesToRadians;
    120     gfx::Vector3dF base_vector(0.0f, -kMeanGravity, 0.0f);
    121     gfx::Vector3dF lid_vector(0.0f,
    122                               kMeanGravity * cos(radians),
    123                               kMeanGravity * sin(radians));
    124     TriggerAccelerometerUpdate(base_vector, lid_vector);
    125   }
    126 
    127 #if defined(OS_CHROMEOS)
    128   void OpenLid() {
    129     maximize_mode_controller()->LidEventReceived(true /* open */,
    130         maximize_mode_controller()->tick_clock_->NowTicks());
    131   }
    132 
    133   void CloseLid() {
    134     maximize_mode_controller()->LidEventReceived(false /* open */,
    135         maximize_mode_controller()->tick_clock_->NowTicks());
    136   }
    137 #endif  // OS_CHROMEOS
    138 
    139   bool WasLidOpenedRecently() {
    140     return maximize_mode_controller()->WasLidOpenedRecently();
    141   }
    142 
    143  private:
    144   base::SimpleTestTickClock* test_tick_clock_;
    145 
    146   DISALLOW_COPY_AND_ASSIGN(MaximizeModeControllerTest);
    147 };
    148 
    149 #if defined(OS_CHROMEOS)
    150 
    151 // Verify that closing the lid will exit maximize mode.
    152 TEST_F(MaximizeModeControllerTest, CloseLidWhileInMaximizeMode) {
    153   OpenLidToAngle(315.0f);
    154   ASSERT_TRUE(IsMaximizeModeStarted());
    155 
    156   CloseLid();
    157   EXPECT_FALSE(IsMaximizeModeStarted());
    158 }
    159 
    160 // Verify that maximize mode will not be entered when the lid is closed.
    161 TEST_F(MaximizeModeControllerTest,
    162     HingeAnglesWithLidClosed) {
    163   AttachTickClockForTest();
    164 
    165   CloseLid();
    166 
    167   OpenLidToAngle(270.0f);
    168   EXPECT_FALSE(IsMaximizeModeStarted());
    169 
    170   OpenLidToAngle(315.0f);
    171   EXPECT_FALSE(IsMaximizeModeStarted());
    172 
    173   OpenLidToAngle(355.0f);
    174   EXPECT_FALSE(IsMaximizeModeStarted());
    175 }
    176 
    177 // Verify the maximize mode state for unstable hinge angles when the lid was
    178 // recently open.
    179 TEST_F(MaximizeModeControllerTest,
    180     UnstableHingeAnglesWhenLidRecentlyOpened) {
    181   AttachTickClockForTest();
    182 
    183   OpenLid();
    184   ASSERT_TRUE(WasLidOpenedRecently());
    185 
    186   OpenLidToAngle(5.0f);
    187   EXPECT_FALSE(IsMaximizeModeStarted());
    188 
    189   OpenLidToAngle(355.0f);
    190   EXPECT_FALSE(IsMaximizeModeStarted());
    191 
    192   // This is a stable reading and should clear the last lid opened time.
    193   OpenLidToAngle(45.0f);
    194   EXPECT_FALSE(IsMaximizeModeStarted());
    195   EXPECT_FALSE(WasLidOpenedRecently());
    196 
    197   OpenLidToAngle(355.0f);
    198   EXPECT_TRUE(IsMaximizeModeStarted());
    199 }
    200 
    201 #endif  // OS_CHROMEOS
    202 
    203 // Verify the WasLidOpenedRecently signal with respect to time.
    204 TEST_F(MaximizeModeControllerTest, WasLidOpenedRecentlyOverTime) {
    205 #if defined(OS_CHROMEOS)
    206 
    207   AttachTickClockForTest();
    208 
    209   // No lid open time initially.
    210   ASSERT_FALSE(WasLidOpenedRecently());
    211 
    212   CloseLid();
    213   EXPECT_FALSE(WasLidOpenedRecently());
    214 
    215   OpenLid();
    216   EXPECT_TRUE(WasLidOpenedRecently());
    217 
    218   // 1 second after lid open.
    219   AdvanceTickClock(base::TimeDelta::FromSeconds(1));
    220   EXPECT_TRUE(WasLidOpenedRecently());
    221 
    222   // 3 seconds after lid open.
    223   AdvanceTickClock(base::TimeDelta::FromSeconds(2));
    224   EXPECT_FALSE(WasLidOpenedRecently());
    225 
    226 #else
    227 
    228   EXPECT_FALSE(WasLidOpenedRecently());
    229 
    230 #endif  // OS_CHROMEOS
    231 }
    232 
    233 // Verify the maximize mode enter/exit thresholds for stable angles.
    234 TEST_F(MaximizeModeControllerTest, StableHingeAnglesWithLidOpened) {
    235   ASSERT_FALSE(IsMaximizeModeStarted());
    236   ASSERT_FALSE(WasLidOpenedRecently());
    237 
    238   OpenLidToAngle(180.0f);
    239   EXPECT_FALSE(IsMaximizeModeStarted());
    240 
    241   OpenLidToAngle(315.0f);
    242   EXPECT_TRUE(IsMaximizeModeStarted());
    243 
    244   OpenLidToAngle(180.0f);
    245   EXPECT_TRUE(IsMaximizeModeStarted());
    246 
    247   OpenLidToAngle(45.0f);
    248   EXPECT_FALSE(IsMaximizeModeStarted());
    249 
    250   OpenLidToAngle(270.0f);
    251   EXPECT_TRUE(IsMaximizeModeStarted());
    252 
    253   OpenLidToAngle(90.0f);
    254   EXPECT_FALSE(IsMaximizeModeStarted());
    255 }
    256 
    257 // Verify the maximize mode state for unstable hinge angles when the lid is open
    258 // but not recently.
    259 TEST_F(MaximizeModeControllerTest, UnstableHingeAnglesWithLidOpened) {
    260   AttachTickClockForTest();
    261 
    262   ASSERT_FALSE(WasLidOpenedRecently());
    263   ASSERT_FALSE(IsMaximizeModeStarted());
    264 
    265   OpenLidToAngle(5.0f);
    266   EXPECT_FALSE(IsMaximizeModeStarted());
    267 
    268   OpenLidToAngle(355.0f);
    269   EXPECT_TRUE(IsMaximizeModeStarted());
    270 
    271   OpenLidToAngle(5.0f);
    272   EXPECT_TRUE(IsMaximizeModeStarted());
    273 }
    274 
    275 // Tests that when the hinge is nearly vertically aligned, the current state
    276 // persists as the computed angle is highly inaccurate in this orientation.
    277 TEST_F(MaximizeModeControllerTest, HingeAligned) {
    278   // Laptop in normal orientation lid open 90 degrees.
    279   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
    280                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    281   EXPECT_FALSE(IsMaximizeModeStarted());
    282 
    283   // Completely vertical.
    284   TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
    285                              gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
    286   EXPECT_FALSE(IsMaximizeModeStarted());
    287 
    288   // Close to vertical but with hinge appearing to be open 270 degrees.
    289   TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
    290                              gfx::Vector3dF(kMeanGravity, 0.1f, 0.0f));
    291   EXPECT_FALSE(IsMaximizeModeStarted());
    292 
    293   // Flat and open 270 degrees should start maximize mode.
    294   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
    295                              gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
    296   EXPECT_TRUE(IsMaximizeModeStarted());
    297 
    298   // Normal 90 degree orientation but near vertical should stay in maximize
    299   // mode.
    300   TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
    301                              gfx::Vector3dF(kMeanGravity, -0.1f, 0.0f));
    302   EXPECT_TRUE(IsMaximizeModeStarted());
    303 }
    304 
    305 // Tests that accelerometer readings in each of the screen angles will trigger a
    306 // rotation of the internal display.
    307 TEST_F(MaximizeModeControllerTest, DisplayRotation) {
    308   // Trigger maximize mode by opening to 270.
    309   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    310                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    311   ASSERT_TRUE(IsMaximizeModeStarted());
    312 
    313   // Now test rotating in all directions.
    314   TriggerAccelerometerUpdate(gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f),
    315                              gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f));
    316   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    317   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f),
    318                              gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
    319   EXPECT_EQ(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
    320   TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
    321                              gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
    322   EXPECT_EQ(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
    323   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, kMeanGravity, 0.0f),
    324                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    325   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    326 }
    327 
    328 // Tests that low angles are ignored by the accelerometer (i.e. when the device
    329 // is almost laying flat).
    330 TEST_F(MaximizeModeControllerTest, RotationIgnoresLowAngles) {
    331   // Trigger maximize mode by opening to 270.
    332   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    333                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    334   ASSERT_TRUE(IsMaximizeModeStarted());
    335 
    336   TriggerAccelerometerUpdate(
    337       gfx::Vector3dF(0.0f, kMeanGravity, kMeanGravity),
    338       gfx::Vector3dF(0.0f, -kMeanGravity, -kMeanGravity));
    339   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    340   TriggerAccelerometerUpdate(gfx::Vector3dF(-2.0f, 0.0f, kMeanGravity),
    341                              gfx::Vector3dF(-2.0f, 0.0f, -kMeanGravity));
    342   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    343   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -2.0f, kMeanGravity),
    344                              gfx::Vector3dF(0.0f, 2.0f, -kMeanGravity));
    345   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    346   TriggerAccelerometerUpdate(gfx::Vector3dF(2.0f, 0.0f, kMeanGravity),
    347                              gfx::Vector3dF(2.0f, 0.0f, -kMeanGravity));
    348   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    349   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 2.0f, kMeanGravity),
    350                              gfx::Vector3dF(0.0f, -2.0f, -kMeanGravity));
    351   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    352 }
    353 
    354 // Tests that the display will stick to the current orientation beyond the
    355 // halfway point, preventing frequent updates back and forth.
    356 TEST_F(MaximizeModeControllerTest, RotationSticky) {
    357   // Trigger maximize mode by opening to 270.
    358   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    359                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    360   ASSERT_TRUE(IsMaximizeModeStarted());
    361 
    362   gfx::Vector3dF gravity(0.0f, -kMeanGravity, 0.0f);
    363   TriggerAccelerometerUpdate(gravity, gravity);
    364   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    365 
    366   // Turn past half-way point to next direction and rotation should remain
    367   // the same.
    368   float degrees = 50.0;
    369   gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
    370   gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
    371   TriggerAccelerometerUpdate(gravity, gravity);
    372   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    373 
    374   // Turn more and the screen should rotate.
    375   degrees = 70.0;
    376   gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
    377   gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
    378   TriggerAccelerometerUpdate(gravity, gravity);
    379   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    380 
    381   // Turn back just beyond the half-way point and the new rotation should
    382   // still be in effect.
    383   degrees = 40.0;
    384   gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
    385   gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
    386   TriggerAccelerometerUpdate(gravity, gravity);
    387   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    388 }
    389 
    390 // Tests that the screen only rotates when maximize mode is engaged, and will
    391 // return to the standard orientation on exiting maximize mode.
    392 TEST_F(MaximizeModeControllerTest, RotationOnlyInMaximizeMode) {
    393   // Rotate on side with lid only open 90 degrees.
    394   TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, -3.5f),
    395                              gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
    396   ASSERT_FALSE(IsMaximizeModeStarted());
    397   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    398 
    399   // Open lid, screen should now rotate to match orientation.
    400   TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, 3.5f),
    401                              gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
    402   ASSERT_TRUE(IsMaximizeModeStarted());
    403   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    404 
    405   // Close lid back to 90, screen should rotate back.
    406   TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, -3.5f),
    407                              gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
    408   ASSERT_FALSE(IsMaximizeModeStarted());
    409   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    410 }
    411 
    412 
    413 TEST_F(MaximizeModeControllerTest, LaptopTest) {
    414   // Feeds in sample accelerometer data and verifies that there are no
    415   // transitions into touchview / maximize mode while shaking the device around
    416   // with the hinge at less than 180 degrees. Note the conversion from device
    417   // data to accelerometer updates consistent with accelerometer_reader.cc.
    418   ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength % 6);
    419   for (size_t i = 0; i < kAccelerometerLaptopModeTestDataLength / 6; ++i) {
    420     gfx::Vector3dF base(-kAccelerometerLaptopModeTestData[i * 6 + 1],
    421                         -kAccelerometerLaptopModeTestData[i * 6],
    422                         -kAccelerometerLaptopModeTestData[i * 6 + 2]);
    423     base.Scale(kMeanGravity);
    424     gfx::Vector3dF lid(-kAccelerometerLaptopModeTestData[i * 6 + 4],
    425                        kAccelerometerLaptopModeTestData[i * 6 + 3],
    426                        kAccelerometerLaptopModeTestData[i * 6 + 5]);
    427     lid.Scale(kMeanGravity);
    428     TriggerAccelerometerUpdate(base, lid);
    429     // There are a lot of samples, so ASSERT rather than EXPECT to only generate
    430     // one failure rather than potentially hundreds.
    431     ASSERT_FALSE(IsMaximizeModeStarted());
    432   }
    433 }
    434 
    435 TEST_F(MaximizeModeControllerTest, MaximizeModeTest) {
    436   // Trigger maximize mode by opening to 270 to begin the test in maximize mode.
    437   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    438                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    439   ASSERT_TRUE(IsMaximizeModeStarted());
    440 
    441   // Feeds in sample accelerometer data and verifies that there are no
    442   // transitions out of touchview / maximize mode while shaking the device
    443   // around. Note the conversion from device data to accelerometer updates
    444   // consistent with accelerometer_reader.cc.
    445   ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength % 6);
    446   for (size_t i = 0; i < kAccelerometerFullyOpenTestDataLength / 6; ++i) {
    447     gfx::Vector3dF base(-kAccelerometerFullyOpenTestData[i * 6 + 1],
    448                         -kAccelerometerFullyOpenTestData[i * 6],
    449                         -kAccelerometerFullyOpenTestData[i * 6 + 2]);
    450     base.Scale(kMeanGravity);
    451     gfx::Vector3dF lid(-kAccelerometerFullyOpenTestData[i * 6 + 4],
    452                        kAccelerometerFullyOpenTestData[i * 6 + 3],
    453                        kAccelerometerFullyOpenTestData[i * 6 + 5]);
    454     lid.Scale(kMeanGravity);
    455     TriggerAccelerometerUpdate(base, lid);
    456     // There are a lot of samples, so ASSERT rather than EXPECT to only generate
    457     // one failure rather than potentially hundreds.
    458     ASSERT_TRUE(IsMaximizeModeStarted());
    459   }
    460 }
    461 
    462 // Tests that the display will stick to its current orientation when the
    463 // rotation lock has been set.
    464 TEST_F(MaximizeModeControllerTest, RotationLockPreventsRotation) {
    465   // Trigger maximize mode by opening to 270.
    466   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    467                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    468   ASSERT_TRUE(IsMaximizeModeStarted());
    469 
    470   gfx::Vector3dF gravity(-kMeanGravity, 0.0f, 0.0f);
    471 
    472   maximize_mode_controller()->SetRotationLocked(true);
    473 
    474   // Turn past the threshold for rotation.
    475   float degrees = 90.0;
    476   gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
    477   gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
    478   TriggerAccelerometerUpdate(gravity, gravity);
    479   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    480 
    481   maximize_mode_controller()->SetRotationLocked(false);
    482   TriggerAccelerometerUpdate(gravity, gravity);
    483   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    484 }
    485 
    486 // Tests that when MaximizeModeController turns off MaximizeMode that on the
    487 // next accelerometer update the rotation lock is cleared.
    488 TEST_F(MaximizeModeControllerTest, ExitingMaximizeModeClearRotationLock) {
    489   // Trigger maximize mode by opening to 270.
    490   OpenLidToAngle(270.0f);
    491   ASSERT_TRUE(IsMaximizeModeStarted());
    492 
    493   maximize_mode_controller()->SetRotationLocked(true);
    494 
    495   OpenLidToAngle(90.0f);
    496   EXPECT_FALSE(IsMaximizeModeStarted());
    497 
    498   // Send an update that would not relaunch MaximizeMode.
    499   OpenLidToAngle(90.0f);
    500   EXPECT_FALSE(maximize_mode_controller()->rotation_locked());
    501 }
    502 
    503 // The TrayDisplay class that is responsible for adding/updating MessageCenter
    504 // notifications is only added to the SystemTray on ChromeOS.
    505 #if defined(OS_CHROMEOS)
    506 // Tests that the screen rotation notifications are suppressed when
    507 // triggered by the accelerometer.
    508 TEST_F(MaximizeModeControllerTest, BlockRotationNotifications) {
    509   test::TestSystemTrayDelegate* tray_delegate =
    510       static_cast<test::TestSystemTrayDelegate*>(
    511           Shell::GetInstance()->system_tray_delegate());
    512   tray_delegate->set_should_show_display_notification(true);
    513 
    514   message_center::MessageCenter* message_center =
    515       message_center::MessageCenter::Get();
    516 
    517   // Make sure notifications are still displayed when
    518   // adjusting the screen rotation directly when not in maximize mode
    519   ASSERT_FALSE(IsMaximizeModeStarted());
    520   ASSERT_NE(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
    521   ASSERT_EQ(0u, message_center->NotificationCount());
    522   ASSERT_FALSE(message_center->HasPopupNotifications());
    523   SetInternalDisplayRotation(gfx::Display::ROTATE_180);
    524   EXPECT_EQ(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
    525   EXPECT_EQ(1u, message_center->NotificationCount());
    526   EXPECT_TRUE(message_center->HasPopupNotifications());
    527 
    528   // Reset the screen rotation.
    529   SetInternalDisplayRotation(gfx::Display::ROTATE_0);
    530   // Clear all notifications
    531   message_center->RemoveAllNotifications(false);
    532   // Trigger maximize mode by opening to 270.
    533   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    534                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    535   EXPECT_TRUE(IsMaximizeModeStarted());
    536   EXPECT_EQ(0u, message_center->NotificationCount());
    537   EXPECT_FALSE(message_center->HasPopupNotifications());
    538 
    539   // Make sure notifications are still displayed when
    540   // adjusting the screen rotation directly when in maximize mode
    541   ASSERT_NE(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
    542   SetInternalDisplayRotation(gfx::Display::ROTATE_270);
    543   maximize_mode_controller()->SetRotationLocked(false);
    544   EXPECT_EQ(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
    545   EXPECT_EQ(1u, message_center->NotificationCount());
    546   EXPECT_TRUE(message_center->HasPopupNotifications());
    547 
    548   // Clear all notifications
    549   message_center->RemoveAllNotifications(false);
    550   EXPECT_EQ(0u, message_center->NotificationCount());
    551   EXPECT_FALSE(message_center->HasPopupNotifications());
    552 
    553   // Make sure notifications are blocked when adjusting the screen rotation
    554   // via the accelerometer while in maximize mode
    555   // Rotate the screen 90 degrees
    556   ASSERT_NE(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    557   TriggerAccelerometerUpdate(gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f),
    558                              gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f));
    559   ASSERT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    560   EXPECT_EQ(0u, message_center->NotificationCount());
    561   EXPECT_FALSE(message_center->HasPopupNotifications());
    562 }
    563 #endif
    564 
    565 // Tests that if a user has set a display rotation that it is restored upon
    566 // exiting maximize mode.
    567 TEST_F(MaximizeModeControllerTest, ResetUserRotationUponExit) {
    568   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
    569   display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(),
    570                                       gfx::Display::ROTATE_90);
    571 
    572   // Trigger maximize mode
    573   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    574                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    575   ASSERT_TRUE(IsMaximizeModeStarted());
    576 
    577   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f),
    578                              gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
    579   EXPECT_EQ(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
    580 
    581   // Exit maximize mode
    582   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
    583                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    584   EXPECT_FALSE(IsMaximizeModeStarted());
    585   EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
    586 }
    587 
    588 // Tests that if a user sets a display rotation that accelerometer rotation
    589 // becomes locked.
    590 TEST_F(MaximizeModeControllerTest,
    591        NonAccelerometerRotationChangesLockRotation) {
    592   // Trigger maximize mode by opening to 270.
    593   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    594                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    595   ASSERT_FALSE(maximize_mode_controller()->rotation_locked());
    596   SetInternalDisplayRotation(gfx::Display::ROTATE_270);
    597   EXPECT_TRUE(maximize_mode_controller()->rotation_locked());
    598 }
    599 
    600 // Tests that if a user changes the display rotation, while rotation is locked,
    601 // that the updates are recorded. Upon exiting maximize mode the latest user
    602 // rotation should be applied.
    603 TEST_F(MaximizeModeControllerTest, UpdateUserRotationWhileRotationLocked) {
    604   // Trigger maximize mode by opening to 270.
    605   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
    606                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    607   SetInternalDisplayRotation(gfx::Display::ROTATE_270);
    608   // User sets rotation to the same rotation that the display was at when
    609   // maximize mode was activated.
    610   SetInternalDisplayRotation(gfx::Display::ROTATE_0);
    611   // Exit maximize mode
    612   TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
    613                              gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
    614   EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
    615 }
    616 
    617 }  // namespace ash
    618