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