summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorjonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-12 16:15:41 +0000
committerjonross@chromium.org <jonross@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-12 16:15:41 +0000
commit1b830e9cb3214f10573a31e436027c35f2a3c8f9 (patch)
treecb835d2a51c7567fad2a6afd910aee453162d5f3 /ash
parent6cd63bac095b225a96da10fdde7250814fb1a8bd (diff)
downloadchromium_src-1b830e9cb3214f10573a31e436027c35f2a3c8f9.zip
chromium_src-1b830e9cb3214f10573a31e436027c35f2a3c8f9.tar.gz
chromium_src-1b830e9cb3214f10573a31e436027c35f2a3c8f9.tar.bz2
Lock Rotation on user settings changes
While in MaximizeMode if the rotation of the internal display is changed by a source other than MaximizeModeController rotation lock will be set. Thereby blocking future accelerometer rotations until the user toggles the lock. The rotation lock tray will listen for these changes and update its visuals. TEST=MaximizeModeControllerTest BUG=371426, 369505 Review URL: https://codereview.chromium.org/303723003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276699 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/system/chromeos/rotation/tray_rotation_lock.cc21
-rw-r--r--ash/system/chromeos/rotation/tray_rotation_lock.h9
-rw-r--r--ash/system/chromeos/rotation/tray_rotation_lock_unittest.cc8
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller.cc48
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller.h35
-rw-r--r--ash/wm/maximize_mode/maximize_mode_controller_unittest.cc36
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