| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..34fc1ff273f85d13644374ded94fa94b70a32303
|
| --- /dev/null
|
| +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
|
| @@ -0,0 +1,103 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ash/wm/maximize_mode/maximize_mode_controller.h"
|
| +
|
| +#include "ash/accelerometer/accelerometer_controller.h"
|
| +#include "ash/shell.h"
|
| +#include "ui/gfx/vector3d_f.h"
|
| +
|
| +namespace ash {
|
| +
|
| +namespace {
|
| +
|
| +// The hinge angle at which to enter maximize mode.
|
| +const float kEnterMaximizeModeAngle = 200.0f;
|
| +
|
| +// The angle at which to exit maximize mode, this is specifically less than the
|
| +// 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 = 10.0f;
|
| +
|
| +// 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 angle from vertical under which we will not compute a hinge
|
| +// angle.
|
| +const float kHingeAxisAlignedThreshold = 15.0f;
|
| +
|
| +const float kRadiansToDegrees = 180.0f / 3.14159265f;
|
| +
|
| +// Returns the angle between |base| and |other| in degrees.
|
| +float AngleBetweenVectorsInDegrees(const gfx::Vector3dF& base,
|
| + const gfx::Vector3dF& other) {
|
| + return acos(gfx::DotProduct(base, other) /
|
| + base.Length() / other.Length()) * kRadiansToDegrees;
|
| +}
|
| +
|
| +// Returns the clockwise angle between |base| and |other| where |normal| is the
|
| +// normal of the virtual surface to measure clockwise according to.
|
| +float ClockwiseAngleBetweenVectorsInDegrees(const gfx::Vector3dF& base,
|
| + const gfx::Vector3dF& other,
|
| + const gfx::Vector3dF& normal) {
|
| + float angle = AngleBetweenVectorsInDegrees(base, other);
|
| + gfx::Vector3dF cross(base);
|
| + cross.Cross(other);
|
| + // If the dot product of this cross product is normal, it means that the
|
| + // shortest angle between |base| and |other| was counterclockwise with respect
|
| + // to the surface represented by |normal| and this angle must be reversed.
|
| + if (gfx::DotProduct(cross, normal) > 0.0f)
|
| + angle = 360.0f - angle;
|
| + return angle;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +MaximizeModeController::MaximizeModeController() {
|
| + Shell::GetInstance()->accelerometer_controller()->AddObserver(this);
|
| +}
|
| +
|
| +MaximizeModeController::~MaximizeModeController() {
|
| + Shell::GetInstance()->accelerometer_controller()->RemoveObserver(this);
|
| +}
|
| +
|
| +void MaximizeModeController::OnAccelerometerUpdated(
|
| + const gfx::Vector3dF& base,
|
| + const gfx::Vector3dF& lid) {
|
| + static const gfx::Vector3dF hinge_vector(0.0f, 1.0f, 0.0f);
|
| +
|
| + // As the hinge approaches a vertical angle, the base and lid accelerometers
|
| + // approach the same values making any angle calculations highly inaccurate.
|
| + // Bail out early when it is too close.
|
| + float hinge_angle = AngleBetweenVectorsInDegrees(base, hinge_vector);
|
| + if (hinge_angle < kHingeAxisAlignedThreshold ||
|
| + hinge_angle > 180.0f - kHingeAxisAlignedThreshold)
|
| + return;
|
| +
|
| + // Compute the angle between the base and the lid.
|
| + float angle = ClockwiseAngleBetweenVectorsInDegrees(base, lid, 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.
|
| + bool maximize_mode_engaged =
|
| + Shell::GetInstance()->IsMaximizeModeWindowManagerEnabled();
|
| + if (maximize_mode_engaged &&
|
| + angle > kFullyOpenAngleErrorTolerance &&
|
| + angle < kExitMaximizeModeAngle) {
|
| + Shell::GetInstance()->EnableMaximizeModeWindowManager(false);
|
| + } else if (!maximize_mode_engaged &&
|
| + angle > kEnterMaximizeModeAngle) {
|
| + Shell::GetInstance()->EnableMaximizeModeWindowManager(true);
|
| + }
|
| +}
|
| +
|
| +} // namespace ash
|
|
|