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

Side by Side Diff: chromeos/accelerometer/accelerometer_reader.cc

Issue 574113002: Use chromeos accelerometer reader and support only lid accelerometer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge with master. Created 6 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 | « chromeos/accelerometer/accelerometer_reader.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chromeos/accelerometer/accelerometer_reader.h" 5 #include "chromeos/accelerometer/accelerometer_reader.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/task_runner.h" 14 #include "base/task_runner.h"
15 #include "base/task_runner_util.h" 15 #include "base/task_runner_util.h"
16 #include "base/threading/sequenced_worker_pool.h" 16 #include "base/threading/sequenced_worker_pool.h"
17 17
18 namespace chromeos { 18 namespace chromeos {
19 19
20 namespace { 20 namespace {
21 21
22 // Paths to access necessary data from the accelerometer device. 22 // Paths to access necessary data from the accelerometer device.
23 const base::FilePath::CharType kAccelerometerTriggerPath[] = 23 const base::FilePath::CharType kAccelerometerTriggerPath[] =
24 FILE_PATH_LITERAL("/sys/bus/iio/devices/trigger0/trigger_now"); 24 FILE_PATH_LITERAL("/sys/bus/iio/devices/trigger0/trigger_now");
25 const base::FilePath::CharType kAccelerometerDevicePath[] = 25 const base::FilePath::CharType kAccelerometerDevicePath[] =
26 FILE_PATH_LITERAL("/dev/cros-ec-accel"); 26 FILE_PATH_LITERAL("/dev/cros-ec-accel");
27 const base::FilePath::CharType kAccelerometerIioBasePath[] = 27 const base::FilePath::CharType kAccelerometerIioBasePath[] =
28 FILE_PATH_LITERAL("/sys/bus/iio/devices/"); 28 FILE_PATH_LITERAL("/sys/bus/iio/devices/");
29 29
30 // Files within the device in kAccelerometerIioBasePath containing the scales of 30 // File within the device in kAccelerometerIioBasePath containing the scale of
31 // the accelerometers. 31 // the accelerometers.
32 const base::FilePath::CharType kAccelerometerBaseScaleName[] = 32 const base::FilePath::CharType kScaleNameFormatString[] = "in_accel_%s_scale";
33 FILE_PATH_LITERAL("in_accel_base_scale");
34 const base::FilePath::CharType kAccelerometerLidScaleName[] =
35 FILE_PATH_LITERAL("in_accel_lid_scale");
36 33
37 // The filename giving the path to read the scan index of each accelerometer 34 // The filename giving the path to read the scan index of each accelerometer
38 // axis. 35 // axis.
39 const char kAccelerometerScanIndexPath[] = 36 const char kAccelerometerScanIndexPath[] =
40 "scan_elements/in_accel_%s_%s_index"; 37 "scan_elements/in_accel_%s_%s_index";
41 38
42 // The names of the accelerometers and axes in the order we want to read them. 39 // The names of the accelerometers. Matches up with the enum AccelerometerSource
43 const char kAccelerometerNames[][5] = {"base", "lid"}; 40 // in ui/accelerometer/accelerometer_types.h.
44 const char kAccelerometerAxes[][2] = {"x", "y", "z"}; 41 const char kAccelerometerNames[ui::ACCELEROMETER_SOURCE_COUNT][5] = {
45 const size_t kTriggerDataValues = 42 "lid", "base"};
46 arraysize(kAccelerometerNames) * arraysize(kAccelerometerAxes); 43
47 const size_t kTriggerDataLength = kTriggerDataValues * 2; 44 // The axes on each accelerometer.
45 const char kAccelerometerAxes[][2] = {"y", "x", "z"};
48 46
49 // The length required to read uint values from configuration files. 47 // The length required to read uint values from configuration files.
50 const size_t kMaxAsciiUintLength = 21; 48 const size_t kMaxAsciiUintLength = 21;
51 49
50 // The size of individual values.
51 const size_t kDataSize = 2;
52
52 // The time to wait between reading the accelerometer. 53 // The time to wait between reading the accelerometer.
53 const int kDelayBetweenReadsMs = 100; 54 const int kDelayBetweenReadsMs = 100;
54 55
55 // The mean acceleration due to gravity on Earth in m/s^2. 56 // The mean acceleration due to gravity on Earth in m/s^2.
56 const float kMeanGravity = 9.80665f; 57 const float kMeanGravity = 9.80665f;
57 58
58 // Reads |path| to the unsigned int pointed to by |value|. Returns true on 59 // Reads |path| to the unsigned int pointed to by |value|. Returns true on
59 // success or false on failure. 60 // success or false on failure.
60 bool ReadFileToUint(const base::FilePath& path, unsigned int* value) { 61 bool ReadFileToInt(const base::FilePath& path, int* value) {
61 std::string s; 62 std::string s;
62 DCHECK(value); 63 DCHECK(value);
63 if (!base::ReadFileToString(path, &s, kMaxAsciiUintLength)) { 64 if (!base::ReadFileToString(path, &s, kMaxAsciiUintLength)) {
64 LOG(ERROR) << "Failed to read " << path.value();
65 return false; 65 return false;
66 } 66 }
67 base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s); 67 base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s);
68 if (!base::StringToUint(s, value)) { 68 if (!base::StringToInt(s, value)) {
69 LOG(ERROR) << "Failed to parse \"" << s << "\" from " << path.value(); 69 LOG(ERROR) << "Failed to parse \"" << s << "\" from " << path.value();
70 return false; 70 return false;
71 } 71 }
72 return true; 72 return true;
73 } 73 }
74 74
75 bool DetectAndReadAccelerometerConfiguration( 75 bool DetectAndReadAccelerometerConfiguration(
76 scoped_refptr<AccelerometerReader::Configuration> configuration) { 76 scoped_refptr<AccelerometerReader::Configuration> configuration) {
77 // Check for accelerometer symlink which will be created by the udev rules 77 // Check for accelerometer symlink which will be created by the udev rules
78 // file on detecting the device. 78 // file on detecting the device.
79 base::FilePath device; 79 base::FilePath device;
80 if (!base::ReadSymbolicLink(base::FilePath(kAccelerometerDevicePath), 80 if (!base::ReadSymbolicLink(base::FilePath(kAccelerometerDevicePath),
81 &device)) { 81 &device)) {
82 return false; 82 return false;
83 } 83 }
84 84
85 if (!base::PathExists(base::FilePath(kAccelerometerTriggerPath))) { 85 if (!base::PathExists(base::FilePath(kAccelerometerTriggerPath))) {
86 LOG(ERROR) << "Accelerometer trigger does not exist at" 86 LOG(ERROR) << "Accelerometer trigger does not exist at"
87 << kAccelerometerTriggerPath; 87 << kAccelerometerTriggerPath;
88 return false; 88 return false;
89 } 89 }
90 90
91 base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append( 91 base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append(
92 device)); 92 device));
93 // Read accelerometer scales 93 // Read configuration of each accelerometer axis from each accelerometer from
94 if (!ReadFileToUint(iio_path.Append(kAccelerometerBaseScaleName), 94 // /sys/bus/iio/devices/iio:deviceX/.
95 &(configuration->data.base_scale))) { 95 for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) {
96 return false; 96 // Read scale of accelerometer.
97 } 97 std::string accelerometer_scale_path = base::StringPrintf(
98 if (!ReadFileToUint(iio_path.Append(kAccelerometerLidScaleName), 98 kScaleNameFormatString, kAccelerometerNames[i]);
99 &(configuration->data.lid_scale))) { 99 int scale_divisor;
100 return false; 100 if (!ReadFileToInt(iio_path.Append(accelerometer_scale_path.c_str()),
101 } 101 &scale_divisor)) {
102 configuration->data.has[i] = false;
103 continue;
104 }
102 105
103 // Read indices of each accelerometer axis from each accelerometer from 106 configuration->data.has[i] = true;
104 // /sys/bus/iio/devices/iio:deviceX/scan_elements/in_accel_{x,y,z}_%s_index 107 configuration->data.count++;
105 for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) {
106 for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) { 108 for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) {
109 configuration->data.scale[i][j] = kMeanGravity / scale_divisor;
107 std::string accelerometer_index_path = base::StringPrintf( 110 std::string accelerometer_index_path = base::StringPrintf(
108 kAccelerometerScanIndexPath, kAccelerometerAxes[j], 111 kAccelerometerScanIndexPath, kAccelerometerAxes[j],
109 kAccelerometerNames[i]); 112 kAccelerometerNames[i]);
110 unsigned int index = 0; 113 if (!ReadFileToInt(iio_path.Append(accelerometer_index_path.c_str()),
111 if (!ReadFileToUint(iio_path.Append(accelerometer_index_path.c_str()), 114 &(configuration->data.index[i][j]))) {
112 &index)) {
113 return false; 115 return false;
114 } 116 }
115 if (index >= kTriggerDataValues) { 117 }
116 LOG(ERROR) << "Field index from " << accelerometer_index_path 118 }
117 << " out of bounds: " << index; 119
120 // Adjust the directions of accelerometers to match the AccelerometerUpdate
121 // type specified in ui/accelerometer/accelerometer_types.h.
122 configuration->data.scale[ui::ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f;
123 for (int i = 0; i < 3; ++i) {
124 configuration->data.scale[ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *=
125 -1.0f;
126 }
127
128 // Verify indices are within bounds.
129 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
130 if (!configuration->data.has[i])
131 continue;
132 for (int j = 0; j < 3; ++j) {
133 if (configuration->data.index[i][j] < 0 ||
134 configuration->data.index[i][j] >=
135 3 * static_cast<int>(configuration->data.count)) {
136 LOG(ERROR) << "Field index for " << kAccelerometerNames[i] << " "
137 << kAccelerometerAxes[j] << " axis out of bounds.";
118 return false; 138 return false;
119 } 139 }
120 configuration->data.index.push_back(index);
121 } 140 }
122 } 141 }
142 configuration->data.length = kDataSize * 3 * configuration->data.count;
123 return true; 143 return true;
124 } 144 }
125 145
126 bool ReadAccelerometer( 146 bool ReadAccelerometer(
127 scoped_refptr<AccelerometerReader::Reading> reading) { 147 scoped_refptr<AccelerometerReader::Reading> reading,
148 size_t length) {
128 // Initiate the trigger to read accelerometers simultaneously 149 // Initiate the trigger to read accelerometers simultaneously
129 int bytes_written = base::WriteFile( 150 int bytes_written = base::WriteFile(
130 base::FilePath(kAccelerometerTriggerPath), "1\n", 2); 151 base::FilePath(kAccelerometerTriggerPath), "1\n", 2);
131 if (bytes_written < 2) { 152 if (bytes_written < 2) {
132 PLOG(ERROR) << "Accelerometer trigger failure: " << bytes_written; 153 PLOG(ERROR) << "Accelerometer trigger failure: " << bytes_written;
133 return false; 154 return false;
134 } 155 }
135 156
136 // Read resulting sample from /dev/cros-ec-accel. 157 // Read resulting sample from /dev/cros-ec-accel.
137 int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath), 158 int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath),
138 reading->data, kTriggerDataLength); 159 reading->data, length);
139 if (bytes_read < static_cast<int>(kTriggerDataLength)) { 160 if (bytes_read < static_cast<int>(length)) {
140 LOG(ERROR) << "Read " << bytes_read << " byte(s), expected " 161 LOG(ERROR) << "Read " << bytes_read << " byte(s), expected "
141 << kTriggerDataLength << " bytes from accelerometer"; 162 << length << " bytes from accelerometer";
142 return false; 163 return false;
143 } 164 }
144 return true; 165 return true;
145 } 166 }
146 167
147 } // namespace 168 } // namespace
148 169
149 AccelerometerReader::ConfigurationData::ConfigurationData() { 170 AccelerometerReader::ConfigurationData::ConfigurationData()
171 : count(0) {
172 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
173 has[i] = false;
174 for (int j = 0; j < 3; ++j) {
175 scale[i][j] = 0;
176 index[i][j] = -1;
177 }
178 }
150 } 179 }
151 180
152 AccelerometerReader::ConfigurationData::~ConfigurationData() { 181 AccelerometerReader::ConfigurationData::~ConfigurationData() {
153 } 182 }
154 183
155 AccelerometerReader::AccelerometerReader( 184 AccelerometerReader::AccelerometerReader(
156 base::TaskRunner* task_runner, 185 base::TaskRunner* blocking_task_runner,
157 AccelerometerReader::Delegate* delegate) 186 AccelerometerReader::Delegate* delegate)
158 : task_runner_(task_runner), 187 : task_runner_(blocking_task_runner),
159 delegate_(delegate), 188 delegate_(delegate),
160 configuration_(new AccelerometerReader::Configuration()), 189 configuration_(new AccelerometerReader::Configuration()),
161 weak_factory_(this) { 190 weak_factory_(this) {
162 DCHECK(task_runner_.get()); 191 DCHECK(task_runner_.get());
163 DCHECK(delegate_); 192 DCHECK(delegate_);
164 // Asynchronously detect and initialize the accelerometer to avoid delaying 193 // Asynchronously detect and initialize the accelerometer to avoid delaying
165 // startup. 194 // startup.
166 base::PostTaskAndReplyWithResult(task_runner_.get(), FROM_HERE, 195 base::PostTaskAndReplyWithResult(task_runner_.get(), FROM_HERE,
167 base::Bind(&DetectAndReadAccelerometerConfiguration, configuration_), 196 base::Bind(&DetectAndReadAccelerometerConfiguration, configuration_),
168 base::Bind(&AccelerometerReader::OnInitialized, 197 base::Bind(&AccelerometerReader::OnInitialized,
(...skipping 10 matching lines...) Expand all
179 TriggerRead(); 208 TriggerRead();
180 } 209 }
181 210
182 void AccelerometerReader::TriggerRead() { 211 void AccelerometerReader::TriggerRead() {
183 DCHECK(!task_runner_->RunsTasksOnCurrentThread()); 212 DCHECK(!task_runner_->RunsTasksOnCurrentThread());
184 213
185 scoped_refptr<AccelerometerReader::Reading> reading( 214 scoped_refptr<AccelerometerReader::Reading> reading(
186 new AccelerometerReader::Reading()); 215 new AccelerometerReader::Reading());
187 base::PostTaskAndReplyWithResult(task_runner_.get(), 216 base::PostTaskAndReplyWithResult(task_runner_.get(),
188 FROM_HERE, 217 FROM_HERE,
189 base::Bind(&ReadAccelerometer, reading), 218 base::Bind(&ReadAccelerometer, reading,
219 configuration_->data.length),
190 base::Bind(&AccelerometerReader::OnDataRead, 220 base::Bind(&AccelerometerReader::OnDataRead,
191 weak_factory_.GetWeakPtr(), 221 weak_factory_.GetWeakPtr(),
192 reading)); 222 reading));
193 } 223 }
194 224
195 void AccelerometerReader::OnDataRead( 225 void AccelerometerReader::OnDataRead(
196 scoped_refptr<AccelerometerReader::Reading> reading, 226 scoped_refptr<AccelerometerReader::Reading> reading,
197 bool success) { 227 bool success) {
198 DCHECK(!task_runner_->RunsTasksOnCurrentThread()); 228 DCHECK(!task_runner_->RunsTasksOnCurrentThread());
199 229
200 if (success) { 230 if (success) {
201 int16* values = reinterpret_cast<int16*>(reading->data); 231 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
202 float lid_scale = kMeanGravity / configuration_->data.lid_scale; 232 if (!configuration_->data.has[i])
203 update_.Set(ui::ACCELEROMETER_SOURCE_SCREEN, 233 continue;
204 -values[configuration_->data.index[4]] * lid_scale, 234
205 values[configuration_->data.index[3]] * lid_scale, 235 int16* values = reinterpret_cast<int16*>(reading->data);
206 values[configuration_->data.index[5]] * lid_scale); 236 update_.Set(static_cast<ui::AccelerometerSource>(i),
207 float base_scale = kMeanGravity / configuration_->data.base_scale; 237 values[configuration_->data.index[i][0]] *
208 update_.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 238 configuration_->data.scale[i][0],
209 -values[configuration_->data.index[1]] * base_scale, 239 values[configuration_->data.index[i][1]] *
210 -values[configuration_->data.index[0]] * base_scale, 240 configuration_->data.scale[i][1],
211 -values[configuration_->data.index[2]] * base_scale); 241 values[configuration_->data.index[i][2]] *
242 configuration_->data.scale[i][2]);
243 }
212 delegate_->HandleAccelerometerUpdate(update_); 244 delegate_->HandleAccelerometerUpdate(update_);
213 } 245 }
214 246
215 // Trigger another read after the current sampling delay. 247 // Trigger another read after the current sampling delay.
216 base::MessageLoop::current()->PostDelayedTask( 248 base::MessageLoop::current()->PostDelayedTask(
217 FROM_HERE, 249 FROM_HERE,
218 base::Bind(&AccelerometerReader::TriggerRead, 250 base::Bind(&AccelerometerReader::TriggerRead,
219 weak_factory_.GetWeakPtr()), 251 weak_factory_.GetWeakPtr()),
220 base::TimeDelta::FromMilliseconds(kDelayBetweenReadsMs)); 252 base::TimeDelta::FromMilliseconds(kDelayBetweenReadsMs));
221 } 253 }
222 254
223 } // namespace chromeos 255 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/accelerometer/accelerometer_reader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698