 Chromium Code Reviews
 Chromium Code Reviews Issue 2533793002:
  [sensors](CrOS/Linux) Implement Sensor device manager for sensors  (Closed)
    
  
    Issue 2533793002:
  [sensors](CrOS/Linux) Implement Sensor device manager for sensors  (Closed) 
  | Index: device/generic_sensor/linux/platform_sensor_reader_linux.cc | 
| diff --git a/device/generic_sensor/linux/platform_sensor_reader_linux.cc b/device/generic_sensor/linux/platform_sensor_reader_linux.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..a090d2139b99b99e702d84e4001cbb868a5892dc | 
| --- /dev/null | 
| +++ b/device/generic_sensor/linux/platform_sensor_reader_linux.cc | 
| @@ -0,0 +1,164 @@ | 
| +// Copyright 2016 The Chromium Authors. All rights reserved. | 
| 
Reilly Grant (use Gerrit)
2016/11/29 20:19:56
Put this in //device/generic_sensor alongside plat
 
maksims (do not use this acc)
2016/12/05 13:06:59
Done.
 | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "device/generic_sensor/linux/platform_sensor_reader_linux.h" | 
| + | 
| +#include "base/files/file_util.h" | 
| +#include "base/strings/string_number_conversions.h" | 
| +#include "base/strings/string_util.h" | 
| +#include "base/threading/thread_restrictions.h" | 
| +#include "base/timer/timer.h" | 
| +#include "device/generic_sensor/platform_sensor_linux.h" | 
| +#include "device/generic_sensor/platform_sensor_manager_linux.h" | 
| +#include "device/generic_sensor/public/cpp/sensor_reading.h" | 
| + | 
| +namespace device { | 
| + | 
| +class PollingSensorReader : public SensorReader { | 
| + public: | 
| + PollingSensorReader( | 
| + double scaling_value, | 
| + double offset_value, | 
| + const SensorDataLinux::ReaderFunctor& apply_scaling_func, | 
| + std::vector<base::FilePath> sensor_file_paths, | 
| + scoped_refptr<base::SingleThreadTaskRunner> polling_task_runner); | 
| + ~PollingSensorReader() override; | 
| + | 
| + // SensorReader implements: | 
| + bool StartFetchingData(const PlatformSensorConfiguration& configuration, | 
| + PlatformSensorLinux* sensor) override; | 
| + void StopFetchingData() override; | 
| + | 
| + private: | 
| + // Initializes a read timer. | 
| + void InitializeTimer(const PlatformSensorConfiguration& configuration); | 
| + | 
| + // Polls data and sends it to a |sensor_|. | 
| + void PollForData(); | 
| + | 
| + // Paths to sensor read files. | 
| + const std::vector<base::FilePath> sensor_file_paths_; | 
| + | 
| + // Scaling value that are applied to raw data from sensors. | 
| + const double scaling_value_; | 
| + | 
| + // Offset value. | 
| + const double offset_value_; | 
| + | 
| + // Used to apply scalings and invert signs if needed. | 
| + const SensorDataLinux::ReaderFunctor apply_scaling_func_; | 
| + | 
| + // Owned pointer to a timer. Will be deleted on a polling thread once | 
| + // destructor is called. | 
| + base::RepeatingTimer* timer_; | 
| + | 
| + base::WeakPtrFactory<PollingSensorReader> weak_factory_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(PollingSensorReader); | 
| +}; | 
| + | 
| +PollingSensorReader::PollingSensorReader( | 
| + double scaling_value, | 
| + double offset_value, | 
| + const SensorDataLinux::ReaderFunctor& apply_scaling_func, | 
| + std::vector<base::FilePath> sensor_file_paths, | 
| + scoped_refptr<base::SingleThreadTaskRunner> polling_task_runner) | 
| + : SensorReader(polling_task_runner), | 
| + sensor_file_paths_(std::move(sensor_file_paths)), | 
| + scaling_value_(scaling_value), | 
| + offset_value_(offset_value), | 
| + apply_scaling_func_(apply_scaling_func), | 
| + timer_(new base::RepeatingTimer()), | 
| + weak_factory_(this) {} | 
| + | 
| +PollingSensorReader::~PollingSensorReader() { | 
| + polling_task_runner_->DeleteSoon(FROM_HERE, timer_); | 
| +} | 
| + | 
| +bool PollingSensorReader::StartFetchingData( | 
| + const PlatformSensorConfiguration& configuration, | 
| + PlatformSensorLinux* sensor) { | 
| + DCHECK(!sensor_); | 
| + sensor_ = sensor; | 
| + return polling_task_runner_->PostTask( | 
| + FROM_HERE, base::Bind(&PollingSensorReader::InitializeTimer, | 
| + weak_factory_.GetWeakPtr(), configuration)); | 
| +} | 
| + | 
| +void PollingSensorReader::StopFetchingData() { | 
| + sensor_ = nullptr; | 
| + timer_->Stop(); | 
| +} | 
| + | 
| +void PollingSensorReader::InitializeTimer( | 
| + const PlatformSensorConfiguration& configuration) { | 
| + DCHECK(polling_task_runner_->BelongsToCurrentThread()); | 
| + timer_->Start(FROM_HERE, base::TimeDelta::FromMicroseconds( | 
| + base::Time::kMicrosecondsPerSecond / | 
| + configuration.frequency()), | 
| + this, &PollingSensorReader::PollForData); | 
| +} | 
| + | 
| +void PollingSensorReader::PollForData() { | 
| + DCHECK(polling_task_runner_->BelongsToCurrentThread()); | 
| + base::ThreadRestrictions::AssertIOAllowed(); | 
| + | 
| + SensorReading readings; | 
| + DCHECK_LE(sensor_file_paths_.size(), arraysize(readings.values)); | 
| + int i = 0; | 
| + for (const auto& path : sensor_file_paths_) { | 
| + std::string new_read_value; | 
| + if (!base::ReadFileToString(path, &new_read_value)) { | 
| + NotifyReadError(); | 
| + StopFetchingData(); | 
| + return; | 
| + } | 
| + | 
| + double new_value = 0; | 
| + base::TrimWhitespaceASCII(new_read_value, base::TRIM_ALL, &new_read_value); | 
| + if (!base::StringToDouble(new_read_value, &new_value)) { | 
| + NotifyReadError(); | 
| + StopFetchingData(); | 
| + return; | 
| + } | 
| + readings.values[i++] = new_value; | 
| + } | 
| + if (!apply_scaling_func_.is_null()) | 
| + apply_scaling_func_.Run(scaling_value_, offset_value_, readings); | 
| + | 
| + if (sensor_) { | 
| + task_runner_->PostTask( | 
| + FROM_HERE, base::Bind(&PlatformSensorLinux::UpdatePlatformSensorReading, | 
| + base::Unretained(sensor_), readings)); | 
| + } | 
| +} | 
| + | 
| +// static | 
| +std::unique_ptr<SensorReader> SensorReader::Create( | 
| + SensorDeviceLinux* sensor_device, | 
| + scoped_refptr<base::SingleThreadTaskRunner> polling_thread_task_runner) { | 
| + // TODO(maksims): implement triggered reading. At the moment, | 
| + // only polling read is supported. | 
| + return base::MakeUnique<PollingSensorReader>( | 
| + sensor_device->device_scaling_value, sensor_device->device_offset_value, | 
| + sensor_device->apply_scaling_func, sensor_device->device_reading_files, | 
| + polling_thread_task_runner); | 
| +} | 
| + | 
| +SensorReader::SensorReader( | 
| + scoped_refptr<base::SingleThreadTaskRunner> polling_task_runner) | 
| + : sensor_(nullptr), | 
| + polling_task_runner_(polling_task_runner), | 
| + task_runner_(base::ThreadTaskRunnerHandle::Get()) {} | 
| + | 
| +SensorReader::~SensorReader() = default; | 
| + | 
| +void SensorReader::NotifyReadError() { | 
| + if (sensor_) | 
| + task_runner_->PostTask( | 
| + FROM_HERE, base::Bind(&PlatformSensorLinux::NotifyPlatformSensorError, | 
| + base::Unretained(sensor_))); | 
| +} | 
| + | 
| +} // namespace device |