Chromium Code Reviews| Index: ash/wm/maximize_mode/maximize_mode_controller.cc |
| diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc |
| index 36f6f2514ca137a01e7595f34a8e5176994367ae..055042249e95eeaecb1ea4b26e9bcd4bd8bdb222 100644 |
| --- a/ash/wm/maximize_mode/maximize_mode_controller.cc |
| +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc |
| @@ -15,6 +15,9 @@ |
| #include "base/auto_reset.h" |
| #include "base/command_line.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/time/default_tick_clock.h" |
| +#include "base/time/tick_clock.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
|
jonross
2014/07/25 13:39:06
#if defined this as well.
bruthig
2014/07/25 15:20:42
Done.
|
| #include "ui/base/accelerators/accelerator.h" |
| #include "ui/events/event.h" |
| #include "ui/events/event_handler.h" |
| @@ -36,11 +39,18 @@ const float kEnterMaximizeModeAngle = 200.0f; |
| // angle to enter maximize mode to prevent rapid toggling when near the angle. |
| const float kExitMaximizeModeAngle = 160.0f; |
| -// When the lid is fully open 360 degrees, the accelerometer readings can |
| -// occasionally appear as though the lid is almost closed. If the lid appears |
| -// near closed but the device is on we assume it is an erroneous reading from |
| -// it being open 360 degrees. |
| -const float kFullyOpenAngleErrorTolerance = 20.0f; |
| +// Defines a range for which accelerometer readings are considered accurate. |
| +// When the lid is near open (or near closed) the acceleromter readings may be |
| +// inaccurate and a lid that is fully open may appear to be near closed (and |
| +// vice versa). |
| +const float kMinStableAngle = 20.0f; |
| +const float kMaxStableAngle = 340.0f; |
| + |
| +// The time duration to consider the lid to be recently opened. |
| +// This is used to prevent entering maximize mode if an erroneous accelerometer |
| +// reading makes the lid appear to be fully open when the user is opening the |
| +// lid from a closed position. |
| +base::TimeDelta kLidRecentlyOpenedTolerance = base::TimeDelta::FromSeconds(2); |
|
jonross
2014/07/25 13:39:06
Make this a const.
bruthig
2014/07/25 15:20:42
Done.
|
| // When the device approaches vertical orientation (i.e. portrait orientation) |
| // the accelerometers for the base and lid approach the same values (i.e. |
| @@ -144,14 +154,25 @@ MaximizeModeController::MaximizeModeController() |
| have_seen_accelerometer_data_(false), |
| in_set_screen_rotation_(false), |
| user_rotation_(gfx::Display::ROTATE_0), |
| - last_touchview_transition_time_(base::Time::Now()) { |
| + last_touchview_transition_time_(base::Time::Now()), |
| + last_lid_open_time_(), |
| + tick_clock_(new base::DefaultTickClock()), |
| + lid_is_closed_(false) { |
| Shell::GetInstance()->accelerometer_controller()->AddObserver(this); |
| Shell::GetInstance()->AddShellObserver(this); |
| +#if defined(OS_CHROMEOS) |
| + chromeos::DBusThreadManager::Get()-> |
| + GetPowerManagerClient()->AddObserver(this); |
| +#endif // OS_CHROMEOS |
| } |
| MaximizeModeController::~MaximizeModeController() { |
| Shell::GetInstance()->RemoveShellObserver(this); |
| Shell::GetInstance()->accelerometer_controller()->RemoveObserver(this); |
| +#if defined(OS_CHROMEOS) |
| + chromeos::DBusThreadManager::Get()-> |
| + GetPowerManagerClient()->RemoveObserver(this); |
| +#endif // OS_CHROMEOS |
| } |
| void MaximizeModeController::SetRotationLocked(bool rotation_locked) { |
| @@ -239,10 +260,30 @@ void MaximizeModeController::OnDisplayConfigurationChanged() { |
| } |
| } |
| +#if defined(OS_CHROMEOS) |
| +void MaximizeModeController::LidEventReceived(bool open, |
| + const base::TimeTicks& time) { |
| + if (open) |
| + last_lid_open_time_ = time; |
| + lid_is_closed_ = !open; |
| + LeaveMaximizeMode(); |
| +} |
| + |
| +void MaximizeModeController::SuspendImminent() { |
| + RecordTouchViewStateTransition(); |
| +} |
| + |
| +void MaximizeModeController::SuspendDone( |
| + const base::TimeDelta& sleep_duration) { |
| + last_touchview_transition_time_ = base::Time::Now(); |
| + // A lid open event won't always occur when coming out of a suspend state. |
| + lid_is_closed_ = false; |
| +} |
| +#endif // OS_CHROMEOS |
| + |
| void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, |
| const gfx::Vector3dF& lid) { |
| static const gfx::Vector3dF hinge_vector(0.0f, 1.0f, 0.0f); |
| - bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled(); |
| // Ignore the component of acceleration parallel to the hinge for the purposes |
| // of hinge angle calculation. |
| gfx::Vector3dF base_flattened(base); |
| @@ -261,18 +302,29 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, |
| // Compute the angle between the base and the lid. |
| float angle = ClockwiseAngleBetweenVectorsInDegrees(base_flattened, |
| lid_flattened, hinge_vector); |
| - |
| // Toggle maximize mode on or off when corresponding thresholds are passed. |
| // TODO(flackr): Make MaximizeModeController own the MaximizeModeWindowManager |
| // such that observations of state changes occur after the change and shell |
| // has fewer states to track. |
| - if (maximize_mode_engaged && |
| - angle > kFullyOpenAngleErrorTolerance && |
| - angle < kExitMaximizeModeAngle) { |
| + if (lid_is_closed_) { |
| LeaveMaximizeMode(); |
| - } else if (!maximize_mode_engaged && |
| - angle > kEnterMaximizeModeAngle) { |
| - EnterMaximizeMode(); |
| + } else if (angle > kMinStableAngle && |
| + angle < kMaxStableAngle) { |
| + // Clear the last_lid_open_time_ for a stable reading so that there is less |
| + // chance of a delay if the lid is moved from the close state to the fully |
| + // open state very quickly. |
| + last_lid_open_time_ = base::TimeTicks(); |
| + if (angle < kExitMaximizeModeAngle) { |
| + LeaveMaximizeMode(); |
| + } else if (angle > kEnterMaximizeModeAngle) { |
| + EnterMaximizeMode(); |
| + } |
| + } else if (angle > kMaxStableAngle) { |
| + if (WasLidOpenedRecently()) { |
| + LeaveMaximizeMode(); |
| + } else { |
| + EnterMaximizeMode(); |
| + } |
|
jonross
2014/07/25 13:39:06
I'd rather the new logic be introduced into the pr
bruthig
2014/07/25 15:20:42
Done.
|
| } |
| } |
| @@ -350,6 +402,8 @@ void MaximizeModeController::SetDisplayRotation( |
| } |
| void MaximizeModeController::EnterMaximizeMode() { |
| + if (IsMaximizeModeWindowManagerEnabled()) |
| + return; |
| DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| current_rotation_ = user_rotation_ = display_manager-> |
| GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); |
| @@ -364,6 +418,8 @@ void MaximizeModeController::EnterMaximizeMode() { |
| } |
| void MaximizeModeController::LeaveMaximizeMode() { |
| + if (!IsMaximizeModeWindowManagerEnabled()) |
| + return; |
| DisplayManager* display_manager = Shell::GetInstance()->display_manager(); |
| gfx::Display::Rotation current_rotation = display_manager-> |
| GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); |
| @@ -373,14 +429,7 @@ void MaximizeModeController::LeaveMaximizeMode() { |
| EnableMaximizeModeWindowManager(false); |
| event_blocker_.reset(); |
| event_handler_.reset(); |
| -} |
| - |
| -void MaximizeModeController::OnSuspend() { |
| - RecordTouchViewStateTransition(); |
| -} |
| - |
| -void MaximizeModeController::OnResume() { |
| - last_touchview_transition_time_ = base::Time::Now(); |
| + Shell::GetInstance()->display_controller()->RemoveObserver(this); |
| } |
| // Called after maximize mode has started, windows might still animate though. |
| @@ -428,4 +477,19 @@ void MaximizeModeController::OnAppTerminating() { |
| Shell::GetInstance()->display_controller()->RemoveObserver(this); |
| } |
| +bool MaximizeModeController::WasLidOpenedRecently() const { |
| + if (last_lid_open_time_.is_null()) |
| + return false; |
| + |
| + base::TimeTicks now = tick_clock_->NowTicks(); |
| + DCHECK(now >= last_lid_open_time_); |
| + base::TimeDelta elapsed_time = now - last_lid_open_time_; |
| + return elapsed_time <= kLidRecentlyOpenedTolerance; |
| +} |
| + |
| +void MaximizeModeController::SetTickClockForTest(base::TickClock* tick_clock) { |
| + DCHECK(tick_clock_); |
| + tick_clock_.reset(tick_clock); |
| +} |
| + |
| } // namespace ash |