• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android-base/file.h>
18 #include <android/hardware/sensors/2.0/types.h>
19 #include <gtest/gtest.h>
20 #include <sys/stat.h>
21 #include <fstream>
22 #include <iostream>
23 #include <map>
24 #include <sstream>
25 
26 #include "iio_utils.h"
27 
28 using ::android::hardware::sensors::V1_0::SensorType;
29 using android::hardware::sensors::V2_0::subhal::implementation::iio_device_data;
30 using android::hardware::sensors::V2_0::subhal::implementation::load_iio_devices;
31 using android::hardware::sensors::V2_0::subhal::implementation::sensors_supported_hal;
32 
sensorFilter(iio_device_data * dev)33 static bool sensorFilter(iio_device_data* dev) {
34     static std::map<std::string, SensorType> KNOWN_SENSORS = {
35             {"scmi.iio.accel", SensorType::ACCELEROMETER},
36     };
37 
38     if (!dev) return false;
39 
40     const auto iter = KNOWN_SENSORS.find(dev->name);
41     if (iter == KNOWN_SENSORS.end()) return false;
42 
43     dev->type = iter->second;
44     return true;
45 }
46 
TEST(IIoUtilsTest,ScanEmptyDirectory)47 TEST(IIoUtilsTest, ScanEmptyDirectory) {
48     TemporaryDir td;
49     std::vector<iio_device_data> iio_devices;
50     const auto err = load_iio_devices(td.path, &iio_devices, sensorFilter);
51     ASSERT_EQ(0, err);
52     ASSERT_EQ(0, iio_devices.size());
53 }
54 
concatPaths(const std::string & a,const std::string & b)55 static std::string concatPaths(const std::string& a, const std::string& b) {
56     std::stringstream ss;
57     ss << a << '/' << b;
58     return ss.str();
59 }
60 
61 template <typename T>
writeFile(const std::string & path,const T & content,bool nl=true)62 static bool writeFile(const std::string& path, const T& content, bool nl = true) {
63     std::stringstream ss;
64     ss << content;
65 
66     std::ofstream f;
67     f.open(path);
68     if (!f) return false;
69     f << ss.str();
70     if (nl) f << '\n';
71     f.close();
72     return true;
73 }
74 
75 template <typename U>
writeFile(const std::string & path,const std::vector<U> & content,bool nl=true)76 static bool writeFile(const std::string& path, const std::vector<U>& content, bool nl = true) {
77     std::stringstream ss;
78     bool first = true;
79     for (const auto& item : content) {
80         if (!first) ss << ' ';
81         ss << item;
82         if (first) first = false;
83     }
84 
85     return writeFile(path, ss.str(), nl);
86 }
87 
writeAccelDevice(const std::string & td_path,const iio_device_data & dev)88 static bool writeAccelDevice(const std::string& td_path, const iio_device_data& dev) {
89     std::stringstream ss;
90     ss << concatPaths(td_path, "iio:device") << std::to_string(dev.iio_dev_num);
91     const std::string dev_path(ss.str());
92 
93     int err = mkdir(dev_path.c_str(), 0777);
94     if (err != 0) return false;
95 
96     if (!writeFile(concatPaths(dev_path, "name"), dev.name)) return false;
97     if (!writeFile(concatPaths(dev_path, "in_accel_x_scale"), dev.scale)) return false;
98     if (!writeFile(concatPaths(dev_path, "in_accel_y_scale"), dev.scale)) return false;
99     if (!writeFile(concatPaths(dev_path, "in_accel_z_scale"), dev.scale)) return false;
100     if (!writeFile(concatPaths(dev_path, "in_accel_raw_available"),
101                    "[-78381056.000000000 2392.000000000 78378664.000000000]"))
102         return false;
103     if (!writeFile(concatPaths(dev_path, "in_accel_sampling_frequency_available"),
104                    dev.sampling_freq_avl))
105         return false;
106 
107     return true;
108 }
109 
110 // sets up a new iio:device<id> device with default parameters for an accelerometer
createDefaultAccelerometerDevice(int id)111 static iio_device_data createDefaultAccelerometerDevice(int id) {
112     iio_device_data dev;
113     dev.type = SensorType::ACCELEROMETER;
114     dev.iio_dev_num = id;
115     dev.name = "scmi.iio.accel";
116     dev.sampling_freq_avl = {12.500000, 26.000364, 52.002080, 104.004160, 208.003993};
117     dev.resolution = 2392;
118     dev.scale = 0.000001000f;
119     dev.max_range = 78378664;
120 
121     return dev;
122 }
123 
TEST(IioUtilsTest,LoadValidSensor)124 TEST(IioUtilsTest, LoadValidSensor) {
125     TemporaryDir td;
126     const std::string td_path(td.path);
127     const auto dev_model = createDefaultAccelerometerDevice(0);
128     bool ok = writeAccelDevice(td_path, dev_model);
129     ASSERT_TRUE(ok);
130 
131     std::vector<iio_device_data> iio_devices;
132     const auto err = load_iio_devices(td_path, &iio_devices, sensorFilter);
133     ASSERT_EQ(0, err);
134     ASSERT_EQ(1, iio_devices.size());
135 
136     const auto& accel(iio_devices[0]);
137 
138     EXPECT_EQ(SensorType::ACCELEROMETER, accel.type);
139     EXPECT_EQ("scmi.iio.accel", accel.name);
140     EXPECT_EQ(0, accel.iio_dev_num);
141 
142     EXPECT_NEAR(dev_model.resolution, accel.resolution, 0.0002);
143     EXPECT_NEAR(dev_model.scale, accel.scale, 0.0002);
144     EXPECT_EQ(dev_model.max_range, accel.max_range);
145 
146     EXPECT_EQ(dev_model.sampling_freq_avl.size(), accel.sampling_freq_avl.size());
147     for (size_t i = 0; i < dev_model.sampling_freq_avl.size(); ++i) {
148         if (i >= accel.sampling_freq_avl.size()) break;
149         EXPECT_NEAR(dev_model.sampling_freq_avl[i], accel.sampling_freq_avl[i], 0.0002);
150     }
151 }
152