diff options
Diffstat (limited to 'ash')
6 files changed, 130 insertions, 27 deletions
diff --git a/ash/system/chromeos/rotation/tray_rotation_lock.cc b/ash/system/chromeos/rotation/tray_rotation_lock.cc index a2283a7..35cc017 100644 --- a/ash/system/chromeos/rotation/tray_rotation_lock.cc +++ b/ash/system/chromeos/rotation/tray_rotation_lock.cc @@ -56,16 +56,9 @@ RotationLockDefaultView::~RotationLockDefaultView() { bool RotationLockDefaultView::PerformAction(const ui::Event& event) { MaximizeModeController* maximize_mode_controller = Shell::GetInstance()-> maximize_mode_controller(); - bool rotation_locked = !maximize_mode_controller->rotation_locked(); - maximize_mode_controller->set_rotation_locked(rotation_locked); - + maximize_mode_controller->SetRotationLocked( + !maximize_mode_controller->rotation_locked()); UpdateImage(); - - // RotationLockDefaultView can only be created by a TrayRotationLock. The - // owner needs to be told of the action so that it can update its visibility. - static_cast<TrayRotationLock*>(owner())->tray_view()-> - SetVisible(rotation_locked); - return true; } @@ -116,6 +109,10 @@ TrayRotationLock::~TrayRotationLock() { Shell::GetInstance()->RemoveShellObserver(this); } +void TrayRotationLock::OnRotationLockChanged(bool rotation_locked) { + tray_view()->SetVisible(ShouldBeVisible()); +} + views::View* TrayRotationLock::CreateDefaultView(user::LoginStatus status) { if (on_primary_display_) return new tray::RotationLockDefaultView(this); @@ -125,13 +122,19 @@ views::View* TrayRotationLock::CreateDefaultView(user::LoginStatus status) { void TrayRotationLock::OnMaximizeModeStarted() { tray_view()->SetVisible( Shell::GetInstance()->maximize_mode_controller()->rotation_locked()); + Shell::GetInstance()->maximize_mode_controller()->AddObserver(this); } void TrayRotationLock::OnMaximizeModeEnded() { tray_view()->SetVisible(false); + Shell::GetInstance()->maximize_mode_controller()->RemoveObserver(this); } bool TrayRotationLock::GetInitialVisibility() { + return ShouldBeVisible(); +} + +bool TrayRotationLock::ShouldBeVisible() { MaximizeModeController* controller = Shell::GetInstance()-> maximize_mode_controller(); return on_primary_display_ && diff --git a/ash/system/chromeos/rotation/tray_rotation_lock.h b/ash/system/chromeos/rotation/tray_rotation_lock.h index 9c53e6e..2a134d0 100644 --- a/ash/system/chromeos/rotation/tray_rotation_lock.h +++ b/ash/system/chromeos/rotation/tray_rotation_lock.h @@ -7,6 +7,7 @@ #include "ash/shell_observer.h" #include "ash/system/tray/tray_image_item.h" +#include "ash/wm/maximize_mode/maximize_mode_controller.h" namespace ash { @@ -20,11 +21,15 @@ class RotationLockDefaultView; // be interacted with, it toggles the state of the rotation lock. // TrayRotationLock is only available on the primary display. class ASH_EXPORT TrayRotationLock : public TrayImageItem, + public MaximizeModeController::Observer, public ShellObserver { public: explicit TrayRotationLock(SystemTray* system_tray); virtual ~TrayRotationLock(); + // MaximizeModeController::Observer: + virtual void OnRotationLockChanged(bool rotation_locked) OVERRIDE; + // SystemTrayItem: virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE; @@ -39,6 +44,10 @@ class ASH_EXPORT TrayRotationLock : public TrayImageItem, private: friend class TrayRotationLockTest; + // True if |on_primary_display_|, maximize mode is enabled, and rotation is + // locked. + bool ShouldBeVisible(); + // True if this has been created by a SystemTray on the primary display. bool on_primary_display_; diff --git a/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc b/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc index d38c709..3b0eb86 100644 --- a/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc +++ b/ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc @@ -118,21 +118,21 @@ TEST_F(TrayRotationLockTest, CreateTrayViewDuringMaximizeModeAndRotationLock) { TearDownViews(); Shell::GetInstance()->maximize_mode_controller()-> EnableMaximizeModeWindowManager(true); - Shell::GetInstance()-> maximize_mode_controller()->set_rotation_locked(true); + Shell::GetInstance()-> maximize_mode_controller()->SetRotationLocked(true); SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget()); EXPECT_TRUE(tray_view()->visible()); Shell::GetInstance()->maximize_mode_controller()-> EnableMaximizeModeWindowManager(false); + EXPECT_FALSE(tray_view()->visible()); } // Tests that the enabling of MaximizeMode affects a previously created tray // view, changing the visibility. TEST_F(TrayRotationLockTest, TrayViewVisibilityChangesDuringMaximizeMode) { - TearDownViews(); + ASSERT_FALSE(tray_view()->visible()); Shell::GetInstance()->maximize_mode_controller()-> EnableMaximizeModeWindowManager(true); - Shell::GetInstance()-> maximize_mode_controller()->set_rotation_locked(true); - SetUpForStatusAreaWidget(StatusAreaWidgetTestHelper::GetStatusAreaWidget()); + Shell::GetInstance()->maximize_mode_controller()->SetRotationLocked(true); EXPECT_TRUE(tray_view()->visible()); Shell::GetInstance()->maximize_mode_controller()-> EnableMaximizeModeWindowManager(false); diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc index 80a94a3..4b079df 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc @@ -146,6 +146,22 @@ MaximizeModeController::~MaximizeModeController() { Shell::GetInstance()->accelerometer_controller()->RemoveObserver(this); } +void MaximizeModeController::SetRotationLocked(bool rotation_locked) { + if (rotation_locked_ == rotation_locked) + return; + rotation_locked_ = rotation_locked; + FOR_EACH_OBSERVER(Observer, observers_, + OnRotationLockChanged(rotation_locked_)); +} + +void MaximizeModeController::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void MaximizeModeController::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + bool MaximizeModeController::CanEnterMaximizeMode() { // If we have ever seen accelerometer data, then HandleHingeRotation may // trigger maximize mode at some point in the future. @@ -199,6 +215,22 @@ void MaximizeModeController::OnAccelerometerUpdated( HandleScreenRotation(lid); } +void MaximizeModeController::OnDisplayConfigurationChanged() { + if (in_set_screen_rotation_) + return; + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + gfx::Display::Rotation user_rotation = display_manager-> + GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); + if (user_rotation != current_rotation_) { + // A user may change other display configuration settings. When the user + // does change the rotation setting, then lock rotation to prevent the + // accelerometer from erasing their change. + SetRotationLocked(true); + user_rotation_ = user_rotation; + current_rotation_ = user_rotation; + } +} + void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, const gfx::Vector3dF& lid) { static const gfx::Vector3dF hinge_vector(0.0f, 1.0f, 0.0f); @@ -239,6 +271,9 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) { bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled(); + // TODO(jonross): track the updated rotation angle even when locked. So that + // when rotation lock is removed the accelerometer rotation can be applied + // without waiting for the next update. if (!maximize_mode_engaged || rotation_locked_) return; @@ -301,35 +336,34 @@ void MaximizeModeController::SetDisplayRotation( gfx::Display::Rotation rotation) { base::AutoReset<bool> auto_in_set_screen_rotation( &in_set_screen_rotation_, true); + current_rotation_ = rotation; display_manager->SetDisplayRotation(gfx::Display::InternalDisplayId(), rotation); } void MaximizeModeController::EnterMaximizeMode() { - // TODO(jonross): Listen for display configuration changes. If the user - // causes a rotation change a rotation lock should be applied. - // https://crbug.com/369505 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - user_rotation_ = display_manager-> + current_rotation_ = user_rotation_ = display_manager-> GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); EnableMaximizeModeWindowManager(true); event_blocker_.reset(new MaximizeModeEventBlocker); #if defined(OS_CHROMEOS) event_handler_.reset(new ScreenshotActionHandler); #endif + Shell::GetInstance()->display_controller()->AddObserver(this); } void MaximizeModeController::LeaveMaximizeMode() { DisplayManager* display_manager = Shell::GetInstance()->display_manager(); - DisplayInfo info = display_manager-> - GetDisplayInfo(gfx::Display::InternalDisplayId()); - gfx::Display::Rotation current_rotation = info.rotation(); + gfx::Display::Rotation current_rotation = display_manager-> + GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); if (current_rotation != user_rotation_) SetDisplayRotation(display_manager, user_rotation_); rotation_locked_ = false; EnableMaximizeModeWindowManager(false); event_blocker_.reset(); event_handler_.reset(); + Shell::GetInstance()->display_controller()->RemoveObserver(this); } } // namespace ash diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h index 4ee4a38..542ad35 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.h +++ b/ash/wm/maximize_mode/maximize_mode_controller.h @@ -7,9 +7,11 @@ #include "ash/accelerometer/accelerometer_observer.h" #include "ash/ash_export.h" +#include "ash/display/display_controller.h" #include "ash/display/display_manager.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" #include "ui/gfx/display.h" namespace ui { @@ -26,8 +28,20 @@ class MaximizeModeWindowManagerTest; // MaximizeModeController listens to accelerometer events and automatically // enters and exits maximize mode when the lid is opened beyond the triggering // angle and rotates the display to match the device when in maximize mode. -class ASH_EXPORT MaximizeModeController : public AccelerometerObserver { +class ASH_EXPORT MaximizeModeController : public AccelerometerObserver, + public DisplayController::Observer { public: + // Observer that reports changes to the state of MaximizeModeController's + // rotation lock. + class Observer { + public: + // Invoked whenever |rotation_locked_| is changed. + virtual void OnRotationLockChanged(bool rotation_locked) {} + + protected: + virtual ~Observer() {} + }; + MaximizeModeController(); virtual ~MaximizeModeController(); @@ -43,9 +57,11 @@ class ASH_EXPORT MaximizeModeController : public AccelerometerObserver { // If |rotation_locked| future calls to OnAccelerometerUpdated will not // change the display rotation. - void set_rotation_locked(bool rotation_locked) { - rotation_locked_ = rotation_locked; - } + void SetRotationLocked(bool rotation_locked); + + // Add/Remove observers. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); // True if it is possible to enter maximize mode in the current // configuration. If this returns false, it should never be the case that @@ -73,6 +89,9 @@ class ASH_EXPORT MaximizeModeController : public AccelerometerObserver { virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base, const gfx::Vector3dF& lid) OVERRIDE; + // DisplayController::Observer: + virtual void OnDisplayConfigurationChanged() OVERRIDE; + private: friend class MaximizeModeControllerTest; friend class MaximizeModeWindowManagerTest; @@ -121,6 +140,14 @@ class ASH_EXPORT MaximizeModeController : public AccelerometerObserver { // restored upon exiting maximize mode. gfx::Display::Rotation user_rotation_; + // The current rotation set by MaximizeModeController for the internal + // display. Compared in OnDisplayConfigurationChanged to determine user + // display setting changes. + gfx::Display::Rotation current_rotation_; + + // Rotation Lock observers. + ObserverList<Observer> observers_; + DISALLOW_COPY_AND_ASSIGN(MaximizeModeController); }; diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc index 3564bc2..8afb9e3 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc @@ -526,7 +526,7 @@ TEST_F(MaximizeModeControllerTest, RotationLockPreventsRotation) { gfx::Vector3dF gravity(-1.0f, 0.0f, 0.0f); - maximize_mode_controller()->set_rotation_locked(true); + maximize_mode_controller()->SetRotationLocked(true); // Turn past the threshold for rotation. float degrees = 90.0; @@ -535,7 +535,7 @@ TEST_F(MaximizeModeControllerTest, RotationLockPreventsRotation) { TriggerAccelerometerUpdate(gravity, gravity); EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation()); - maximize_mode_controller()->set_rotation_locked(false); + maximize_mode_controller()->SetRotationLocked(false); TriggerAccelerometerUpdate(gravity, gravity); EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation()); } @@ -551,7 +551,7 @@ TEST_F(MaximizeModeControllerTest, ExitingMaximizeModeClearRotationLock) { gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); ASSERT_TRUE(IsMaximizeModeStarted()); - maximize_mode_controller()->set_rotation_locked(true); + maximize_mode_controller()->SetRotationLocked(true); // Open 90 degrees. TriggerAccelerometerUpdate(base, gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); @@ -602,6 +602,7 @@ TEST_F(MaximizeModeControllerTest, BlockRotationNotifications) { // adjusting the screen rotation directly when in maximize mode ASSERT_NE(gfx::Display::ROTATE_270, GetInternalDisplayRotation()); SetInternalDisplayRotation(gfx::Display::ROTATE_270); + maximize_mode_controller()->SetRotationLocked(false); EXPECT_EQ(gfx::Display::ROTATE_270, GetInternalDisplayRotation()); EXPECT_EQ(1u, message_center->NotificationCount()); EXPECT_TRUE(message_center->HasPopupNotifications()); @@ -646,4 +647,33 @@ TEST_F(MaximizeModeControllerTest, ResetUserRotationUponExit) { EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation()); } +// Tests that if a user sets a display rotation that accelerometer rotation +// becomes locked. +TEST_F(MaximizeModeControllerTest, + NonAccelerometerRotationChangesLockRotation) { + // Trigger maximize mode by opening to 270. + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f), + gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); + ASSERT_FALSE(maximize_mode_controller()->rotation_locked()); + SetInternalDisplayRotation(gfx::Display::ROTATE_270); + EXPECT_TRUE(maximize_mode_controller()->rotation_locked()); +} + +// Tests that if a user changes the display rotation, while rotation is locked, +// that the updates are recorded. Upon exiting maximize mode the latest user +// rotation should be applied. +TEST_F(MaximizeModeControllerTest, UpdateUserRotationWhileRotationLocked) { + // Trigger maximize mode by opening to 270. + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f), + gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); + SetInternalDisplayRotation(gfx::Display::ROTATE_270); + // User sets rotation to the same rotation that the display was at when + // maximize mode was activated. + SetInternalDisplayRotation(gfx::Display::ROTATE_0); + // Exit maximize mode + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f), + gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); + EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation()); +} + } // namespace ash |