Commit 45f31ae7 authored by flackr's avatar flackr Committed by Commit bot

Use standardized and extendable accelerometer update type.

Updates the type used when delivering accelerometer updates in ash to:
- support a variable number of accelerometers
- be measured in m/s^2
- use axes consistent with the web device motion API.

BUG=380831
TEST=MaximizeModeController unit tests still pass.
TEST=Run on a touchview device and verify that entering / exiting touchview as well as screen rotation still works.

Review URL: https://codereview.chromium.org/500613003

Cr-Commit-Position: refs/heads/master@{#292968}
parent 7cd720bd
......@@ -29,6 +29,7 @@ component("ash") {
"//net",
"//skia",
"//third_party/icu",
"//ui/accelerometer",
"//ui/accessibility",
"//ui/app_list",
"//ui/aura",
......@@ -251,6 +252,7 @@ test("ash_unittests") {
"//skia",
"//testing/gtest",
"//third_party/icu",
"//ui/accelerometer",
"//ui/accessibility",
"//ui/aura",
"//ui/aura:test_support",
......
......@@ -5,7 +5,6 @@
#include "ash/accelerometer/accelerometer_controller.h"
#include "ash/accelerometer/accelerometer_observer.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace ash {
......@@ -31,11 +30,10 @@ void AccelerometerController::RemoveObserver(AccelerometerObserver* observer) {
}
#if defined(OS_CHROMEOS)
void AccelerometerController::HandleAccelerometerReading(
const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) {
void AccelerometerController::HandleAccelerometerUpdate(
const ui::AccelerometerUpdate& update) {
FOR_EACH_OBSERVER(AccelerometerObserver, observers_,
OnAccelerometerUpdated(base, lid));
OnAccelerometerUpdated(update));
}
#endif
......
......@@ -18,10 +18,6 @@ namespace base {
class TaskRunner;
}
namespace gfx {
class Vector3dF;
}
namespace ash {
class AccelerometerObserver;
......@@ -50,8 +46,8 @@ class ASH_EXPORT AccelerometerController
// This needs to be CHROMEOS only as on other platforms it does not actually
// override a method.
// chromeos::AccelerometerReader::Delegate:
virtual void HandleAccelerometerReading(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) OVERRIDE;
virtual void HandleAccelerometerUpdate(
const ui::AccelerometerUpdate& update) OVERRIDE;
#endif
private:
......
......@@ -6,20 +6,17 @@
#define ASH_ACCELEROMETER_ACCELEROMETER_OBSERVER_H_
#include "ash/ash_export.h"
namespace gfx {
class Vector3dF;
}
#include "ui/accelerometer/accelerometer_types.h"
namespace ash {
// The interface for classes which observe accelerometer updates.
class ASH_EXPORT AccelerometerObserver {
public:
// Invoked when an accelerometer reading has been taken. The |base| and |lid|
// accelerometer readings are in G's.
virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) = 0;
// Invoked when an accelerometer reading has been taken. The |update| can
// contain readings from one or more AccelerometerSources.
virtual void OnAccelerometerUpdated(
const ui::AccelerometerUpdate& update) = 0;
protected:
virtual ~AccelerometerObserver() {}
......
......@@ -894,6 +894,7 @@
'../skia/skia.gyp:skia',
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/accessibility/accessibility.gyp:accessibility',
'../ui/app_list/app_list.gyp:app_list',
'../ui/aura/aura.gyp:aura',
......@@ -1065,6 +1066,7 @@
'../testing/gtest.gyp:gtest',
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/accessibility/accessibility.gyp:accessibility',
'../ui/app_list/app_list.gyp:app_list',
'../ui/aura/aura.gyp:aura',
......
......@@ -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) <
......
......@@ -109,8 +109,8 @@ class ASH_EXPORT MaximizeModeController
void Shutdown();
// AccelerometerObserver:
virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) OVERRIDE;
virtual void OnAccelerometerUpdated(
const ui::AccelerometerUpdate& update) OVERRIDE;
// ShellObserver:
virtual void OnAppTerminating() OVERRIDE;
......
......@@ -17,6 +17,7 @@
#include "ash/test/test_system_tray_delegate.h"
#include "ash/test/test_volume_control_delegate.h"
#include "base/test/simple_test_tick_clock.h"
#include "ui/accelerometer/accelerometer_types.h"
#include "ui/events/event_handler.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/vector3d_f.h"
......@@ -30,7 +31,8 @@ namespace ash {
namespace {
const float kDegreesToRadians = 3.14159265f / 180.0f;
const float kDegreesToRadians = 3.1415926f / 180.0f;
const float kMeanGravity = 9.8066f;
} // namespace
......@@ -76,7 +78,12 @@ class MaximizeModeControllerTest : public test::AshTestBase {
void TriggerAccelerometerUpdate(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) {
maximize_mode_controller()->OnAccelerometerUpdated(base, lid);
ui::AccelerometerUpdate update;
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
base.x(), base.y(), base.z());
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
lid.x(), lid.y(), lid.z());
maximize_mode_controller()->OnAccelerometerUpdated(update);
}
bool IsMaximizeModeStarted() {
......@@ -112,8 +119,10 @@ class MaximizeModeControllerTest : public test::AshTestBase {
DCHECK(degrees <= 360.0f);
float radians = degrees * kDegreesToRadians;
gfx::Vector3dF base_vector(1.0f, 0.0f, 0.0f);
gfx::Vector3dF lid_vector(cos(radians), 0.0f, sin(radians));
gfx::Vector3dF base_vector(0.0f, -kMeanGravity, 0.0f);
gfx::Vector3dF lid_vector(0.0f,
kMeanGravity * cos(radians),
kMeanGravity * sin(radians));
TriggerAccelerometerUpdate(base_vector, lid_vector);
}
......@@ -269,29 +278,29 @@ TEST_F(MaximizeModeControllerTest, UnstableHingeAnglesWithLidOpened) {
// persists as the computed angle is highly inaccurate in this orientation.
TEST_F(MaximizeModeControllerTest, HingeAligned) {
// Laptop in normal orientation lid open 90 degrees.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
EXPECT_FALSE(IsMaximizeModeStarted());
// Completely vertical.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -1.0f, 0.0f),
gfx::Vector3dF(0.0f, -1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
EXPECT_FALSE(IsMaximizeModeStarted());
// Close to vertical but with hinge appearing to be open 270 degrees.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -1.0f, 0.01f),
gfx::Vector3dF(0.01f, -1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
gfx::Vector3dF(kMeanGravity, 0.1f, 0.0f));
EXPECT_FALSE(IsMaximizeModeStarted());
// Flat and open 270 degrees should start maximize mode.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f),
gfx::Vector3dF(1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
EXPECT_TRUE(IsMaximizeModeStarted());
// Normal 90 degree orientation but near vertical should stay in maximize
// mode.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -1.0f, 0.01f),
gfx::Vector3dF(-0.01f, -1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, -0.1f),
gfx::Vector3dF(kMeanGravity, -0.1f, 0.0f));
EXPECT_TRUE(IsMaximizeModeStarted());
}
......@@ -299,22 +308,22 @@ TEST_F(MaximizeModeControllerTest, HingeAligned) {
// rotation of the internal display.
TEST_F(MaximizeModeControllerTest, DisplayRotation) {
// Trigger maximize mode by opening to 270.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
// Now test rotating in all directions.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 1.0f, 0.0f),
gfx::Vector3dF(0.0f, 1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f),
gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(1.0f, 0.0f, 0.0f),
gfx::Vector3dF(1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f),
gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -1.0f, 0.0f),
gfx::Vector3dF(0.0f, -1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f),
gfx::Vector3dF(kMeanGravity, 0.0f, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_270, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(-1.0f, 0.0f, 0.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, kMeanGravity, 0.0f),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
}
......@@ -322,24 +331,25 @@ TEST_F(MaximizeModeControllerTest, DisplayRotation) {
// is almost laying flat).
TEST_F(MaximizeModeControllerTest, RotationIgnoresLowAngles) {
// Trigger maximize mode by opening to 270.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
TriggerAccelerometerUpdate(gfx::Vector3dF(-1.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, -1.0f));
TriggerAccelerometerUpdate(
gfx::Vector3dF(0.0f, kMeanGravity, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, -kMeanGravity));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.2f, -1.0f),
gfx::Vector3dF(0.0f, 0.2f, -1.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-2.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(-2.0f, 0.0f, -kMeanGravity));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(0.2f, 0.0f, -1.0f),
gfx::Vector3dF(0.2f, 0.0f, -1.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -2.0f, kMeanGravity),
gfx::Vector3dF(0.0f, 2.0f, -kMeanGravity));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -0.2f, -1.0f),
gfx::Vector3dF(0.0f, -0.2f, -1.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(2.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(2.0f, 0.0f, -kMeanGravity));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(-0.2f, 0.0f, -1.0f),
gfx::Vector3dF(-0.2f, 0.0f, -1.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 2.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -2.0f, -kMeanGravity));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
}
......@@ -347,34 +357,34 @@ TEST_F(MaximizeModeControllerTest, RotationIgnoresLowAngles) {
// halfway point, preventing frequent updates back and forth.
TEST_F(MaximizeModeControllerTest, RotationSticky) {
// Trigger maximize mode by opening to 270.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
gfx::Vector3dF gravity(-1.0f, 0.0f, 0.0f);
gfx::Vector3dF gravity(0.0f, -kMeanGravity, 0.0f);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
// Turn past half-way point to next direction and rotation should remain
// the same.
float degrees = 50.0;
gravity.set_x(-cos(degrees * kDegreesToRadians));
gravity.set_y(sin(degrees * kDegreesToRadians));
gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
// Turn more and the screen should rotate.
degrees = 70.0;
gravity.set_x(-cos(degrees * kDegreesToRadians));
gravity.set_y(sin(degrees * kDegreesToRadians));
gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
// Turn back just beyond the half-way point and the new rotation should
// still be in effect.
degrees = 40.0;
gravity.set_x(-cos(degrees * kDegreesToRadians));
gravity.set_y(sin(degrees * kDegreesToRadians));
gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
}
......@@ -383,20 +393,20 @@ TEST_F(MaximizeModeControllerTest, RotationSticky) {
// return to the standard orientation on exiting maximize mode.
TEST_F(MaximizeModeControllerTest, RotationOnlyInMaximizeMode) {
// Rotate on side with lid only open 90 degrees.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.95f, 0.35f),
gfx::Vector3dF(-0.35f, 0.95f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, -3.5f),
gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
ASSERT_FALSE(IsMaximizeModeStarted());
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
// Open lid, screen should now rotate to match orientation.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.95f, -0.35f),
gfx::Vector3dF(-0.35f, 0.95f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, 3.5f),
gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
// Close lid back to 90, screen should rotate back.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.95f, 0.35f),
gfx::Vector3dF(-0.35f, 0.95f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-9.5f, 0.0f, -3.5f),
gfx::Vector3dF(-9.5f, -3.5f, 0.0f));
ASSERT_FALSE(IsMaximizeModeStarted());
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
}
......@@ -433,15 +443,18 @@ TEST_F(MaximizeModeControllerTest, Screenshot) {
TEST_F(MaximizeModeControllerTest, LaptopTest) {
// Feeds in sample accelerometer data and verifies that there are no
// transitions into touchview / maximize mode while shaking the device around
// with the hinge at less than 180 degrees.
// with the hinge at less than 180 degrees. Note the conversion from device
// data to accelerometer updates consistent with accelerometer_reader.cc.
ASSERT_EQ(0u, kAccelerometerLaptopModeTestDataLength % 6);
for (size_t i = 0; i < kAccelerometerLaptopModeTestDataLength / 6; ++i) {
gfx::Vector3dF base(kAccelerometerLaptopModeTestData[i * 6],
kAccelerometerLaptopModeTestData[i * 6 + 1],
kAccelerometerLaptopModeTestData[i * 6 + 2]);
gfx::Vector3dF lid(kAccelerometerLaptopModeTestData[i * 6 + 3],
kAccelerometerLaptopModeTestData[i * 6 + 4],
gfx::Vector3dF base(-kAccelerometerLaptopModeTestData[i * 6 + 1],
-kAccelerometerLaptopModeTestData[i * 6],
-kAccelerometerLaptopModeTestData[i * 6 + 2]);
base.Scale(kMeanGravity);
gfx::Vector3dF lid(-kAccelerometerLaptopModeTestData[i * 6 + 4],
kAccelerometerLaptopModeTestData[i * 6 + 3],
kAccelerometerLaptopModeTestData[i * 6 + 5]);
lid.Scale(kMeanGravity);
TriggerAccelerometerUpdate(base, lid);
// There are a lot of samples, so ASSERT rather than EXPECT to only generate
// one failure rather than potentially hundreds.
......@@ -451,21 +464,24 @@ TEST_F(MaximizeModeControllerTest, LaptopTest) {
TEST_F(MaximizeModeControllerTest, MaximizeModeTest) {
// Trigger maximize mode by opening to 270 to begin the test in maximize mode.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
// Feeds in sample accelerometer data and verifies that there are no
// transitions out of touchview / maximize mode while shaking the device
// around.
// around. Note the conversion from device data to accelerometer updates
// consistent with accelerometer_reader.cc.
ASSERT_EQ(0u, kAccelerometerFullyOpenTestDataLength % 6);
for (size_t i = 0; i < kAccelerometerFullyOpenTestDataLength / 6; ++i) {
gfx::Vector3dF base(kAccelerometerFullyOpenTestData[i * 6],
kAccelerometerFullyOpenTestData[i * 6 + 1],
kAccelerometerFullyOpenTestData[i * 6 + 2]);
gfx::Vector3dF lid(kAccelerometerFullyOpenTestData[i * 6 + 3],
kAccelerometerFullyOpenTestData[i * 6 + 4],
gfx::Vector3dF base(-kAccelerometerFullyOpenTestData[i * 6 + 1],
-kAccelerometerFullyOpenTestData[i * 6],
-kAccelerometerFullyOpenTestData[i * 6 + 2]);
base.Scale(kMeanGravity);
gfx::Vector3dF lid(-kAccelerometerFullyOpenTestData[i * 6 + 4],
kAccelerometerFullyOpenTestData[i * 6 + 3],
kAccelerometerFullyOpenTestData[i * 6 + 5]);
lid.Scale(kMeanGravity);
TriggerAccelerometerUpdate(base, lid);
// There are a lot of samples, so ASSERT rather than EXPECT to only generate
// one failure rather than potentially hundreds.
......@@ -477,18 +493,18 @@ TEST_F(MaximizeModeControllerTest, MaximizeModeTest) {
// rotation lock has been set.
TEST_F(MaximizeModeControllerTest, RotationLockPreventsRotation) {
// Trigger maximize mode by opening to 270.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
gfx::Vector3dF gravity(-1.0f, 0.0f, 0.0f);
gfx::Vector3dF gravity(-kMeanGravity, 0.0f, 0.0f);
maximize_mode_controller()->SetRotationLocked(true);
// Turn past the threshold for rotation.
float degrees = 90.0;
gravity.set_x(-cos(degrees * kDegreesToRadians));
gravity.set_y(sin(degrees * kDegreesToRadians));
gravity.set_x(-sin(degrees * kDegreesToRadians) * kMeanGravity);
gravity.set_y(-cos(degrees * kDegreesToRadians) * kMeanGravity);
TriggerAccelerometerUpdate(gravity, gravity);
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
......@@ -544,8 +560,8 @@ TEST_F(MaximizeModeControllerTest, BlockRotationNotifications) {
// Clear all notifications
message_center->RemoveAllNotifications(false);
// Trigger maximize mode by opening to 270.
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
EXPECT_TRUE(IsMaximizeModeStarted());
EXPECT_EQ(0u, message_center->NotificationCount());
EXPECT_FALSE(message_center->HasPopupNotifications());
......@@ -568,8 +584,8 @@ TEST_F(MaximizeModeControllerTest, BlockRotationNotifications) {
// via the accelerometer while in maximize mode
// Rotate the screen 90 degrees
ASSERT_NE(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 1.0f, 0.0f),
gfx::Vector3dF(0.0f, 1.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f),
gfx::Vector3dF(-kMeanGravity, 0.0f, 0.0f));
ASSERT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
EXPECT_EQ(0u, message_center->NotificationCount());
EXPECT_FALSE(message_center->HasPopupNotifications());
......@@ -584,17 +600,17 @@ TEST_F(MaximizeModeControllerTest, ResetUserRotationUponExit) {
gfx::Display::ROTATE_90);
// Trigger maximize mode
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_TRUE(IsMaximizeModeStarted());
TriggerAccelerometerUpdate(gfx::Vector3dF(1.0f, 0.0f, 0.0f),
gfx::Vector3dF(1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f),
gfx::Vector3dF(0.0f, kMeanGravity, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_180, GetInternalDisplayRotation());
// Exit maximize mode
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
EXPECT_FALSE(IsMaximizeModeStarted());
EXPECT_EQ(gfx::Display::ROTATE_90, GetInternalDisplayRotation());
}
......@@ -604,8 +620,8 @@ TEST_F(MaximizeModeControllerTest, ResetUserRotationUponExit) {
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));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
ASSERT_FALSE(maximize_mode_controller()->rotation_locked());
SetInternalDisplayRotation(gfx::Display::ROTATE_270);
EXPECT_TRUE(maximize_mode_controller()->rotation_locked());
......@@ -616,15 +632,15 @@ TEST_F(MaximizeModeControllerTest,
// 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));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 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));
TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -kMeanGravity),
gfx::Vector3dF(0.0f, -kMeanGravity, 0.0f));
EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation());
}
......
......@@ -38,6 +38,9 @@ const char kMirroredKey[] = "mirrored";
const char kPositionKey[] = "position";
const char kOffsetKey[] = "offset";
// The mean acceleration due to gravity on Earth in m/s^2.
const float kMeanGravity = 9.80665f;
class DisplayPreferencesTest : public ash::test::AshTestBase {
protected:
DisplayPreferencesTest()
......@@ -663,13 +666,20 @@ TEST_F(DisplayPreferencesTest, DontSaveMaximizeModeControllerRotations) {
gfx::Display::ROTATE_0);
// Open up 270 degrees to trigger maximize mode
controller->OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
ui::AccelerometerUpdate update;
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
0.0f, 0.0f, kMeanGravity);
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
0.0f, -kMeanGravity, 0.0f);
controller->OnAccelerometerUpdated(update);
EXPECT_TRUE(controller->IsMaximizeModeWindowManagerEnabled());
// Trigger 90 degree rotation
controller->OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 1.0f, 0.0f),
gfx::Vector3dF(0.0f, 1.0f, 0.0f));
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
-kMeanGravity, 0.0f, 0.0f);
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
-kMeanGravity, 0.0f, 0.0f);
controller->OnAccelerometerUpdated(update);
EXPECT_EQ(gfx::Display::ROTATE_90, display_manager->
GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation());
......@@ -799,9 +809,12 @@ TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) {
EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation);
// Open up 270 degrees to trigger maximize mode
maximize_mode_controller->
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
ui::AccelerometerUpdate update;
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
0.0f, 0.0f, kMeanGravity);
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
0.0f, -kMeanGravity, 0.0f);
maximize_mode_controller->OnAccelerometerUpdated(update);
EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
bool maximize_mode_rotation_lock =
maximize_mode_controller->rotation_locked();
......@@ -826,16 +839,21 @@ TEST_F(DisplayPreferencesTest, LoadRotationIgnoredInNormalMode) {
ash::MaximizeModeController* maximize_mode_controller =
ash::Shell::GetInstance()->maximize_mode_controller();
// Lid open to 90 degrees
maximize_mode_controller->
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, 1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
ui::AccelerometerUpdate update;
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
-kMeanGravity, 0.0f, 0.0f);
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
-kMeanGravity, 0.0f, 0.0f);
maximize_mode_controller->OnAccelerometerUpdated(update);
EXPECT_FALSE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
EXPECT_FALSE(maximize_mode_controller->rotation_locked());
// Open up 270 degrees to trigger maximize mode
maximize_mode_controller->
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f),
gfx::Vector3dF(-1.0f, 0.0f, 0.0f));
update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
0.0f, 0.0f, kMeanGravity);
update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
0.0f, -kMeanGravity, 0.0f);
maximize_mode_controller->OnAccelerometerUpdated(update);
EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
EXPECT_FALSE(maximize_mode_controller->rotation_locked());
}
......
......@@ -500,6 +500,7 @@
'../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc',
'../third_party/libxml/libxml.gyp:libxml',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/base/ui_base.gyp:ui_base_test_support',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/resources/ui_resources.gyp:ui_resources',
......
......@@ -5,6 +5,6 @@ include_rules = [
"+third_party/cros_system_api",
"+third_party/libxml",
"+third_party/protobuf",
"+ui/gfx/geometry",
"+ui/accelerometer",
"+ui/gfx/x"
]
......@@ -52,6 +52,9 @@ const size_t kMaxAsciiUintLength = 21;
// The time to wait between reading the accelerometer.
const int kDelayBetweenReadsMs = 100;
// The mean acceleration due to gravity on Earth in m/s^2.
const float kMeanGravity = 9.80665f;
// Reads |path| to the unsigned int pointed to by |value|. Returns true on
// success or false on failure.
bool ReadFileToUint(const base::FilePath& path, unsigned int* value) {
......@@ -193,18 +196,18 @@ void AccelerometerReader::OnDataRead(
DCHECK(!task_runner_->RunsTasksOnCurrentThread());
if (success) {
gfx::Vector3dF base_reading, lid_reading;
int16* values = reinterpret_cast<int16*>(reading->data);
base_reading.set_x(values[configuration_->data.index[0]]);
base_reading.set_y(values[configuration_->data.index[1]]);
base_reading.set_z(values[configuration_->data.index[2]]);
base_reading.Scale(1.0f / configuration_->data.base_scale);
lid_reading.set_x(values[configuration_->data.index[3]]);
lid_reading.set_y(values[configuration_->data.index[4]]);
lid_reading.set_z(values[configuration_->data.index[5]]);
lid_reading.Scale(1.0f / configuration_->data.lid_scale);
delegate_->HandleAccelerometerReading(base_reading, lid_reading);
float lid_scale = kMeanGravity / configuration_->data.lid_scale;
update_.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
-values[configuration_->data.index[4]] * lid_scale,
values[configuration_->data.index[3]] * lid_scale,
values[configuration_->data.index[5]] * lid_scale);
float base_scale = kMeanGravity / configuration_->data.base_scale;
update_.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
-values[configuration_->data.index[1]] * base_scale,
-values[configuration_->data.index[0]] * base_scale,
-values[configuration_->data.index[2]] * base_scale);
delegate_->HandleAccelerometerUpdate(update_);
}
// Trigger another read after the current sampling delay.
......
......@@ -11,7 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "ui/gfx/geometry/vector3d_f.h"
#include "ui/accelerometer/accelerometer_types.h"
namespace base {
class TaskRunner;
......@@ -41,8 +41,8 @@ class CHROMEOS_EXPORT AccelerometerReader {
// An interface to receive data from the AccelerometerReader.
class Delegate {
public:
virtual void HandleAccelerometerReading(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) = 0;
virtual void HandleAccelerometerUpdate(
const ui::AccelerometerUpdate& update) = 0;
};
AccelerometerReader(base::TaskRunner* blocking_task_runner,
......@@ -58,8 +58,8 @@ class CHROMEOS_EXPORT AccelerometerReader {
// OnDataRead with the result.
void TriggerRead();
// If |success|, converts the raw reading to a pair of Vector3dF
// values and notifies the |delegate_| with the new readings.
// If |success|, converts the raw reading to an AccelerometerUpdate
// message and notifies the |delegate_| with the new readings.
// Triggers another read from the accelerometer at the current sampling rate.
void OnDataRead(scoped_refptr<Reading> reading, bool success);
......@@ -69,6 +69,9 @@ class CHROMEOS_EXPORT AccelerometerReader {
// A weak pointer to the delegate to send accelerometer readings to.
Delegate* delegate_;
// The last seen accelerometer data.
ui::AccelerometerUpdate update_;
// The accelerometer configuration.
scoped_refptr<Configuration> configuration_;
......
......@@ -28,7 +28,7 @@
'../third_party/icu/icu.gyp:icui18n',
'../third_party/libxml/libxml.gyp:libxml',
'../third_party/protobuf/protobuf.gyp:protobuf_lite',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../url/url.gyp:url_lib',
'cryptohome_proto',
'ime/input_method.gyp:gencode',
......
# 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.
import("//build/config/ui.gni")
component("accelerometer") {
output_name = "ui_accelerometer"
sources = [
"accelerometer_types.cc",
"accelerometer_types.h",
"ui_accelerometer_export.h",
]
defines = [ "UI_ACCELEROMETER_IMPLEMENTATION" ]
deps = [
"//ui/gfx/geometry",
]
}
include_rules = [
"+ui/gfx/geometry/vector3d_f.h"
]
// 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 "ui/accelerometer/accelerometer_types.h"
namespace ui {
AccelerometerReading::AccelerometerReading() : present(false) {
}
AccelerometerReading::~AccelerometerReading() {
}
AccelerometerUpdate::AccelerometerUpdate() {
}
AccelerometerUpdate::~AccelerometerUpdate() {
}
} // namespace ui
// 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.
#ifndef UI_ACCEROMETER_ACCELEROMETER_TYPES_H_
#define UI_ACCEROMETER_ACCELEROMETER_TYPES_H_
#include "base/macros.h"
#include "ui/accelerometer/ui_accelerometer_export.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace ui {
enum AccelerometerSource {
// Accelerometer is located in the device's screen. In the screen's natural
// orientation, positive X points to the right, consistent with the pixel
// position. Positive Y points up the screen. Positive Z is perpendicular to
// the screen, pointing outwards towards the user. The orientation is
// described at:
// http://www.html5rocks.com/en/tutorials/device/orientation/.
ACCELEROMETER_SOURCE_SCREEN = 0,
// Accelerometer is located in a keyboard attached to the device's screen.
// If the device is open 180 degrees the orientation is consistent with the
// screen. I.e. Positive X points to the right, positive Y points up on the
// keyboard and positive Z is perpendicular to the keyboard pointing out
// towards the user.
ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
ACCELEROMETER_SOURCE_COUNT
};
struct UI_ACCELEROMETER_EXPORT AccelerometerReading {
AccelerometerReading();
~AccelerometerReading();
// If true, this accelerometer is being updated.
bool present;
// The reading from this accelerometer measured in m/s^2.
gfx::Vector3dF reading;
};
// An accelerometer update contains the last known value for each of the
// accelerometers present on the device.
class UI_ACCELEROMETER_EXPORT AccelerometerUpdate {
public:
AccelerometerUpdate();
~AccelerometerUpdate();
// Returns true if |source| has a valid value in this update.
bool has(AccelerometerSource source) const {
return data_[source].present;
}
// Returns the last known value for |source|.
const gfx::Vector3dF& get(AccelerometerSource source) const {
return data_[source].reading;
}
void Set(AccelerometerSource source, float x, float y, float z) {
data_[source].present = true;
data_[source].reading.set_x(x);
data_[source].reading.set_y(y);
data_[source].reading.set_z(z);
}
protected:
AccelerometerReading data_[ACCELEROMETER_SOURCE_COUNT];
DISALLOW_COPY_AND_ASSIGN(AccelerometerUpdate);
};
} // namespace chromeos
#endif // UI_ACCEROMETER_ACCELEROMETER_TYPES_H_
# 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.
{
'variables': {
'chromium_code': 1,
},
'targets': [
{
# GN version: //ui/accelerometer
'target_name': 'ui_accelerometer',
'type': '<(component)',
'dependencies': [
'../gfx/gfx.gyp:gfx_geometry',
],
'defines': [
'UI_ACCELEROMETER_IMPLEMENTATION',
],
'sources' : [
'accelerometer_types.cc',
'accelerometer_types.h',
'ui_accelerometer_export.h',
],
'include_dirs': [
'../..',
],
},
],
}
// 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.
#ifndef UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_
#define UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_
// Defines UI_ACCELEROMETER_EXPORT so that functionality implemented by the UI
// accelerometer module can be exported to consumers.
#if defined(COMPONENT_BUILD)
#if defined(WIN32)
#if defined(UI_ACCELEROMETER_IMPLEMENTATION)
#define UI_ACCELEROMETER_EXPORT __declspec(dllexport)
#else
#define UI_ACCELEROMETER_EXPORT __declspec(dllimport)
#endif
#else // !defined(WIN32)
#if defined(UI_ACCELEROMETER_IMPLEMENTATION)
#define UI_ACCELEROMETER_EXPORT __attribute__((visibility("default")))
#else
#define UI_ACCELEROMETER_EXPORT
#endif
#endif
#else // !defined(COMPONENT_BUILD)
#define UI_ACCELEROMETER_EXPORT
#endif
#endif // UI_ACCELEROMETER_UI_ACCELEROMETER_EXPORT_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment