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") { ...@@ -29,6 +29,7 @@ component("ash") {
"//net", "//net",
"//skia", "//skia",
"//third_party/icu", "//third_party/icu",
"//ui/accelerometer",
"//ui/accessibility", "//ui/accessibility",
"//ui/app_list", "//ui/app_list",
"//ui/aura", "//ui/aura",
...@@ -251,6 +252,7 @@ test("ash_unittests") { ...@@ -251,6 +252,7 @@ test("ash_unittests") {
"//skia", "//skia",
"//testing/gtest", "//testing/gtest",
"//third_party/icu", "//third_party/icu",
"//ui/accelerometer",
"//ui/accessibility", "//ui/accessibility",
"//ui/aura", "//ui/aura",
"//ui/aura:test_support", "//ui/aura:test_support",
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "ash/accelerometer/accelerometer_controller.h" #include "ash/accelerometer/accelerometer_controller.h"
#include "ash/accelerometer/accelerometer_observer.h" #include "ash/accelerometer/accelerometer_observer.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace ash { namespace ash {
...@@ -31,11 +30,10 @@ void AccelerometerController::RemoveObserver(AccelerometerObserver* observer) { ...@@ -31,11 +30,10 @@ void AccelerometerController::RemoveObserver(AccelerometerObserver* observer) {
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void AccelerometerController::HandleAccelerometerReading( void AccelerometerController::HandleAccelerometerUpdate(
const gfx::Vector3dF& base, const ui::AccelerometerUpdate& update) {
const gfx::Vector3dF& lid) {
FOR_EACH_OBSERVER(AccelerometerObserver, observers_, FOR_EACH_OBSERVER(AccelerometerObserver, observers_,
OnAccelerometerUpdated(base, lid)); OnAccelerometerUpdated(update));
} }
#endif #endif
......
...@@ -18,10 +18,6 @@ namespace base { ...@@ -18,10 +18,6 @@ namespace base {
class TaskRunner; class TaskRunner;
} }
namespace gfx {
class Vector3dF;
}
namespace ash { namespace ash {
class AccelerometerObserver; class AccelerometerObserver;
...@@ -50,8 +46,8 @@ class ASH_EXPORT AccelerometerController ...@@ -50,8 +46,8 @@ class ASH_EXPORT AccelerometerController
// This needs to be CHROMEOS only as on other platforms it does not actually // This needs to be CHROMEOS only as on other platforms it does not actually
// override a method. // override a method.
// chromeos::AccelerometerReader::Delegate: // chromeos::AccelerometerReader::Delegate:
virtual void HandleAccelerometerReading(const gfx::Vector3dF& base, virtual void HandleAccelerometerUpdate(
const gfx::Vector3dF& lid) OVERRIDE; const ui::AccelerometerUpdate& update) OVERRIDE;
#endif #endif
private: private:
......
...@@ -6,20 +6,17 @@ ...@@ -6,20 +6,17 @@
#define ASH_ACCELEROMETER_ACCELEROMETER_OBSERVER_H_ #define ASH_ACCELEROMETER_ACCELEROMETER_OBSERVER_H_
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ui/accelerometer/accelerometer_types.h"
namespace gfx {
class Vector3dF;
}
namespace ash { namespace ash {
// The interface for classes which observe accelerometer updates. // The interface for classes which observe accelerometer updates.
class ASH_EXPORT AccelerometerObserver { class ASH_EXPORT AccelerometerObserver {
public: public:
// Invoked when an accelerometer reading has been taken. The |base| and |lid| // Invoked when an accelerometer reading has been taken. The |update| can
// accelerometer readings are in G's. // contain readings from one or more AccelerometerSources.
virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base, virtual void OnAccelerometerUpdated(
const gfx::Vector3dF& lid) = 0; const ui::AccelerometerUpdate& update) = 0;
protected: protected:
virtual ~AccelerometerObserver() {} virtual ~AccelerometerObserver() {}
......
...@@ -894,6 +894,7 @@ ...@@ -894,6 +894,7 @@
'../skia/skia.gyp:skia', '../skia/skia.gyp:skia',
'../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc', '../third_party/icu/icu.gyp:icuuc',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/accessibility/accessibility.gyp:accessibility', '../ui/accessibility/accessibility.gyp:accessibility',
'../ui/app_list/app_list.gyp:app_list', '../ui/app_list/app_list.gyp:app_list',
'../ui/aura/aura.gyp:aura', '../ui/aura/aura.gyp:aura',
...@@ -1065,6 +1066,7 @@ ...@@ -1065,6 +1066,7 @@
'../testing/gtest.gyp:gtest', '../testing/gtest.gyp:gtest',
'../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc', '../third_party/icu/icu.gyp:icuuc',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/accessibility/accessibility.gyp:accessibility', '../ui/accessibility/accessibility.gyp:accessibility',
'../ui/app_list/app_list.gyp:app_list', '../ui/app_list/app_list.gyp:app_list',
'../ui/aura/aura.gyp:aura', '../ui/aura/aura.gyp:aura',
......
...@@ -56,34 +56,37 @@ const float kMaxStableAngle = 340.0f; ...@@ -56,34 +56,37 @@ const float kMaxStableAngle = 340.0f;
const base::TimeDelta kLidRecentlyOpenedDuration = const base::TimeDelta kLidRecentlyOpenedDuration =
base::TimeDelta::FromSeconds(2); 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) // When the device approaches vertical orientation (i.e. portrait orientation)
// the accelerometers for the base and lid approach the same values (i.e. // 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 // gravity pointing in the direction of the hinge). When this happens we cannot
// compute the hinge angle reliably and must turn ignore accelerometer readings. // compute the hinge angle reliably and must turn ignore accelerometer readings.
// This is the minimum acceleration perpendicular to the hinge under which to // This is the minimum acceleration perpendicular to the hinge under which to
// detect hinge angle. // detect hinge angle in m/s^2.
const float kHingeAngleDetectionThreshold = 0.25f; const float kHingeAngleDetectionThreshold = 2.5f;
// The maximum deviation from the acceleration expected due to gravity under // The maximum deviation from the acceleration expected due to gravity under
// which to detect hinge angle and screen rotation. // which to detect hinge angle and screen rotation in m/s^2
const float kDeviationFromGravityThreshold = 0.1f; const float kDeviationFromGravityThreshold = 1.0f;
// The maximum deviation between the magnitude of the two accelerometers under // The maximum deviation between the magnitude of the two accelerometers under
// which to detect hinge angle and screen rotation. These accelerometers are // which to detect hinge angle and screen rotation in m/s^2. These
// attached to the same physical device and so should be under the same // accelerometers are attached to the same physical device and so should be
// acceleration. // under the same acceleration.
const float kNoisyMagnitudeDeviation = 0.1f; const float kNoisyMagnitudeDeviation = 1.0f;
// The angle which the screen has to be rotated past before the display will // 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). // rotate to match it (i.e. 45.0f is no stickiness).
const float kDisplayRotationStickyAngleDegrees = 60.0f; const float kDisplayRotationStickyAngleDegrees = 60.0f;
// The minimum acceleration in a direction required to trigger screen rotation. // The minimum acceleration in m/s^2 in a direction required to trigger screen
// This prevents rapid toggling of rotation when the device is near flat and // rotation. This prevents rapid toggling of rotation when the device is near
// there is very little screen aligned force on it. The value is effectively the // flat and there is very little screen aligned force on it. The value is
// sine of the rise angle required, with the current value requiring at least a // effectively the sine of the rise angle required times the acceleration due
// 25 degree rise. // to gravity, with the current value requiring at least a 25 degree rise.
const float kMinimumAccelerationScreenRotation = 0.42f; const float kMinimumAccelerationScreenRotation = 4.2f;
const float kRadiansToDegrees = 180.0f / 3.14159265f; const float kRadiansToDegrees = 180.0f / 3.14159265f;
...@@ -236,26 +239,35 @@ void MaximizeModeController::Shutdown() { ...@@ -236,26 +239,35 @@ void MaximizeModeController::Shutdown() {
} }
void MaximizeModeController::OnAccelerometerUpdated( void MaximizeModeController::OnAccelerometerUpdated(
const gfx::Vector3dF& base, const ui::AccelerometerUpdate& update) {
const gfx::Vector3dF& lid) {
bool first_accelerometer_update = !have_seen_accelerometer_data_; bool first_accelerometer_update = !have_seen_accelerometer_data_;
have_seen_accelerometer_data_ = true; have_seen_accelerometer_data_ = true;
// Ignore the reading if it appears unstable. The reading is considered // 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 // 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. // reading from the lid differs too much from the reading from the base.
float base_magnitude = base.Length(); float base_magnitude =
float lid_magnitude = lid.Length(); update.has(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD) ?
if (std::abs(base_magnitude - lid_magnitude) > kNoisyMagnitudeDeviation || update.get(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD).Length() :
std::abs(base_magnitude - 1.0f) > kDeviationFromGravityThreshold || 0.0f;
std::abs(lid_magnitude - 1.0f) > kDeviationFromGravityThreshold) { float lid_magnitude = update.has(ui::ACCELEROMETER_SOURCE_SCREEN) ?
return; 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));
} }
if (lid_stable)
// Responding to the hinge rotation can change the maximize mode state which HandleScreenRotation(update.get(ui::ACCELEROMETER_SOURCE_SCREEN));
// affects screen rotation, so we handle hinge rotation first.
HandleHingeRotation(base, lid);
HandleScreenRotation(lid);
if (first_accelerometer_update) { if (first_accelerometer_update) {
// On the first accelerometer update we will know if we have entered // On the first accelerometer update we will know if we have entered
...@@ -303,14 +315,14 @@ void MaximizeModeController::SuspendDone( ...@@ -303,14 +315,14 @@ void MaximizeModeController::SuspendDone(
void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
const gfx::Vector3dF& lid) { 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(); bool maximize_mode_engaged = IsMaximizeModeWindowManagerEnabled();
// Ignore the component of acceleration parallel to the hinge for the purposes // Ignore the component of acceleration parallel to the hinge for the purposes
// of hinge angle calculation. // of hinge angle calculation.
gfx::Vector3dF base_flattened(base); gfx::Vector3dF base_flattened(base);
gfx::Vector3dF lid_flattened(lid); gfx::Vector3dF lid_flattened(lid);
base_flattened.set_y(0.0f); base_flattened.set_x(0.0f);
lid_flattened.set_y(0.0f); lid_flattened.set_x(0.0f);
// As the hinge approaches a vertical angle, the base and lid accelerometers // As the hinge approaches a vertical angle, the base and lid accelerometers
// approach the same values making any angle calculations highly inaccurate. // approach the same values making any angle calculations highly inaccurate.
...@@ -321,10 +333,13 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base, ...@@ -321,10 +333,13 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
} }
// Compute the angle between the base and the lid. // Compute the angle between the base and the lid.
float angle = ClockwiseAngleBetweenVectorsInDegrees(base_flattened, float lid_angle = 180.0f - ClockwiseAngleBetweenVectorsInDegrees(
lid_flattened, hinge_vector); 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 // 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 // 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, ...@@ -337,10 +352,10 @@ void MaximizeModeController::HandleHingeRotation(const gfx::Vector3dF& base,
// such that observations of state changes occur after the change and shell // such that observations of state changes occur after the change and shell
// has fewer states to track. // has fewer states to track.
if (maximize_mode_engaged && is_angle_stable && if (maximize_mode_engaged && is_angle_stable &&
angle < kExitMaximizeModeAngle) { lid_angle <= kExitMaximizeModeAngle) {
LeaveMaximizeMode(); LeaveMaximizeMode();
} else if (!lid_is_closed_ && !maximize_mode_engaged && } else if (!lid_is_closed_ && !maximize_mode_engaged &&
angle > kEnterMaximizeModeAngle && lid_angle >= kEnterMaximizeModeAngle &&
(is_angle_stable || !WasLidOpenedRecently())) { (is_angle_stable || !WasLidOpenedRecently())) {
EnterMaximizeMode(); EnterMaximizeMode();
} }
...@@ -372,7 +387,7 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) { ...@@ -372,7 +387,7 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) {
// The reference vector is the angle of gravity when the device is rotated // The reference vector is the angle of gravity when the device is rotated
// clockwise by 45 degrees. Computing the angle between this vector and // clockwise by 45 degrees. Computing the angle between this vector and
// gravity we can easily determine the expected display rotation. // 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 // 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 // last configured rotation. This is used to enforce a stickiness that the
...@@ -380,13 +395,13 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) { ...@@ -380,13 +395,13 @@ void MaximizeModeController::HandleScreenRotation(const gfx::Vector3dF& lid) {
// when holding the device near 45 degrees. // when holding the device near 45 degrees.
gfx::Vector3dF down(0.0f, 0.0f, 0.0f); gfx::Vector3dF down(0.0f, 0.0f, 0.0f);
if (current_rotation == gfx::Display::ROTATE_0) 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) 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) else if (current_rotation == gfx::Display::ROTATE_180)
down.set_x(1.0f); down.set_y(1.0f);
else else
down.set_y(-1.0f); down.set_x(1.0f);
// Don't rotate if the screen has not passed the threshold. // Don't rotate if the screen has not passed the threshold.
if (AngleBetweenVectorsInDegrees(down, lid_flattened) < if (AngleBetweenVectorsInDegrees(down, lid_flattened) <
......
...@@ -109,8 +109,8 @@ class ASH_EXPORT MaximizeModeController ...@@ -109,8 +109,8 @@ class ASH_EXPORT MaximizeModeController
void Shutdown(); void Shutdown();
// AccelerometerObserver: // AccelerometerObserver:
virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base, virtual void OnAccelerometerUpdated(
const gfx::Vector3dF& lid) OVERRIDE; const ui::AccelerometerUpdate& update) OVERRIDE;
// ShellObserver: // ShellObserver:
virtual void OnAppTerminating() OVERRIDE; virtual void OnAppTerminating() OVERRIDE;
......
...@@ -38,6 +38,9 @@ const char kMirroredKey[] = "mirrored"; ...@@ -38,6 +38,9 @@ const char kMirroredKey[] = "mirrored";
const char kPositionKey[] = "position"; const char kPositionKey[] = "position";
const char kOffsetKey[] = "offset"; 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 { class DisplayPreferencesTest : public ash::test::AshTestBase {
protected: protected:
DisplayPreferencesTest() DisplayPreferencesTest()
...@@ -663,13 +666,20 @@ TEST_F(DisplayPreferencesTest, DontSaveMaximizeModeControllerRotations) { ...@@ -663,13 +666,20 @@ TEST_F(DisplayPreferencesTest, DontSaveMaximizeModeControllerRotations) {
gfx::Display::ROTATE_0); gfx::Display::ROTATE_0);
// Open up 270 degrees to trigger maximize mode // Open up 270 degrees to trigger maximize mode
controller->OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f), ui::AccelerometerUpdate update;
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);
controller->OnAccelerometerUpdated(update);
EXPECT_TRUE(controller->IsMaximizeModeWindowManagerEnabled()); EXPECT_TRUE(controller->IsMaximizeModeWindowManagerEnabled());
// Trigger 90 degree rotation // Trigger 90 degree rotation
controller->OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 1.0f, 0.0f), update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
gfx::Vector3dF(0.0f, 1.0f, 0.0f)); -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-> EXPECT_EQ(gfx::Display::ROTATE_90, display_manager->
GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation()); GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation());
...@@ -799,9 +809,12 @@ TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) { ...@@ -799,9 +809,12 @@ TEST_F(DisplayPreferencesTest, LoadRotationNoLogin) {
EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation); EXPECT_EQ(gfx::Display::ROTATE_0, before_maximize_mode_rotation);
// Open up 270 degrees to trigger maximize mode // Open up 270 degrees to trigger maximize mode
maximize_mode_controller-> ui::AccelerometerUpdate update;
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f), update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); 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_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
bool maximize_mode_rotation_lock = bool maximize_mode_rotation_lock =
maximize_mode_controller->rotation_locked(); maximize_mode_controller->rotation_locked();
...@@ -826,16 +839,21 @@ TEST_F(DisplayPreferencesTest, LoadRotationIgnoredInNormalMode) { ...@@ -826,16 +839,21 @@ TEST_F(DisplayPreferencesTest, LoadRotationIgnoredInNormalMode) {
ash::MaximizeModeController* maximize_mode_controller = ash::MaximizeModeController* maximize_mode_controller =
ash::Shell::GetInstance()->maximize_mode_controller(); ash::Shell::GetInstance()->maximize_mode_controller();
// Lid open to 90 degrees // Lid open to 90 degrees
maximize_mode_controller-> ui::AccelerometerUpdate update;
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, 1.0f), update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); -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->IsMaximizeModeWindowManagerEnabled());
EXPECT_FALSE(maximize_mode_controller->rotation_locked()); EXPECT_FALSE(maximize_mode_controller->rotation_locked());
// Open up 270 degrees to trigger maximize mode // Open up 270 degrees to trigger maximize mode
maximize_mode_controller-> update.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
OnAccelerometerUpdated(gfx::Vector3dF(0.0f, 0.0f, -1.0f), 0.0f, 0.0f, kMeanGravity);
gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); update.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
0.0f, -kMeanGravity, 0.0f);
maximize_mode_controller->OnAccelerometerUpdated(update);
EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled()); EXPECT_TRUE(maximize_mode_controller->IsMaximizeModeWindowManagerEnabled());
EXPECT_FALSE(maximize_mode_controller->rotation_locked()); EXPECT_FALSE(maximize_mode_controller->rotation_locked());
} }
......
...@@ -500,6 +500,7 @@ ...@@ -500,6 +500,7 @@
'../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icui18n',
'../third_party/icu/icu.gyp:icuuc', '../third_party/icu/icu.gyp:icuuc',
'../third_party/libxml/libxml.gyp:libxml', '../third_party/libxml/libxml.gyp:libxml',
'../ui/accelerometer/ui_accelerometer.gyp:ui_accelerometer',
'../ui/base/ui_base.gyp:ui_base_test_support', '../ui/base/ui_base.gyp:ui_base_test_support',
'../ui/gfx/gfx.gyp:gfx_test_support', '../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/resources/ui_resources.gyp:ui_resources', '../ui/resources/ui_resources.gyp:ui_resources',
......
...@@ -5,6 +5,6 @@ include_rules = [ ...@@ -5,6 +5,6 @@ include_rules = [
"+third_party/cros_system_api", "+third_party/cros_system_api",
"+third_party/libxml", "+third_party/libxml",
"+third_party/protobuf", "+third_party/protobuf",
"+ui/gfx/geometry", "+ui/accelerometer",
"+ui/gfx/x" "+ui/gfx/x"
] ]
...@@ -52,6 +52,9 @@ const size_t kMaxAsciiUintLength = 21; ...@@ -52,6 +52,9 @@ const size_t kMaxAsciiUintLength = 21;
// The time to wait between reading the accelerometer. // The time to wait between reading the accelerometer.
const int kDelayBetweenReadsMs = 100; 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 // Reads |path| to the unsigned int pointed to by |value|. Returns true on
// success or false on failure. // success or false on failure.
bool ReadFileToUint(const base::FilePath& path, unsigned int* value) { bool ReadFileToUint(const base::FilePath& path, unsigned int* value) {
...@@ -193,18 +196,18 @@ void AccelerometerReader::OnDataRead( ...@@ -193,18 +196,18 @@ void AccelerometerReader::OnDataRead(
DCHECK(!task_runner_->RunsTasksOnCurrentThread()); DCHECK(!task_runner_->RunsTasksOnCurrentThread());
if (success) { if (success) {
gfx::Vector3dF base_reading, lid_reading;
int16* values = reinterpret_cast<int16*>(reading->data); int16* values = reinterpret_cast<int16*>(reading->data);
base_reading.set_x(values[configuration_->data.index[0]]); float lid_scale = kMeanGravity / configuration_->data.lid_scale;
base_reading.set_y(values[configuration_->data.index[1]]); update_.Set(ui::ACCELEROMETER_SOURCE_SCREEN,
base_reading.set_z(values[configuration_->data.index[2]]); -values[configuration_->data.index[4]] * lid_scale,
base_reading.Scale(1.0f / configuration_->data.base_scale); values[configuration_->data.index[3]] * lid_scale,
values[configuration_->data.index[5]] * lid_scale);
lid_reading.set_x(values[configuration_->data.index[3]]); float base_scale = kMeanGravity / configuration_->data.base_scale;
lid_reading.set_y(values[configuration_->data.index[4]]); update_.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD,
lid_reading.set_z(values[configuration_->data.index[5]]); -values[configuration_->data.index[1]] * base_scale,
lid_reading.Scale(1.0f / configuration_->data.lid_scale); -values[configuration_->data.index[0]] * base_scale,
delegate_->HandleAccelerometerReading(base_reading, lid_reading); -values[configuration_->data.index[2]] * base_scale);
delegate_->HandleAccelerometerUpdate(update_);
} }
// Trigger another read after the current sampling delay. // Trigger another read after the current sampling delay.
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "ui/gfx/geometry/vector3d_f.h" #include "ui/accelerometer/accelerometer_types.h"
namespace base { namespace base {
class TaskRunner; class TaskRunner;
...@@ -41,8 +41,8 @@ class CHROMEOS_EXPORT AccelerometerReader { ...@@ -41,8 +41,8 @@ class CHROMEOS_EXPORT AccelerometerReader {
// An interface to receive data from the AccelerometerReader. // An interface to receive data from the AccelerometerReader.
class Delegate { class Delegate {
public: public:
virtual void HandleAccelerometerReading(const gfx::Vector3dF& base, virtual void HandleAccelerometerUpdate(
const gfx::Vector3dF& lid) = 0; const ui::AccelerometerUpdate& update) = 0;
}; };
AccelerometerReader(base::TaskRunner* blocking_task_runner, AccelerometerReader(base::TaskRunner* blocking_task_runner,
...@@ -58,8 +58,8 @@ class CHROMEOS_EXPORT AccelerometerReader { ...@@ -58,8 +58,8 @@ class CHROMEOS_EXPORT AccelerometerReader {
// OnDataRead with the result. // OnDataRead with the result.
void TriggerRead(); void TriggerRead();
// If |success|, converts the raw reading to a pair of Vector3dF // If |success|, converts the raw reading to an AccelerometerUpdate
// values and notifies the |delegate_| with the new readings. // message and notifies the |delegate_| with the new readings.
// Triggers another read from the accelerometer at the current sampling rate. // Triggers another read from the accelerometer at the current sampling rate.
void OnDataRead(scoped_refptr<Reading> reading, bool success); void OnDataRead(scoped_refptr<Reading> reading, bool success);
...@@ -69,6 +69,9 @@ class CHROMEOS_EXPORT AccelerometerReader { ...@@ -69,6 +69,9 @@ class CHROMEOS_EXPORT AccelerometerReader {
// A weak pointer to the delegate to send accelerometer readings to. // A weak pointer to the delegate to send accelerometer readings to.
Delegate* delegate_; Delegate* delegate_;
// The last seen accelerometer data.
ui::AccelerometerUpdate update_;
// The accelerometer configuration. // The accelerometer configuration.
scoped_refptr<Configuration> configuration_; scoped_refptr<Configuration> configuration_;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
'../third_party/icu/icu.gyp:icui18n', '../third_party/icu/icu.gyp:icui18n',
'../third_party/libxml/libxml.gyp:libxml', '../third_party/libxml/libxml.gyp:libxml',
'../third_party/protobuf/protobuf.gyp:protobuf_lite', '../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', '../url/url.gyp:url_lib',
'cryptohome_proto', 'cryptohome_proto',
'ime/input_method.gyp:gencode', '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