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

Side by Side Diff: chrome/browser/device_orientation/accelerometer_mac.cc

Issue 3275002: Added tested and corrected accelerometer support for the following MacBook / MacBook Pro models: (Closed)
Patch Set: Created 10 years, 3 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
« no previous file with comments | « chrome/browser/device_orientation/accelerometer_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // This file is based on the SMSLib library. 5 // This file is based on the SMSLib library.
6 // 6 //
7 // SMSLib Sudden Motion Sensor Access Library 7 // SMSLib Sudden Motion Sensor Access Library
8 // Copyright (c) 2010 Suitable Systems 8 // Copyright (c) 2010 Suitable Systems
9 // All rights reserved. 9 // All rights reserved.
10 // 10 //
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 #include <math.h> // For isfinite. 53 #include <math.h> // For isfinite.
54 #include <sys/sysctl.h> 54 #include <sys/sysctl.h>
55 55
56 #include "base/logging.h" 56 #include "base/logging.h"
57 #include "base/scoped_ptr.h" 57 #include "base/scoped_ptr.h"
58 #include "chrome/browser/device_orientation/orientation.h" 58 #include "chrome/browser/device_orientation/orientation.h"
59 59
60 namespace device_orientation { 60 namespace device_orientation {
61 61
62 // Per-axis sensor data. 62 struct AccelerometerMac::GenericMacbookSensor {
63 // Name of device to be read.
64 const char* service_name;
65
66 // Number of bytes of the axis data.
67 int axis_size;
68
69 // Default calibration value for zero g.
70 float zero_g;
71
72 // Default calibration value for one g (negative when axis is inverted).
73 float one_g;
74
75 // Kernel function index.
76 unsigned int function;
77
78 // Size of the sensor record to be sent/received.
79 unsigned int record_size;
80 };
81
63 struct AccelerometerMac::AxisData { 82 struct AccelerometerMac::AxisData {
64 // Non-zero if the axis is valid in this sensor. 83 // Location of the first byte representing the axis in the sensor data.
65 int enabled;
66
67 // Location in struct of first byte.
68 int index; 84 int index;
69 85
70 // Number of bytes of the axis data. 86 // Axis inversion flag. The value changes often between models.
71 int size; 87 bool inverted;
72
73 // Value meaning "zero g".
74 float zero_g;
75
76 // (can be negative if the sensor axis is reversed).
77 float one_g;
78 }; 88 };
79 89
80 // Sudden Motion Sensor descriptor. 90 // Sudden Motion Sensor descriptor.
81 struct AccelerometerMac::SensorDescriptor { 91 struct AccelerometerMac::SensorDescriptor {
82 // Prefix of model to be tested. 92 // Prefix of model to be tested.
83 const char* model_name; 93 const char* model_name;
84 94
85 // Name of device to be read. 95 // Axis-specific data (x,y,z order).
86 const char* service_name; 96 AxisData axis[3];
97 };
87 98
88 // Kernel function index. 99 // Typical sensor parameters in MacBook models.
89 unsigned int function; 100 const AccelerometerMac::GenericMacbookSensor
90 101 AccelerometerMac::kGenericSensor = {
91 // Size of record to be sent/received. 102 "SMCMotionSensor", 2,
92 unsigned int record_size; 103 0, 251,
93 104 5, 40
94 // Description of three axes (x,y,z).
95 AxisData axes[3];
96 }; 105 };
97 106
98 // Supported sensor descriptors. Add entries here to enhance compatibility. 107 // Supported sensor descriptors. Add entries here to enhance compatibility.
99 // All non-tested entries from SMSLib have been removed. 108 // All non-tested entries from SMSLib have been removed.
100 const AccelerometerMac::SensorDescriptor 109 const AccelerometerMac::SensorDescriptor
101 AccelerometerMac::kSupportedSensors[] = { 110 AccelerometerMac::kSupportedSensors[] = {
102 // Tested by leandrogracia on a 15'' MacBook Pro. 111 // Tested by leandrogracia on a 15'' MacBook Pro.
103 { "MacBookPro5,4", "SMCMotionSensor", 5, 40, { 112 { "MacBookPro2,2", { { 0, true }, { 2, true }, { 4, false } } },
104 { 1, 0, 2, 0, 251 }, 113
105 { 1, 2, 2, 0, 251 }, 114 // Tested by leandrogracia on a 15'' MacBook Pro.
106 { 1, 4, 2, 0, 251 } 115 { "MacBookPro3,1", { { 0, false }, { 2, true }, { 4, true } } },
107 } }, 116
117 // Tested by leandrogracia on a 15'' MacBook Pro.
118 { "MacBookPro4,1", { { 0, true }, { 2, true }, { 4, false } } },
119
120 // Tested by leandrogracia on a 15'' MacBook Pro.
121 { "MacBookPro5,1", { { 0, false }, { 2, false }, { 4, false } } },
122
123 // Tested by leandrogracia on a 15'' MacBook Pro.
124 { "MacBookPro5,4", { { 0, false }, { 2, false }, { 4, false } } },
108 125
109 // Tested by leandrogracia on a 13'' MacBook Pro. 126 // Tested by leandrogracia on a 13'' MacBook Pro.
110 { "MacBookPro5,5", "SMCMotionSensor", 5, 40, { 127 { "MacBookPro5,5", { { 0, true }, { 2, true }, { 4, false } } },
111 { 1, 0, 2, 0, -251 }, 128
112 { 1, 2, 2, 0, -251 }, 129 // Tested by leandrogracia on a 15'' MacBook Pro.
113 { 1, 4, 2, 0, 251 } 130 { "MacBookPro6,2", { { 0, true }, { 2, false }, { 4, true } } },
114 } }, 131
132 // Tested by leandrogracia on a 13'' MacBook Pro.
133 { "MacBookPro7,1", { { 0, true }, { 2, true }, { 4, false } } },
115 134
116 // Generic MacBook accelerometer sensor data. 135 // Generic MacBook accelerometer sensor data.
117 // Added for forward compatibility (there may be problems with inverted axes). 136 // Added for compatibility with non-tested models
118 {"", "SMCMotionSensor", 5, 40, { 137 // Note: there may be problems with inverted axes.
119 { 1, 0, 2, 0, -251 }, 138 { "", { { 0, true }, { 2, true }, { 4, false } } }
120 { 1, 2, 2, 0, -251 },
121 { 1, 4, 2, 0, 251 }
122 } }
123 }; 139 };
124 140
125 // Create a AccelerometerMac object and return NULL if no valid sensor found. 141 // Create a AccelerometerMac object and return NULL if no valid sensor found.
126 DataFetcher* AccelerometerMac::Create() { 142 DataFetcher* AccelerometerMac::Create() {
127 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac); 143 scoped_ptr<AccelerometerMac> accelerometer(new AccelerometerMac);
128 return accelerometer->Init() ? accelerometer.release() : NULL; 144 return accelerometer->Init() ? accelerometer.release() : NULL;
129 } 145 }
130 146
131 AccelerometerMac::~AccelerometerMac() { 147 AccelerometerMac::~AccelerometerMac() {
132 IOServiceClose(io_connection_); 148 IOServiceClose(io_connection_);
(...skipping 13 matching lines...) Expand all
146 // 162 //
147 // Returns false in case of error or non-properly initialized object. 163 // Returns false in case of error or non-properly initialized object.
148 // 164 //
149 bool AccelerometerMac::GetOrientation(Orientation* orientation) { 165 bool AccelerometerMac::GetOrientation(Orientation* orientation) {
150 DCHECK(sensor_); 166 DCHECK(sensor_);
151 167
152 // Reset output record memory buffer. 168 // Reset output record memory buffer.
153 std::fill(output_record_.begin(), output_record_.end(), 0x00); 169 std::fill(output_record_.begin(), output_record_.end(), 0x00);
154 170
155 // Read record data from memory. 171 // Read record data from memory.
156 const size_t kInputSize = sensor_->record_size; 172 const size_t kInputSize = kGenericSensor.record_size;
157 size_t output_size = sensor_->record_size; 173 size_t output_size = kGenericSensor.record_size;
158 174
159 if (IOConnectCallStructMethod(io_connection_, sensor_->function, 175 if (IOConnectCallStructMethod(io_connection_, kGenericSensor.function,
160 static_cast<const char *>(&input_record_[0]), kInputSize, 176 static_cast<const char *>(&input_record_[0]), kInputSize,
161 &output_record_[0], &output_size) != KERN_SUCCESS) { 177 &output_record_[0], &output_size) != KERN_SUCCESS) {
162 return false; 178 return false;
163 } 179 }
164 180
165 // Calculate per-axis calibrated values. 181 // Calculate per-axis calibrated values.
166 float axis_value[3]; 182 float axis_value[3];
167 183
168 for (int i = 0; i < 3; ++i) { 184 for (int i = 0; i < 3; ++i) {
169 int sensor_value = 0; 185 int sensor_value = 0;
170 int size = sensor_->axes[i].size; 186 int size = kGenericSensor.axis_size;
171 int index = sensor_->axes[i].index; 187 int index = sensor_->axis[i].index;
172 188
173 // Important Note: little endian is assumed as this code is mac-only 189 // Important Note: little endian is assumed as this code is mac-only
174 // and PowerPC is currently not supported. 190 // and PowerPC is currently not supported.
175 memcpy(&sensor_value, &output_record_[index], size); 191 memcpy(&sensor_value, &output_record_[index], size);
176 192
177 sensor_value = ExtendSign(sensor_value, size); 193 sensor_value = ExtendSign(sensor_value, size);
178 194
179 // Correct value using the current calibration. 195 // Correct value using the current calibration.
180 axis_value[i] = static_cast<float>(sensor_value - sensor_->axes[i].zero_g) / 196 axis_value[i] = static_cast<float>(sensor_value - kGenericSensor.zero_g) /
181 sensor_->axes[i].one_g; 197 kGenericSensor.one_g;
182 198
183 // Make sure we reject any NaN or infinite values. 199 // Make sure we reject any NaN or infinite values.
184 if (!isfinite(axis_value[i])) 200 if (!isfinite(axis_value[i]))
185 return false; 201 return false;
186 202
187 // Clamp value to the [-1, 1] range. 203 // Clamp value to the [-1, 1] range.
188 if (axis_value[i] < -1.0) 204 if (axis_value[i] < -1.0)
189 axis_value[i] = -1.0; 205 axis_value[i] = -1.0;
190 else if (axis_value[i] > 1.0) 206 else if (axis_value[i] > 1.0)
191 axis_value[i] = 1.0; 207 axis_value[i] = 1.0;
208
209 // Apply axis inversion.
210 if (sensor_->axis[i].inverted)
211 axis_value[i] = -axis_value[i];
192 } 212 }
193 213
194 // Transform the accelerometer values to W3C draft angles. 214 // Transform the accelerometer values to W3C draft angles.
195 // 215 //
196 // Accelerometer values are just dot products of the sensor axes 216 // Accelerometer values are just dot products of the sensor axes
197 // by the gravity vector 'g' with the result for the z axis inverted. 217 // by the gravity vector 'g' with the result for the z axis inverted.
198 // 218 //
199 // To understand this transformation calculate the 3rd row of the z-x-y 219 // To understand this transformation calculate the 3rd row of the z-x-y
200 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row 220 // Euler angles rotation matrix (because of the 'g' vector, only 3rd row
201 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz. 221 // affects to the result). Note that z-x-y matrix means R = Ry * Rx * Rz.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 for (const char* p2 = local_model; *p1 != '\0' && *p1 == *p2; ++p1, ++p2) 281 for (const char* p2 = local_model; *p1 != '\0' && *p1 == *p2; ++p1, ++p2)
262 continue; 282 continue;
263 if (*p1 != '\0') 283 if (*p1 != '\0')
264 continue; 284 continue;
265 285
266 // Local hardware found in the supported sensor list. 286 // Local hardware found in the supported sensor list.
267 sensor_candidate = &kSupportedSensors[i]; 287 sensor_candidate = &kSupportedSensors[i];
268 288
269 // Get a dictionary of the services matching to the one in the sensor. 289 // Get a dictionary of the services matching to the one in the sensor.
270 CFMutableDictionaryRef dict = 290 CFMutableDictionaryRef dict =
271 IOServiceMatching(sensor_candidate->service_name); 291 IOServiceMatching(kGenericSensor.service_name);
272 if (dict == NULL) 292 if (dict == NULL)
273 continue; 293 continue;
274 294
275 // Get an iterator for the matching services. 295 // Get an iterator for the matching services.
276 io_iterator_t device_iterator; 296 io_iterator_t device_iterator;
277 if (IOServiceGetMatchingServices(kIOMasterPortDefault, dict, 297 if (IOServiceGetMatchingServices(kIOMasterPortDefault, dict,
278 &device_iterator) != KERN_SUCCESS) { 298 &device_iterator) != KERN_SUCCESS) {
279 continue; 299 continue;
280 } 300 }
281 301
(...skipping 10 matching lines...) Expand all
292 312
293 // Local sensor service confirmed by IOKit. 313 // Local sensor service confirmed by IOKit.
294 sensor_ = sensor_candidate; 314 sensor_ = sensor_candidate;
295 break; 315 break;
296 } 316 }
297 317
298 if (sensor_ == NULL) 318 if (sensor_ == NULL)
299 return false; 319 return false;
300 320
301 // Allocate and initialize input/output records. 321 // Allocate and initialize input/output records.
302 input_record_.resize(sensor_->record_size, 0x01); 322 input_record_.resize(kGenericSensor.record_size, 0x01);
303 output_record_.resize(sensor_->record_size, 0x00); 323 output_record_.resize(kGenericSensor.record_size, 0x00);
304 324
305 // Try to retrieve the current orientation. 325 // Try to retrieve the current orientation.
306 Orientation test_orientation; 326 Orientation test_orientation;
307 return GetOrientation(&test_orientation); 327 return GetOrientation(&test_orientation);
308 } 328 }
309 329
310 // Extend the sign of an integer of less than 32 bits to a 32-bit integer. 330 // Extend the sign of an integer of less than 32 bits to a 32-bit integer.
311 int AccelerometerMac::ExtendSign(int value, size_t size) { 331 int AccelerometerMac::ExtendSign(int value, size_t size) {
312 switch (size) { 332 switch (size) {
313 case 1: 333 case 1:
(...skipping 12 matching lines...) Expand all
326 break; 346 break;
327 347
328 default: 348 default:
329 LOG(FATAL) << "Invalid integer size for sign extension: " << size; 349 LOG(FATAL) << "Invalid integer size for sign extension: " << size;
330 } 350 }
331 351
332 return value; 352 return value;
333 } 353 }
334 354
335 } // namespace device_orientation 355 } // namespace device_orientation
OLDNEW
« no previous file with comments | « chrome/browser/device_orientation/accelerometer_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698