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