Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(880)

Side by Side Diff: content/browser/device_sensors/sensor_manager_chromeos.cc

Issue 934843002: Implement DeviceMotionEvent API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/device_sensors/sensor_manager_chromeos.h" 5 #include "content/browser/device_sensors/sensor_manager_chromeos.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/logging.h"
10 #include "chromeos/accelerometer/accelerometer_reader.h" 9 #include "chromeos/accelerometer/accelerometer_reader.h"
11 #include "chromeos/accelerometer/accelerometer_types.h" 10 #include "chromeos/accelerometer/accelerometer_types.h"
11 #include "content/browser/device_sensors/inertial_sensor_consts.h"
12 #include "ui/gfx/geometry/vector3d_f.h" 12 #include "ui/gfx/geometry/vector3d_f.h"
13 13
14 namespace { 14 namespace {
15 // Conversion ratio from radians to degrees. 15 // Conversion ratio from radians to degrees.
16 const double kRad2deg = 180.0 / M_PI; 16 const double kRad2deg = 180.0 / M_PI;
17
18 // The portion of previous gravity readings to perserve when updating with the
19 // latest data.
20 const double kGravityFilterRatio = 0.8;
17 } 21 }
18 22
19 namespace content { 23 namespace content {
20 24
21 SensorManagerChromeOS::SensorManagerChromeOS() : orientation_buffer_(nullptr) { 25 SensorManagerChromeOS::SensorManagerChromeOS()
26 : motion_buffer_(nullptr), orientation_buffer_(nullptr) {
22 } 27 }
23 28
24 SensorManagerChromeOS::~SensorManagerChromeOS() { 29 SensorManagerChromeOS::~SensorManagerChromeOS() {
25 } 30 }
26 31
32 bool SensorManagerChromeOS::StartFetchingDeviceMotionData(
33 DeviceMotionHardwareBuffer* buffer) {
34 DCHECK(buffer);
35 {
36 base::AutoLock autolock(motion_buffer_lock_);
37 if (motion_buffer_)
38 return false;
39 motion_buffer_ = buffer;
40
41 motion_buffer_->seqlock.WriteBegin();
42 motion_buffer_->data.interval = kInertialSensorIntervalMicroseconds / 1000;
flackr 2015/02/18 22:34:09 But this is not actually the update interval. Even
jonross 2015/02/24 00:02:47 This is the interval with which events are sent to
flackr 2015/02/25 23:15:16 But when I tested it, it seems that JS is only not
jonross 2015/03/05 14:28:02 Done.
43 motion_buffer_->seqlock.WriteEnd();
44 }
45
46 StartObservingAccelerometer();
47 return true;
48 }
49
50 bool SensorManagerChromeOS::StopFetchingDeviceMotionData() {
51 {
52 base::AutoLock autolock(motion_buffer_lock_);
53 if (!motion_buffer_)
54 return false;
55 // Make sure to indicate that the sensor data is no longer available.
56 motion_buffer_->seqlock.WriteBegin();
57 motion_buffer_->data.allAvailableSensorsAreActive = false;
58 motion_buffer_->seqlock.WriteEnd();
59
60 motion_buffer_ = nullptr;
61 }
62 StopObservingAccelerometer();
63 return true;
64 }
65
27 bool SensorManagerChromeOS::StartFetchingDeviceOrientationData( 66 bool SensorManagerChromeOS::StartFetchingDeviceOrientationData(
28 DeviceOrientationHardwareBuffer* buffer) { 67 DeviceOrientationHardwareBuffer* buffer) {
29 DCHECK(buffer); 68 DCHECK(buffer);
30 { 69 {
31 base::AutoLock autolock(orientation_buffer_lock_); 70 base::AutoLock autolock(orientation_buffer_lock_);
32 if (orientation_buffer_) 71 if (orientation_buffer_)
33 return false; 72 return false;
34 orientation_buffer_ = buffer; 73 orientation_buffer_ = buffer;
35 74
36 // No compass information, so we cannot provide absolute orientation. 75 // No compass information, so we cannot provide absolute orientation.
37 orientation_buffer_->seqlock.WriteBegin(); 76 orientation_buffer_->seqlock.WriteBegin();
38 orientation_buffer_->data.absolute = false; 77 orientation_buffer_->data.absolute = false;
39 orientation_buffer_->data.hasAbsolute = true; 78 orientation_buffer_->data.hasAbsolute = true;
40 orientation_buffer_->seqlock.WriteEnd(); 79 orientation_buffer_->seqlock.WriteEnd();
41 } 80 }
42
43 StartObservingAccelerometer(); 81 StartObservingAccelerometer();
44 return true; 82 return true;
45 } 83 }
46 84
47 bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() { 85 bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() {
48 { 86 {
49 base::AutoLock autolock(orientation_buffer_lock_); 87 base::AutoLock autolock(orientation_buffer_lock_);
50 if (!orientation_buffer_) 88 if (!orientation_buffer_)
51 return false; 89 return false;
52 // Make sure to indicate that the sensor data is no longer available. 90 // Make sure to indicate that the sensor data is no longer available.
53 orientation_buffer_->seqlock.WriteBegin(); 91 orientation_buffer_->seqlock.WriteBegin();
54 orientation_buffer_->data.allAvailableSensorsAreActive = false; 92 orientation_buffer_->data.allAvailableSensorsAreActive = false;
55 orientation_buffer_->seqlock.WriteEnd(); 93 orientation_buffer_->seqlock.WriteEnd();
56 orientation_buffer_ = nullptr; 94 orientation_buffer_ = nullptr;
57 } 95 }
58 96
59 StopObservingAccelerometer(); 97 StopObservingAccelerometer();
60 return true; 98 return true;
61 } 99 }
62 100
63 void SensorManagerChromeOS::OnAccelerometerUpdated( 101 void SensorManagerChromeOS::OnAccelerometerUpdated(
flackr 2015/02/18 22:34:09 Given the accelerometer source reader runs on a bl
jonross 2015/02/25 00:09:56 For the DeviceMotion API this will be partially ad
64 const chromeos::AccelerometerUpdate& update) { 102 const chromeos::AccelerometerUpdate& update) {
65 base::AutoLock autolock(orientation_buffer_lock_); 103 chromeos::AccelerometerSource source;
66 if (!orientation_buffer_) 104 if (update.has(chromeos::ACCELEROMETER_SOURCE_SCREEN))
105 source = chromeos::ACCELEROMETER_SOURCE_SCREEN;
106 else if (update.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD))
107 source = chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD;
108 else
67 return; 109 return;
68 110
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;
74 } else {
75 return;
76 }
77
78 double x = update.get(source).x; 111 double x = update.get(source).x;
79 double y = update.get(source).y; 112 double y = update.get(source).y;
80 double z = update.get(source).z; 113 double z = update.get(source).z;
81 114
115 GenerateMotionEvent(x, y, z);
116 GenerateOrientationEvent(x, y, z);
117 }
118
119 void SensorManagerChromeOS::StartObservingAccelerometer() {
120 if (chromeos::AccelerometerReader::GetInstance()->HasObserver(this))
121 return;
122 chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
123 }
124
125 void SensorManagerChromeOS::StopObservingAccelerometer() {
126 {
127 base::AutoLock auto_motion_lock(motion_buffer_lock_);
128 base::AutoLock auto_orientation_lock(orientation_buffer_lock_);
129 if (orientation_buffer_ || motion_buffer_)
130 return;
131 }
132 if (!chromeos::AccelerometerReader::GetInstance()->HasObserver(this))
flackr 2015/02/18 22:34:09 It should always have an observer if StopObserving
jonross 2015/02/25 00:09:56 Done.
133 return;
134 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this);
135 }
136
137 void SensorManagerChromeOS::GenerateMotionEvent(double x, double y, double z) {
138 base::AutoLock autlock(motion_buffer_lock_);
139 if (!motion_buffer_)
140 return;
141
142 motion_buffer_->seqlock.WriteBegin();
143 motion_buffer_->data.accelerationIncludingGravityX = x;
144 motion_buffer_->data.hasAccelerationIncludingGravityX = true;
145 motion_buffer_->data.accelerationIncludingGravityY = y;
146 motion_buffer_->data.hasAccelerationIncludingGravityY = true;
147 motion_buffer_->data.accelerationIncludingGravityZ = z;
148 motion_buffer_->data.hasAccelerationIncludingGravityZ = true;
149 motion_buffer_->data.allAvailableSensorsAreActive = true;
150
151 gravity_.set_x(kGravityFilterRatio * gravity_.x() +
flackr 2015/02/18 22:34:09 I'm not sure we should be using a low pass filter
jonross 2015/02/24 00:02:47 The idea for the filter actually came from Android
flackr 2015/02/25 23:15:16 My understanding from reading this was that it's a
jonross 2015/03/05 14:28:02 Acknowledged.
152 (1.0f - kGravityFilterRatio) * x);
153 gravity_.set_y(kGravityFilterRatio * gravity_.y() +
154 (1.0f - kGravityFilterRatio) * y);
155 gravity_.set_z(kGravityFilterRatio * gravity_.z() +
156 (1.0f - kGravityFilterRatio) * z);
157
158 motion_buffer_->data.accelerationX = x - gravity_.x();
159 motion_buffer_->data.hasAccelerationX = true;
160 motion_buffer_->data.accelerationY = y - gravity_.y();
161 motion_buffer_->data.hasAccelerationY = true;
162 motion_buffer_->data.accelerationZ = z - gravity_.z();
163 motion_buffer_->data.hasAccelerationZ = true;
164 motion_buffer_->seqlock.WriteEnd();
165 }
166
167 void SensorManagerChromeOS::GenerateOrientationEvent(double x,
168 double y,
169 double z) {
170 base::AutoLock autolock(orientation_buffer_lock_);
171 if (!orientation_buffer_)
172 return;
173
82 // Create a unit vector for trigonometry 174 // Create a unit vector for trigonometry
83 // TODO(jonross): Stop reversing signs for vector components once 175 // TODO(jonross): Stop reversing signs for vector components once
84 // accelerometer values have been fixed. crbug.com/431391 176 // accelerometer values have been fixed. crbug.com/431391
85 // Ternaries are to remove -0.0f which gives incorrect trigonometrical 177 // Ternaries are to remove -0.0f which gives incorrect trigonometrical
86 // results. 178 // results.
87 gfx::Vector3dF data(x, y ? -y : 0.0f, z ? -z : 0.0f); 179 gfx::Vector3dF data(x, y ? -y : 0.0f, z ? -z : 0.0f);
88 data.Scale(1.0f / data.Length()); 180 data.Scale(1.0f / data.Length());
89 181
90 // Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix. 182 // Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix.
91 // x = sin(gamma) 183 // x = sin(gamma)
(...skipping 11 matching lines...) Expand all
103 gamma = -90.0f; 195 gamma = -90.0f;
104 orientation_buffer_->seqlock.WriteBegin(); 196 orientation_buffer_->seqlock.WriteBegin();
105 orientation_buffer_->data.beta = beta; 197 orientation_buffer_->data.beta = beta;
106 orientation_buffer_->data.hasBeta = true; 198 orientation_buffer_->data.hasBeta = true;
107 orientation_buffer_->data.gamma = gamma; 199 orientation_buffer_->data.gamma = gamma;
108 orientation_buffer_->data.hasGamma = true; 200 orientation_buffer_->data.hasGamma = true;
109 orientation_buffer_->data.allAvailableSensorsAreActive = true; 201 orientation_buffer_->data.allAvailableSensorsAreActive = true;
110 orientation_buffer_->seqlock.WriteEnd(); 202 orientation_buffer_->seqlock.WriteEnd();
111 } 203 }
112 204
113 void SensorManagerChromeOS::StartObservingAccelerometer() {
114 chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
115 }
116
117 void SensorManagerChromeOS::StopObservingAccelerometer() {
118 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this);
119 }
120
121 } // namespace content 205 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698