1 /*
2 * Copyright (C) 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 #define LOG_TAG "GoogleIIOSensorSubHal"
17
18 #include "SensorsSubHal.h"
19 #include <android/hardware/sensors/2.0/types.h>
20 #include <log/log.h>
21
sensorsHalGetSubHal(uint32_t * version)22 ISensorsSubHal* sensorsHalGetSubHal(uint32_t* version) {
23 static ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal subHal;
24 *version = SUB_HAL_2_0_VERSION;
25 return &subHal;
26 }
27
28 namespace android {
29 namespace hardware {
30 namespace sensors {
31 namespace V2_0 {
32 namespace subhal {
33 namespace implementation {
34
35 using ::android::hardware::Void;
36 using ::android::hardware::sensors::V1_0::Event;
37 using ::android::hardware::sensors::V1_0::RateLevel;
38 using ::android::hardware::sensors::V1_0::SharedMemInfo;
39 using ::android::hardware::sensors::V2_0::SensorTimeout;
40 using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
41 using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;
42 using ::sensor::hal::configuration::V1_0::Sensor;
43 using ::sensor::hal::configuration::V1_0::SensorHalConfiguration;
44
45 #define SENSOR_XML_CONFIG_FILE_NAME "sensor_hal_configuration.xml"
46 static const char* gSensorConfigLocationList[] = {"/odm/etc/sensors/", "/vendor/etc/sensors/"};
47 static const int gSensorConfigLocationListSize =
48 (sizeof(gSensorConfigLocationList) / sizeof(gSensorConfigLocationList[0]));
49
50 #define MODULE_NAME "android.hardware.sensors@2.0-Google-IIO-Subhal"
51
readSensorsConfigFromXml()52 static std::optional<std::vector<Sensor>> readSensorsConfigFromXml() {
53 for (int i = 0; i < gSensorConfigLocationListSize; i++) {
54 const auto sensor_config_file =
55 std::string(gSensorConfigLocationList[i]) + SENSOR_XML_CONFIG_FILE_NAME;
56 auto sensorConfig = ::sensor::hal::configuration::V1_0::read(sensor_config_file.c_str());
57 if (sensorConfig) {
58 auto modulesList = sensorConfig->getFirstModules()->get_module();
59 for (auto module : modulesList) {
60 if (module.getHalName().compare(MODULE_NAME) == 0) {
61 return module.getFirstSensors()->getSensor();
62 }
63 }
64 }
65 }
66 ALOGI("Could not find the sensors configuration for module %s", MODULE_NAME);
67 return std::nullopt;
68 }
69
getSensorConfiguration(const std::vector<Sensor> & sensor_list,const std::string & name,SensorType type)70 static std::optional<std::vector<Configuration>> getSensorConfiguration(
71 const std::vector<Sensor>& sensor_list, const std::string& name, SensorType type) {
72 for (auto sensor : sensor_list) {
73 if ((name.compare(sensor.getName()) == 0) && (type == (SensorType)sensor.getType())) {
74 return sensor.getConfiguration();
75 }
76 }
77 ALOGI("Could not find the sensor configuration for %s ", name.c_str());
78 return std::nullopt;
79 }
80
isSensorSupported(iio_device_data * sensor)81 static bool isSensorSupported(iio_device_data* sensor) {
82 #define SENSOR_SUPPORTED(SENSOR_NAME, SENSOR_TYPE) \
83 { .name = SENSOR_NAME, .type = SENSOR_TYPE, }
84 static const std::vector<sensors_supported_hal> supported_sensors = {
85 SENSOR_SUPPORTED("scmi.iio.accel", SensorType::ACCELEROMETER),
86 SENSOR_SUPPORTED("scmi.iio.gyro", SensorType::GYROSCOPE),
87 };
88 #undef SENSOR_SUPPORTED
89
90 if (!sensor) return false;
91
92 auto iter = std::find_if(
93 supported_sensors.begin(), supported_sensors.end(),
94 [&sensor](const auto& candidate) -> bool { return candidate.name == sensor->name; });
95 if (iter == supported_sensors.end()) return false;
96
97 sensor->type = iter->type;
98 return true;
99 }
100
SensorsSubHal()101 SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {
102 int err;
103 std::vector<iio_device_data> iio_devices;
104 const auto sensors_config_list = readSensorsConfigFromXml();
105 err = load_iio_devices(DEFAULT_IIO_DIR, &iio_devices, isSensorSupported);
106 if (err == 0) {
107 for (auto& iio_device : iio_devices) {
108 err = scan_elements(iio_device.sysfspath, &iio_device);
109 if (err == 0) {
110 err = enable_sensor(iio_device.sysfspath, false);
111 if (err == 0) {
112 std::optional<std::vector<Configuration>> sensor_configuration = std::nullopt;
113 if (sensors_config_list)
114 sensor_configuration = getSensorConfiguration(
115 *sensors_config_list, iio_device.name, iio_device.type);
116
117 if (iio_device.channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) {
118 AddSensor(iio_device, sensor_configuration);
119 } else {
120 ALOGE("SensorsSubHal(): Unexpected number of channels for sensor %s",
121 iio_device.sysfspath.c_str());
122 }
123 } else {
124 ALOGE("SensorsSubHal(): Error in enabling_sensor %s to %d error code %d",
125 iio_device.sysfspath.c_str(), false, err);
126 }
127 } else {
128 ALOGE("SensorsSubHal(): Error in scanning channels for IIO device %s error code %d",
129 iio_device.sysfspath.c_str(), err);
130 }
131 }
132 } else {
133 ALOGE("SensorsSubHal: load_iio_devices returned error %d", err);
134 }
135 }
136
137 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
getSensorsList(getSensorsList_cb _hidl_cb)138 Return<void> SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
139 std::vector<SensorInfo> sensors;
140 for (const auto& sensor : mSensors) {
141 SensorInfo sensorInfo = sensor.second->getSensorInfo();
142 sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
143 sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_REPORT);
144 sensors.push_back(sensorInfo);
145 }
146
147 _hidl_cb(sensors);
148 return Void();
149 }
150
setOperationMode(OperationMode mode)151 Return<Result> SensorsSubHal::setOperationMode(OperationMode mode) {
152 for (auto& sensor : mSensors) {
153 sensor.second->setOperationMode(mode);
154 }
155 mCurrentOperationMode = mode;
156 return Result::OK;
157 }
158
activate(int32_t sensorHandle,bool enabled)159 Return<Result> SensorsSubHal::activate(int32_t sensorHandle, bool enabled) {
160 auto sensor = mSensors.find(sensorHandle);
161 if (sensor != mSensors.end()) {
162 sensor->second->activate(enabled);
163 return Result::OK;
164 }
165 return Result::BAD_VALUE;
166 }
167
batch(int32_t sensorHandle,int64_t samplingPeriodNs,int64_t)168 Return<Result> SensorsSubHal::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
169 int64_t /* maxReportLatencyNs */) {
170 auto sensor = mSensors.find(sensorHandle);
171 if (sensor != mSensors.end()) {
172 sensor->second->batch(samplingPeriodNs);
173 return Result::OK;
174 }
175 return Result::BAD_VALUE;
176 }
177
flush(int32_t sensorHandle)178 Return<Result> SensorsSubHal::flush(int32_t sensorHandle) {
179 auto sensor = mSensors.find(sensorHandle);
180 if (sensor != mSensors.end()) {
181 return sensor->second->flush();
182 }
183 return Result::BAD_VALUE;
184 }
185
injectSensorData(const Event &)186 Return<Result> SensorsSubHal::injectSensorData(const Event& /* event */) {
187 return Result::INVALID_OPERATION;
188 }
189
registerDirectChannel(const SharedMemInfo &,registerDirectChannel_cb _hidl_cb)190 Return<void> SensorsSubHal::registerDirectChannel(const SharedMemInfo& /* mem */,
191 registerDirectChannel_cb _hidl_cb) {
192 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
193 return Return<void>();
194 }
195
unregisterDirectChannel(int32_t)196 Return<Result> SensorsSubHal::unregisterDirectChannel(int32_t /* channelHandle */) {
197 return Result::INVALID_OPERATION;
198 }
199
configDirectReport(int32_t,int32_t,RateLevel,configDirectReport_cb _hidl_cb)200 Return<void> SensorsSubHal::configDirectReport(int32_t /* sensorHandle */,
201 int32_t /* channelHandle */, RateLevel /* rate */,
202 configDirectReport_cb _hidl_cb) {
203 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
204 return Return<void>();
205 }
206
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & args)207 Return<void> SensorsSubHal::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
208 if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
209 ALOGE("%s: missing fd for writing", __FUNCTION__);
210 return Void();
211 }
212 FILE* out = fdopen(dup(fd->data[0]), "w");
213
214 if (args.size() != 0) {
215 fprintf(out,
216 "Note: sub-HAL %s currently does not support args. Input arguments are "
217 "ignored.\n",
218 getName().c_str());
219 }
220
221 std::ostringstream stream;
222 stream << "Available sensors:" << std::endl;
223 for (auto& sensor : mSensors) {
224 SensorInfo info = sensor.second->getSensorInfo();
225 HWSensorBase* hwSensor = static_cast<HWSensorBase*>(sensor.second.get());
226 stream << "Name: " << info.name << std::endl;
227 stream << "handle: " << info.sensorHandle << std::endl;
228 stream << "resolution: " << info.resolution << " minDelay: " << info.minDelay
229 << " maxDelay:" << info.maxDelay << std::endl;
230 stream << "iio path" << hwSensor->mIioData.sysfspath << std::endl;
231 }
232
233 stream << std::endl;
234
235 fprintf(out, "%s", stream.str().c_str());
236
237 fclose(out);
238 return Return<void>();
239 }
240
initialize(const sp<IHalProxyCallback> & halProxyCallback)241 Return<Result> SensorsSubHal::initialize(const sp<IHalProxyCallback>& halProxyCallback) {
242 mCallback = halProxyCallback;
243 setOperationMode(OperationMode::NORMAL);
244 return Result::OK;
245 }
246
postEvents(const std::vector<Event> & events,bool wakeup)247 void SensorsSubHal::postEvents(const std::vector<Event>& events, bool wakeup) {
248 ScopedWakelock wakelock = mCallback->createScopedWakelock(wakeup);
249 mCallback->postEvents(events, std::move(wakelock));
250 }
AddSensor(const struct iio_device_data & iio_data,const std::optional<std::vector<Configuration>> & config)251 void SensorsSubHal::AddSensor(const struct iio_device_data& iio_data,
252 const std::optional<std::vector<Configuration>>& config) {
253 HWSensorBase* sensor = HWSensorBase::buildSensor(mNextHandle++ /* sensorHandle */,
254 this /* callback */, iio_data, config);
255 if (sensor != nullptr)
256 mSensors[sensor->getSensorInfo().sensorHandle] = std::unique_ptr<SensorBase>(sensor);
257 else
258 ALOGE("Unable to add sensor %s as buildSensor returned null", iio_data.name.c_str());
259 }
260
261 } // namespace implementation
262 } // namespace subhal
263 } // namespace V2_0
264 } // namespace sensors
265 } // namespace hardware
266 } // namespace android
267