| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #include "device/generic_sensor/linux/platform_sensor_manager.h" |  | 
| 6 |  | 
| 7 #include "base/strings/string_number_conversions.h" |  | 
| 8 #include "base/threading/thread_restrictions.h" |  | 
| 9 #include "base/threading/thread_task_runner_handle.h" |  | 
| 10 #include "device/generic_sensor/linux/sensor_data_linux.h" |  | 
| 11 |  | 
| 12 namespace device { |  | 
| 13 |  | 
| 14 namespace { |  | 
| 15 |  | 
| 16 std::string StringOrEmptyIfNull(const char* value) { |  | 
| 17   return value ? value : std::string(); |  | 
| 18 } |  | 
| 19 |  | 
| 20 }  // namespace |  | 
| 21 |  | 
| 22 SensorDeviceManager::SensorDeviceManager() |  | 
| 23     : observer_(this), |  | 
| 24       delegate_(nullptr), |  | 
| 25       task_runner_(base::ThreadTaskRunnerHandle::Get()) { |  | 
| 26   thread_checker_.DetachFromThread(); |  | 
| 27 } |  | 
| 28 |  | 
| 29 SensorDeviceManager::~SensorDeviceManager() { |  | 
| 30   DCHECK(thread_checker_.CalledOnValidThread()); |  | 
| 31 } |  | 
| 32 |  | 
| 33 void SensorDeviceManager::Start(Delegate* delegate) { |  | 
| 34   DCHECK(thread_checker_.CalledOnValidThread()); |  | 
| 35   base::ThreadRestrictions::AssertIOAllowed(); |  | 
| 36   DCHECK(!delegate_); |  | 
| 37 |  | 
| 38   delegate_ = delegate; |  | 
| 39 |  | 
| 40   DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |  | 
| 41   observer_.Add(monitor); |  | 
| 42   monitor->Enumerate( |  | 
| 43       base::Bind(&SensorDeviceManager::OnDeviceAdded, base::Unretained(this))); |  | 
| 44 |  | 
| 45   task_runner_->PostTask( |  | 
| 46       FROM_HERE, |  | 
| 47       base::Bind(&SensorDeviceManager::Delegate::OnSensorNodesEnumerated, |  | 
| 48                  base::Unretained(delegate_))); |  | 
| 49 } |  | 
| 50 |  | 
| 51 std::string SensorDeviceManager::GetUdevDeviceGetSubsystem(udev_device* dev) { |  | 
| 52   return StringOrEmptyIfNull(udev_device_get_subsystem(dev)); |  | 
| 53 } |  | 
| 54 |  | 
| 55 std::string SensorDeviceManager::GetUdevDeviceGetSyspath(udev_device* dev) { |  | 
| 56   return StringOrEmptyIfNull(udev_device_get_syspath(dev)); |  | 
| 57 } |  | 
| 58 |  | 
| 59 std::string SensorDeviceManager::GetUdevDeviceGetSysattrValue( |  | 
| 60     udev_device* dev, |  | 
| 61     const std::string& attribute) { |  | 
| 62   return StringOrEmptyIfNull( |  | 
| 63       udev_device_get_sysattr_value(dev, attribute.c_str())); |  | 
| 64 } |  | 
| 65 |  | 
| 66 std::string SensorDeviceManager::GetUdevDeviceGetDevnode(udev_device* dev) { |  | 
| 67   return StringOrEmptyIfNull(udev_device_get_devnode(dev)); |  | 
| 68 } |  | 
| 69 |  | 
| 70 void SensorDeviceManager::OnDeviceAdded(udev_device* dev) { |  | 
| 71   const std::string subsystem = GetUdevDeviceGetSubsystem(dev); |  | 
| 72   if (subsystem.empty() || subsystem.compare("iio") != 0) |  | 
| 73     return; |  | 
| 74 |  | 
| 75   const std::string sysfs_path = GetUdevDeviceGetSyspath(dev); |  | 
| 76   if (sysfs_path.empty()) |  | 
| 77     return; |  | 
| 78 |  | 
| 79   const std::string device_node = GetUdevDeviceGetDevnode(dev); |  | 
| 80   if (device_node.empty()) |  | 
| 81     return; |  | 
| 82 |  | 
| 83   const uint32_t first = static_cast<uint32_t>(mojom::SensorType::FIRST); |  | 
| 84   const uint32_t last = static_cast<uint32_t>(mojom::SensorType::LAST); |  | 
| 85   for (uint32_t i = first; i < last; ++i) { |  | 
| 86     SensorPathsLinux data; |  | 
| 87     mojom::SensorType type = static_cast<mojom::SensorType>(i); |  | 
| 88     if (!InitSensorData(type, &data)) |  | 
| 89       continue; |  | 
| 90 |  | 
| 91     std::vector<base::FilePath> sensor_file_names; |  | 
| 92     for (const std::vector<std::string>& names : data.sensor_file_names) { |  | 
| 93       for (const auto& name : names) { |  | 
| 94         const std::string value = |  | 
| 95             GetUdevDeviceGetSysattrValue(dev, name.c_str()); |  | 
| 96         if (value.empty()) |  | 
| 97           continue; |  | 
| 98         base::FilePath full_path = base::FilePath(sysfs_path).Append(name); |  | 
| 99         sensor_file_names.push_back(full_path); |  | 
| 100         break; |  | 
| 101       } |  | 
| 102     } |  | 
| 103 |  | 
| 104     if (sensor_file_names.empty()) |  | 
| 105       continue; |  | 
| 106 |  | 
| 107     const std::string scaling_value = |  | 
| 108         GetUdevDeviceGetSysattrValue(dev, data.sensor_scale_name.c_str()); |  | 
| 109     // If scaling value is not found, treat it as 1. |  | 
| 110     double sensor_scaling_value = 1; |  | 
| 111     if (!scaling_value.empty()) |  | 
| 112       base::StringToDouble(scaling_value, &sensor_scaling_value); |  | 
| 113 |  | 
| 114     const std::string offset_vallue = |  | 
| 115         GetUdevDeviceGetSysattrValue(dev, data.sensor_offset_file_name.c_str()); |  | 
| 116     // If offset value is not found, treat it as 0. |  | 
| 117     double sensor_offset_value = 0; |  | 
| 118     if (!offset_vallue.empty()) |  | 
| 119       base::StringToDouble(offset_vallue, &sensor_offset_value); |  | 
| 120 |  | 
| 121     const std::string frequency_value = GetUdevDeviceGetSysattrValue( |  | 
| 122         dev, data.sensor_frequency_file_name.c_str()); |  | 
| 123     // If frequency is not found, use default one from SensorPathsLinux struct. |  | 
| 124     double sensor_frequency_value = data.default_configuration.frequency(); |  | 
| 125     // By default, |reporting_mode| is ON_CHANGE. But if platform provides |  | 
| 126     // sampling frequency, the reporting mode is CONTINUOUS. |  | 
| 127     mojom::ReportingMode reporting_mode = mojom::ReportingMode::ON_CHANGE; |  | 
| 128     if (!frequency_value.empty()) { |  | 
| 129       base::StringToDouble(frequency_value, &sensor_frequency_value); |  | 
| 130       reporting_mode = mojom::ReportingMode::CONTINUOUS; |  | 
| 131     } |  | 
| 132 |  | 
| 133     // Update own cache of known sensor devices. |  | 
| 134     if (!base::ContainsKey(sensors_by_node_, device_node)) |  | 
| 135       sensors_by_node_[device_node] = data.type; |  | 
| 136 |  | 
| 137     std::unique_ptr<SensorInfoLinux> device(new SensorInfoLinux( |  | 
| 138         device_node, sensor_frequency_value, sensor_scaling_value, |  | 
| 139         sensor_offset_value, reporting_mode, data.apply_scaling_func, |  | 
| 140         std::move(sensor_file_names))); |  | 
| 141     task_runner_->PostTask( |  | 
| 142         FROM_HERE, base::Bind(&SensorDeviceManager::Delegate::OnDeviceAdded, |  | 
| 143                               base::Unretained(delegate_), data.type, |  | 
| 144                               base::Passed(&device))); |  | 
| 145 |  | 
| 146     // One |dev| can represent more than one sensor. |  | 
| 147     // For example, there is an accelerometer and gyroscope represented by one |  | 
| 148     // |dev| in Chrome OS, kernel < 3.18. Thus, iterate through all possible |  | 
| 149     // types of sensors. |  | 
| 150   } |  | 
| 151 } |  | 
| 152 |  | 
| 153 void SensorDeviceManager::OnDeviceRemoved(udev_device* dev) { |  | 
| 154   const std::string subsystem = GetUdevDeviceGetSubsystem(dev); |  | 
| 155   if (subsystem.empty() || subsystem.compare("iio") != 0) |  | 
| 156     return; |  | 
| 157 |  | 
| 158   const std::string device_node = GetUdevDeviceGetDevnode(dev); |  | 
| 159   if (device_node.empty()) |  | 
| 160     return; |  | 
| 161 |  | 
| 162   auto sensor = sensors_by_node_.find(device_node); |  | 
| 163   if (sensor == sensors_by_node_.end()) |  | 
| 164     return; |  | 
| 165   mojom::SensorType type = sensor->second; |  | 
| 166   sensors_by_node_.erase(sensor); |  | 
| 167 |  | 
| 168   task_runner_->PostTask( |  | 
| 169       FROM_HERE, base::Bind(&SensorDeviceManager::Delegate::OnDeviceRemoved, |  | 
| 170                             base::Unretained(delegate_), type, device_node)); |  | 
| 171 } |  | 
| 172 |  | 
| 173 }  // namespace device |  | 
| OLD | NEW | 
|---|