| 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 6f655b28d9a6b2f82a7bbc26ec3d336c47dd42c8..663dcfc1a90bb4b47d051cab1506b16d93d695f1 100644
|
| --- a/ash/wm/maximize_mode/maximize_mode_controller.cc
|
| +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
|
| @@ -56,34 +56,37 @@ const float kMaxStableAngle = 340.0f;
|
| const base::TimeDelta kLidRecentlyOpenedDuration =
|
| base::TimeDelta::FromSeconds(2);
|
|
|
| +// The mean acceleration due to gravity on Earth in m/s^2.
|
| +const float kMeanGravity = 9.80665f;
|
| +
|
| // When the device approaches vertical orientation (i.e. portrait orientation)
|
| // the accelerometers for the base and lid approach the same values (i.e.
|
| // gravity pointing in the direction of the hinge). When this happens we cannot
|
| // compute the hinge angle reliably and must turn ignore accelerometer readings.
|
| // This is the minimum acceleration perpendicular to the hinge under which to
|
| -// detect hinge angle.
|
| -const float kHingeAngleDetectionThreshold = 0.25f;
|
| +// detect hinge angle in m/s^2.
|
| +const float kHingeAngleDetectionThreshold = 2.5f;
|
|
|
| // The maximum deviation from the acceleration expected due to gravity under
|
| -// which to detect hinge angle and screen rotation.
|
| -const float kDeviationFromGravityThreshold = 0.1f;
|
| +// which to detect hinge angle and screen rotation in m/s^2
|
| +const float kDeviationFromGravityThreshold = 1.0f;
|
|
|
| // The maximum deviation between the magnitude of the two accelerometers under
|
| -// which to detect hinge angle and screen rotation. These accelerometers are
|
| -// attached to the same physical device and so should be under the same
|
| -// acceleration.
|
| -const float kNoisyMagnitudeDeviation = 0.1f;
|
| +// which to detect hinge angle and screen rotation in m/s^2. These
|
| +// accelerometers are attached to the same physical device and so should be
|
| +// under the same acceleration.
|
| +const float kNoisyMagnitudeDeviation = 1.0f;
|
|
|
| // The angle which the screen has to be rotated past before the display will
|
| // rotate to match it (i.e. 45.0f is no stickiness).
|
| const float kDisplayRotationStickyAngleDegrees = 60.0f;
|
|
|
| -// The minimum acceleration in a direction required to trigger screen rotation.
|
| -// This prevents rapid toggling of rotation when the device is near flat and
|
| -// there is very little screen aligned force on it. The value is effectively the
|
| -// sine of the rise angle required, with the current value requiring at least a
|
| -// 25 degree rise.
|
| -const float kMinimumAccelerationScreenRotation = 0.42f;
|
| +// The minimum acceleration in m/s^2 in a direction required to trigger screen
|
| +// rotation. This prevents rapid toggling of rotation when the device is near
|
| +// flat and there is very little screen aligned force on it. The value is
|
| +// effectively the sine of the rise angle required times the acceleration due
|
| +// to gravity, with the current value requiring at least a 25 degree rise.
|
| +const float kMinimumAccelerationScreenRotation = 4.2f;
|
|
|
| const float kRadiansToDegrees = 180.0f / 3.14159265f;
|
|
|
| @@ -236,26 +239,35 @@ void MaximizeModeController::Shutdown() {
|
| }
|
|
|
| void MaximizeModeController::OnAccelerometerUpdated(
|
| - const gfx::Vector3dF& base,
|
| - const gfx::Vector3dF& lid) {
|
| + const ui::AccelerometerUpdate& update) {
|
| bool first_accelerometer_update = !have_seen_accelerometer_data_;
|
| have_seen_accelerometer_data_ = true;
|
|
|
| // Ignore the reading if it appears unstable. The reading is considered
|
| // unstable if it deviates too much from gravity and/or the magnitude of the
|
| // reading from the lid differs too much from the reading from the base.
|
| - float base_magnitude = base.Length();
|
| - float lid_magnitude = lid.Length();
|
| - if (std::abs(base_magnitude - lid_magnitude) > kNoisyMagnitudeDeviation ||
|
| - std::abs(base_magnitude - 1.0f) > kDeviationFromGravityThreshold ||
|
| - std::abs(lid_magnitude - 1.0f) > kDeviationFromGravityThreshold) {
|
| - return;
|
| + float base_magnitude =
|
| + update.has(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) ?
|
| + update.get(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD).Length() :
|
| + 0.0f;
|
| + float lid_magnitude = update.has(ui::ACCELEROMETER_SOURCE_SCREEN) ?
|
| + update.get(ui::ACCELEROMETER_SOURCE_SCREEN).Length() : 0.0f;
|
| + bool lid_stable = update.has(ui::ACCELEROMETER_SOURCE_SCREEN) &&
|
| + std::abs(lid_magnitude - kMeanGravity) <= kDeviationFromGravityThreshold;
|
| + bool base_angle_stable = lid_stable &&
|
| + update.has(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) &&
|
| + std::abs(base_magnitude - lid_magnitude) <= kNoisyMagnitudeDeviation &&
|
| + std::abs(base_magnitude - kMeanGravity) <= kDeviationFromGravityThreshold;
|
| +
|
| + if (base_angle_stable) {
|
| + // Responding to the hinge rotation can change the maximize mode state which
|
| + // affects screen rotation, so we handle hinge rotation first.
|
| + HandleHingeRotation(
|
| + update.get(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD),
|
| + update.get(ui::ACCELEROMETER_SOURCE_SCREEN));
|
| }
|
| -
|
| - // Responding to the hinge rotation can change the maximize mode state which
|
| - // affects screen rotation, so we handle hinge rotation first.
|
| - HandleHingeRotation(base, lid);
|
| - HandleScreenRotation(lid);
|
| + if (lid_stable)
|
| + HandleScreenRotation(update.get(ui::ACCELEROMETER_SOURCE_SCREEN));
|
|
|
| if (first_accelerometer_update) {
|
| // On the first accelerometer update we will know if we have entered
|
| @@ -303,14 +315,14 @@ void MaximizeModeController::SuspendDone(
|
|
|
| void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
|
| const gfx::Vector3dF& lid) {
|
| - static const gfx::Vector3dF hinge_vector(0.0f, 1.0f, 0.0f);
|
| + static const gfx::Vector3dF hinge_vector(1.0f, 0.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);
|
| gfx::Vector3dF lid_flattened(lid);
|
| - base_flattened.set_y(0.0f);
|
| - lid_flattened.set_y(0.0f);
|
| + base_flattened.set_x(0.0f);
|
| + lid_flattened.set_x(0.0f);
|
|
|
| // As the hinge approaches a vertical angle, the base and lid accelerometers
|
| // approach the same values making any angle calculations highly inaccurate.
|
| @@ -321,10 +333,13 @@ 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);
|
| + float lid_angle = 180.0f - ClockwiseAngleBetweenVectorsInDegrees(
|
| + base_flattened, lid_flattened, hinge_vector);
|
| + if (lid_angle < 0.0f)
|
| + lid_angle += 360.0f;
|
|
|
| - bool is_angle_stable = angle > kMinStableAngle && angle < kMaxStableAngle;
|
| + bool is_angle_stable = lid_angle >= kMinStableAngle &&
|
| + lid_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
|
| @@ -337,10 +352,10 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
|
| // such that observations of state changes occur after the change and shell
|
| // has fewer states to track.
|
| if (maximize_mode_engaged && is_angle_stable &&
|
| - angle < kExitMaximizeModeAngle) {
|
| + lid_angle <= kExitMaximizeModeAngle) {
|
| LeaveMaximizeMode();
|
| } else if (!lid_is_closed_ && !maximize_mode_engaged &&
|
| - angle > kEnterMaximizeModeAngle &&
|
| + lid_angle >= kEnterMaximizeModeAngle &&
|
| (is_angle_stable || !WasLidOpenedRecently())) {
|
| EnterMaximizeMode();
|
| }
|
| @@ -372,7 +387,7 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) {
|
| // The reference vector is the angle of gravity when the device is rotated
|
| // clockwise by 45 degrees. Computing the angle between this vector and
|
| // gravity we can easily determine the expected display rotation.
|
| - static gfx::Vector3dF rotation_reference(-1.0f, 1.0f, 0.0f);
|
| + static const gfx::Vector3dF rotation_reference(-1.0f, -1.0f, 0.0f);
|
|
|
| // Set the down vector to match the expected direction of gravity given the
|
| // last configured rotation. This is used to enforce a stickiness that the
|
| @@ -380,13 +395,13 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) {
|
| // when holding the device near 45 degrees.
|
| gfx::Vector3dF down(0.0f, 0.0f, 0.0f);
|
| if (current_rotation == gfx::Display::ROTATE_0)
|
| - down.set_x(-1.0f);
|
| + down.set_y(-1.0f);
|
| else if (current_rotation == gfx::Display::ROTATE_90)
|
| - down.set_y(1.0f);
|
| + down.set_x(-1.0f);
|
| else if (current_rotation == gfx::Display::ROTATE_180)
|
| - down.set_x(1.0f);
|
| + down.set_y(1.0f);
|
| else
|
| - down.set_y(-1.0f);
|
| + down.set_x(1.0f);
|
|
|
| // Don't rotate if the screen has not passed the threshold.
|
| if (AngleBetweenVectorsInDegrees(down, lid_flattened) <
|
|
|