• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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