1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/device_sensors/sensor_manager_chromeos.h"
9 #include "base/logging.h"
10 #include "chromeos/accelerometer/accelerometer_reader.h"
11 #include "chromeos/accelerometer/accelerometer_types.h"
12 #include "ui/gfx/geometry/vector3d_f.h"
15 // Conversion ratio from radians to degrees.
16 const double kRad2deg
= 180.0 / M_PI
;
21 SensorManagerChromeOS::SensorManagerChromeOS() : orientation_buffer_(nullptr) {
24 SensorManagerChromeOS::~SensorManagerChromeOS() {
27 bool SensorManagerChromeOS::StartFetchingDeviceOrientationData(
28 DeviceOrientationHardwareBuffer
* buffer
) {
31 base::AutoLock
autolock(orientation_buffer_lock_
);
32 if (orientation_buffer_
)
34 orientation_buffer_
= buffer
;
36 // No compass information, so we cannot provide absolute orientation.
37 orientation_buffer_
->seqlock
.WriteBegin();
38 orientation_buffer_
->data
.absolute
= false;
39 orientation_buffer_
->data
.hasAbsolute
= true;
40 orientation_buffer_
->seqlock
.WriteEnd();
43 StartObservingAccelerometer();
47 bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() {
49 base::AutoLock
autolock(orientation_buffer_lock_
);
50 if (!orientation_buffer_
)
52 // Make sure to indicate that the sensor data is no longer available.
53 orientation_buffer_
->seqlock
.WriteBegin();
54 orientation_buffer_
->data
.allAvailableSensorsAreActive
= false;
55 orientation_buffer_
->seqlock
.WriteEnd();
56 orientation_buffer_
= nullptr;
59 StopObservingAccelerometer();
63 void SensorManagerChromeOS::OnAccelerometerUpdated(
64 const chromeos::AccelerometerUpdate
& update
) {
65 base::AutoLock
autolock(orientation_buffer_lock_
);
66 if (!orientation_buffer_
)
69 chromeos::AccelerometerSource source
;
70 if (update
.has(chromeos::ACCELEROMETER_SOURCE_SCREEN
)) {
71 source
= chromeos::ACCELEROMETER_SOURCE_SCREEN
;
72 } else if (update
.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD
)) {
73 source
= chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD
;
78 double x
= update
.get(source
).x
;
79 double y
= update
.get(source
).y
;
80 double z
= update
.get(source
).z
;
82 // Create a unit vector for trigonometry
83 // TODO(jonross): Stop reversing signs for vector components once
84 // accelerometer values have been fixed. crbug.com/431391
85 // Ternaries are to remove -0.0f which gives incorrect trigonometrical
87 gfx::Vector3dF
data(x
, y
? -y
: 0.0f
, z
? -z
: 0.0f
);
88 data
.Scale(1.0f
/ data
.Length());
90 // Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix.
92 // y = -cos(gamma) * sin(beta)
93 // z = cos(beta) * cos(gamma)
94 // With only accelerometer alpha cannot be provided.
95 double beta
= kRad2deg
* atan2(data
.y(), data
.z());
96 double gamma
= kRad2deg
* asin(data
.x());
98 // Convert beta and gamma to fit the intervals in the specification. Beta is
99 // [-180, 180) and gamma is [-90, 90).
104 orientation_buffer_
->seqlock
.WriteBegin();
105 orientation_buffer_
->data
.beta
= beta
;
106 orientation_buffer_
->data
.hasBeta
= true;
107 orientation_buffer_
->data
.gamma
= gamma
;
108 orientation_buffer_
->data
.hasGamma
= true;
109 orientation_buffer_
->data
.allAvailableSensorsAreActive
= true;
110 orientation_buffer_
->seqlock
.WriteEnd();
113 void SensorManagerChromeOS::StartObservingAccelerometer() {
114 chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
117 void SensorManagerChromeOS::StopObservingAccelerometer() {
118 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this);
121 } // namespace content