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

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: 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
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 kAccelerometerScaleName[] = "in_accel_%s_scale";
Daniel Erat 2014/09/16 21:41:03 nit: kScaleNameFormatString?
flackr 2014/09/16 22:19:23 Done.
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 DCHECK(base::MessageLoopForIO::current());
77 // Check for accelerometer symlink which will be created by the udev rules 78 // Check for accelerometer symlink which will be created by the udev rules
78 // file on detecting the device. 79 // file on detecting the device.
79 base::FilePath device; 80 base::FilePath device;
80 if (!base::ReadSymbolicLink(base::FilePath(kAccelerometerDevicePath), 81 if (!base::ReadSymbolicLink(base::FilePath(kAccelerometerDevicePath),
81 &device)) { 82 &device)) {
82 return false; 83 return false;
83 } 84 }
84 85
85 if (!base::PathExists(base::FilePath(kAccelerometerTriggerPath))) { 86 if (!base::PathExists(base::FilePath(kAccelerometerTriggerPath))) {
86 LOG(ERROR) << "Accelerometer trigger does not exist at" 87 LOG(ERROR) << "Accelerometer trigger does not exist at"
87 << kAccelerometerTriggerPath; 88 << kAccelerometerTriggerPath;
88 return false; 89 return false;
89 } 90 }
90 91
91 base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append( 92 base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append(
92 device)); 93 device));
93 // Read accelerometer scales 94 // Read configuration of each accelerometer axis from each accelerometer from
94 if (!ReadFileToUint(iio_path.Append(kAccelerometerBaseScaleName), 95 // /sys/bus/iio/devices/iio:deviceX/.
95 &(configuration->data.base_scale))) { 96 for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) {
96 return false; 97 // Read scale of accelerometer.
97 } 98 std::string accelerometer_scale_path = base::StringPrintf(
98 if (!ReadFileToUint(iio_path.Append(kAccelerometerLidScaleName), 99 kAccelerometerScaleName, kAccelerometerNames[i]);
99 &(configuration->data.lid_scale))) { 100 int scale_divisor;
100 return false; 101 if (!ReadFileToInt(iio_path.Append(accelerometer_scale_path.c_str()),
101 } 102 &scale_divisor)) {
103 configuration->data.has[i] = false;
104 continue;
105 }
102 106
103 // Read indices of each accelerometer axis from each accelerometer from 107 configuration->data.has[i] = true;
104 // /sys/bus/iio/devices/iio:deviceX/scan_elements/in_accel_{x,y,z}_%s_index 108 configuration->data.count++;
105 for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) {
106 for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) { 109 for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) {
110 configuration->data.scale[i][j] = kMeanGravity / scale_divisor;
107 std::string accelerometer_index_path = base::StringPrintf( 111 std::string accelerometer_index_path = base::StringPrintf(
108 kAccelerometerScanIndexPath, kAccelerometerAxes[j], 112 kAccelerometerScanIndexPath, kAccelerometerAxes[j],
109 kAccelerometerNames[i]); 113 kAccelerometerNames[i]);
110 unsigned int index = 0; 114 if (!ReadFileToInt(iio_path.Append(accelerometer_index_path.c_str()),
111 if (!ReadFileToUint(iio_path.Append(accelerometer_index_path.c_str()), 115 &(configuration->data.index[i][j]))) {
112 &index)) {
113 return false; 116 return false;
114 } 117 }
115 if (index >= kTriggerDataValues) { 118 }
116 LOG(ERROR) << "Field index from " << accelerometer_index_path 119 }
117 << " out of bounds: " << index; 120
121 // Adjust the directions of accelerometers to match the AccelerometerUpdate
122 // type specified in ui/accelerometer/accelerometer_types.h.
123 configuration->data.scale[ui::ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f;
124 for (int i = 0; i < 3; ++i) {
125 configuration->data.scale[ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *=
126 -1.0f;
127 }
128
129 // Verify indices are within bounds.
130 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
131 if (!configuration->data.has[i])
132 continue;
133 for (int j = 0; j < 3; ++j) {
134 if (configuration->data.index[i][j] < 0 ||
135 configuration->data.index[i][j] >=
136 3 * static_cast<int>(configuration->data.count)) {
137 LOG(ERROR) << "Field index for " << kAccelerometerNames[i] << " "
138 << kAccelerometerAxes[j] << " axis out of bounds.";
118 return false; 139 return false;
119 } 140 }
120 configuration->data.index.push_back(index);
121 } 141 }
122 } 142 }
143 configuration->data.length = kDataSize * 3 * configuration->data.count;
123 return true; 144 return true;
124 } 145 }
125 146
126 bool ReadAccelerometer( 147 bool ReadAccelerometer(
127 scoped_refptr<AccelerometerReader::Reading> reading) { 148 scoped_refptr<AccelerometerReader::Reading> reading,
149 size_t length) {
150 DCHECK(base::MessageLoopForIO::current());
128 // Initiate the trigger to read accelerometers simultaneously 151 // Initiate the trigger to read accelerometers simultaneously
129 int bytes_written = base::WriteFile( 152 int bytes_written = base::WriteFile(
130 base::FilePath(kAccelerometerTriggerPath), "1\n", 2); 153 base::FilePath(kAccelerometerTriggerPath), "1\n", 2);
131 if (bytes_written < 2) { 154 if (bytes_written < 2) {
132 PLOG(ERROR) << "Accelerometer trigger failure: " << bytes_written; 155 PLOG(ERROR) << "Accelerometer trigger failure: " << bytes_written;
133 return false; 156 return false;
134 } 157 }
135 158
136 // Read resulting sample from /dev/cros-ec-accel. 159 // Read resulting sample from /dev/cros-ec-accel.
137 int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath), 160 int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath),
138 reading->data, kTriggerDataLength); 161 reading->data, length);
139 if (bytes_read < static_cast<int>(kTriggerDataLength)) { 162 if (bytes_read < static_cast<int>(length)) {
140 LOG(ERROR) << "Read " << bytes_read << " byte(s), expected " 163 LOG(ERROR) << "Read " << bytes_read << " byte(s), expected "
141 << kTriggerDataLength << " bytes from accelerometer"; 164 << length << " bytes from accelerometer";
142 return false; 165 return false;
143 } 166 }
144 return true; 167 return true;
145 } 168 }
146 169
147 } // namespace 170 } // namespace
148 171
149 AccelerometerReader::ConfigurationData::ConfigurationData() { 172 AccelerometerReader::ConfigurationData::ConfigurationData()
173 : count(0) {
174 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
175 has[i] = false;
176 for (int j = 0; j < 3; ++j) {
177 scale[i][j] = 0;
178 index[i][j] = -1;
179 }
180 }
150 } 181 }
151 182
152 AccelerometerReader::ConfigurationData::~ConfigurationData() { 183 AccelerometerReader::ConfigurationData::~ConfigurationData() {
153 } 184 }
154 185
155 AccelerometerReader::AccelerometerReader( 186 AccelerometerReader::AccelerometerReader(
156 base::TaskRunner* task_runner, 187 base::TaskRunner* file_task_runner,
157 AccelerometerReader::Delegate* delegate) 188 AccelerometerReader::Delegate* delegate)
158 : task_runner_(task_runner), 189 : task_runner_(file_task_runner),
159 delegate_(delegate), 190 delegate_(delegate),
160 configuration_(new AccelerometerReader::Configuration()), 191 configuration_(new AccelerometerReader::Configuration()),
161 weak_factory_(this) { 192 weak_factory_(this) {
162 DCHECK(task_runner_.get()); 193 DCHECK(task_runner_.get());
163 DCHECK(delegate_); 194 DCHECK(delegate_);
164 // Asynchronously detect and initialize the accelerometer to avoid delaying 195 // Asynchronously detect and initialize the accelerometer to avoid delaying
165 // startup. 196 // startup.
166 base::PostTaskAndReplyWithResult(task_runner_.get(), FROM_HERE, 197 base::PostTaskAndReplyWithResult(task_runner_.get(), FROM_HERE,
167 base::Bind(&DetectAndReadAccelerometerConfiguration, configuration_), 198 base::Bind(&DetectAndReadAccelerometerConfiguration, configuration_),
168 base::Bind(&AccelerometerReader::OnInitialized, 199 base::Bind(&AccelerometerReader::OnInitialized,
(...skipping 10 matching lines...) Expand all
179 TriggerRead(); 210 TriggerRead();
180 } 211 }
181 212
182 void AccelerometerReader::TriggerRead() { 213 void AccelerometerReader::TriggerRead() {
183 DCHECK(!task_runner_->RunsTasksOnCurrentThread()); 214 DCHECK(!task_runner_->RunsTasksOnCurrentThread());
184 215
185 scoped_refptr<AccelerometerReader::Reading> reading( 216 scoped_refptr<AccelerometerReader::Reading> reading(
186 new AccelerometerReader::Reading()); 217 new AccelerometerReader::Reading());
187 base::PostTaskAndReplyWithResult(task_runner_.get(), 218 base::PostTaskAndReplyWithResult(task_runner_.get(),
188 FROM_HERE, 219 FROM_HERE,
189 base::Bind(&ReadAccelerometer, reading), 220 base::Bind(&ReadAccelerometer, reading,
221 configuration_->data.length),
190 base::Bind(&AccelerometerReader::OnDataRead, 222 base::Bind(&AccelerometerReader::OnDataRead,
191 weak_factory_.GetWeakPtr(), 223 weak_factory_.GetWeakPtr(),
192 reading)); 224 reading));
193 } 225 }
194 226
195 void AccelerometerReader::OnDataRead( 227 void AccelerometerReader::OnDataRead(
196 scoped_refptr<AccelerometerReader::Reading> reading, 228 scoped_refptr<AccelerometerReader::Reading> reading,
197 bool success) { 229 bool success) {
198 DCHECK(!task_runner_->RunsTasksOnCurrentThread()); 230 DCHECK(!task_runner_->RunsTasksOnCurrentThread());
199 231
200 if (success) { 232 if (success) {
201 int16* values = reinterpret_cast<int16*>(reading->data); 233 for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
202 float lid_scale = kMeanGravity / configuration_->data.lid_scale; 234 if (!configuration_->data.has[i])
203 update_.Set(ui::ACCELEROMETER_SOURCE_SCREEN, 235 continue;
204 -values[configuration_->data.index[4]] * lid_scale, 236
205 values[configuration_->data.index[3]] * lid_scale, 237 int16* values = reinterpret_cast<int16*>(reading->data);
206 values[configuration_->data.index[5]] * lid_scale); 238 update_.Set(static_cast<ui::AccelerometerSource>(i),
207 float base_scale = kMeanGravity / configuration_->data.base_scale; 239 values[configuration_->data.index[i][0]] *
208 update_.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, 240 configuration_->data.scale[i][0],
209 -values[configuration_->data.index[1]] * base_scale, 241 values[configuration_->data.index[i][1]] *
210 -values[configuration_->data.index[0]] * base_scale, 242 configuration_->data.scale[i][1],
211 -values[configuration_->data.index[2]] * base_scale); 243 values[configuration_->data.index[i][2]] *
244 configuration_->data.scale[i][2]);
245 }
212 delegate_->HandleAccelerometerUpdate(update_); 246 delegate_->HandleAccelerometerUpdate(update_);
213 } 247 }
214 248
215 // Trigger another read after the current sampling delay. 249 // Trigger another read after the current sampling delay.
216 base::MessageLoop::current()->PostDelayedTask( 250 base::MessageLoop::current()->PostDelayedTask(
217 FROM_HERE, 251 FROM_HERE,
218 base::Bind(&AccelerometerReader::TriggerRead, 252 base::Bind(&AccelerometerReader::TriggerRead,
219 weak_factory_.GetWeakPtr()), 253 weak_factory_.GetWeakPtr()),
220 base::TimeDelta::FromMilliseconds(kDelayBetweenReadsMs)); 254 base::TimeDelta::FromMilliseconds(kDelayBetweenReadsMs));
221 } 255 }
222 256
223 } // namespace chromeos 257 } // namespace chromeos
OLDNEW
« chrome/browser/ui/ash/ash_init.cc ('K') | « chromeos/accelerometer/accelerometer_reader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698