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 #include "SensorsSubHal.h"
17 #include <android/hardware/sensors/2.0/types.h>
18 #include <log/log.h>
19 
sensorsHalGetSubHal(uint32_t * version)20 ISensorsSubHal* sensorsHalGetSubHal(uint32_t* version) {
21     static ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal subHal;
22     *version = SUB_HAL_2_0_VERSION;
23     return &subHal;
24 }
25 
26 namespace android {
27 namespace hardware {
28 namespace sensors {
29 namespace V2_0 {
30 namespace subhal {
31 namespace implementation {
32 
33 using ::android::hardware::Void;
34 using ::android::hardware::sensors::V1_0::Event;
35 using ::android::hardware::sensors::V1_0::OperationMode;
36 using ::android::hardware::sensors::V1_0::RateLevel;
37 using ::android::hardware::sensors::V1_0::Result;
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 
43 #define SENSOR_SUPPORTED(SENSOR_NAME, SENSOR_TYPE) \
44     { .name = SENSOR_NAME, .type = SENSOR_TYPE, }
45 
46 static const std::vector<sensors_supported_hal> sensors_supported = {
47         SENSOR_SUPPORTED("scmi.iio.accel", SensorType::ACCELEROMETER),
48         SENSOR_SUPPORTED("scmi.iio.gyro", SensorType::GYROSCOPE),
49 };
50 
SensorsSubHal()51 SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {
52     int err;
53     std::vector<iio_device_data> iio_devices;
54     err = load_iio_devices(&iio_devices, sensors_supported);
55     if (err == 0) {
56         for (auto i = 0u; i < iio_devices.size(); i++) {
57             err = scan_elements(iio_devices[i].sysfspath, &iio_devices[i]);
58             if (err == 0) {
59                 err = enable_sensor(iio_devices[i].sysfspath, false);
60                 if (err == 0) {
61                     switch (iio_devices[i].type) {
62                         case SensorType::ACCELEROMETER:
63                             if (iio_devices[i].channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) {
64                                 AddSensor<Accelerometer>(iio_devices[i]);
65                             } else {
66                                 ALOGE("Unexpected number of channels for Accelerometer");
67                             }
68                             break;
69 
70                         case SensorType::GYROSCOPE:
71                             if (iio_devices[i].channelInfo.size() == NUM_OF_CHANNEL_SUPPORTED) {
72                                 AddSensor<Gyroscope>(iio_devices[i]);
73                             } else {
74                                 ALOGE("Unexpected number fo channels for Gyroscope");
75                             }
76                             break;
77 
78                         default:
79                             break;
80                     }
81                 } else {
82                     ALOGE("SensorsSubHal(): Error in enabling_sensor %s to %d error code %d",
83                           iio_devices[i].sysfspath.c_str(), false, err);
84                 }
85             } else {
86                 ALOGE("SensorsSubHal(): Error in scanning channels for IIO device %s error code %d",
87                       iio_devices[i].sysfspath.c_str(), err);
88             }
89         }
90     } else {
91         ALOGE("SensorsSubHal: load_iio_devices returned error %d", err);
92     }
93 }
94 
95 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
getSensorsList(getSensorsList_cb _hidl_cb)96 Return<void> SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
97     std::vector<SensorInfo> sensors;
98     for (const auto& sensor : mSensors) {
99         SensorInfo sensorInfo = sensor.second->getSensorInfo();
100         sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
101         sensorInfo.flags &= ~static_cast<uint32_t>(V1_0::SensorFlagBits::MASK_DIRECT_REPORT);
102         sensors.push_back(sensorInfo);
103     }
104 
105     _hidl_cb(sensors);
106     return Void();
107 }
108 
setOperationMode(OperationMode mode)109 Return<Result> SensorsSubHal::setOperationMode(OperationMode mode) {
110     for (auto& sensor : mSensors) {
111         sensor.second->setOperationMode(mode);
112     }
113     mCurrentOperationMode = mode;
114     return Result::OK;
115 }
116 
activate(int32_t sensorHandle,bool enabled)117 Return<Result> SensorsSubHal::activate(int32_t sensorHandle, bool enabled) {
118     auto sensor = mSensors.find(sensorHandle);
119     if (sensor != mSensors.end()) {
120         sensor->second->activate(enabled);
121         return Result::OK;
122     }
123     return Result::BAD_VALUE;
124 }
125 
batch(int32_t sensorHandle,int64_t samplingPeriodNs,int64_t)126 Return<Result> SensorsSubHal::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
127                                     int64_t /* maxReportLatencyNs */) {
128     auto sensor = mSensors.find(sensorHandle);
129     if (sensor != mSensors.end()) {
130         sensor->second->batch(samplingPeriodNs);
131         return Result::OK;
132     }
133     return Result::BAD_VALUE;
134 }
135 
flush(int32_t sensorHandle)136 Return<Result> SensorsSubHal::flush(int32_t sensorHandle) {
137     auto sensor = mSensors.find(sensorHandle);
138     if (sensor != mSensors.end()) {
139         return sensor->second->flush();
140     }
141     return Result::BAD_VALUE;
142 }
143 
injectSensorData(const Event &)144 Return<Result> SensorsSubHal::injectSensorData(const Event& /* event */) {
145     return Result::INVALID_OPERATION;
146 }
147 
registerDirectChannel(const SharedMemInfo &,registerDirectChannel_cb _hidl_cb)148 Return<void> SensorsSubHal::registerDirectChannel(const SharedMemInfo& /* mem */,
149                                                   registerDirectChannel_cb _hidl_cb) {
150     _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
151     return Return<void>();
152 }
153 
unregisterDirectChannel(int32_t)154 Return<Result> SensorsSubHal::unregisterDirectChannel(int32_t /* channelHandle */) {
155     return Result::INVALID_OPERATION;
156 }
157 
configDirectReport(int32_t,int32_t,RateLevel,configDirectReport_cb _hidl_cb)158 Return<void> SensorsSubHal::configDirectReport(int32_t /* sensorHandle */,
159                                                int32_t /* channelHandle */, RateLevel /* rate */,
160                                                configDirectReport_cb _hidl_cb) {
161     _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
162     return Return<void>();
163 }
164 
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & args)165 Return<void> SensorsSubHal::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
166     if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
167         ALOGE("%s: missing fd for writing", __FUNCTION__);
168         return Void();
169     }
170     FILE* out = fdopen(dup(fd->data[0]), "w");
171 
172     if (args.size() != 0) {
173         fprintf(out,
174                 "Note: sub-HAL %s currently does not support args. Input arguments are "
175                 "ignored.\n",
176                 getName().c_str());
177     }
178 
179     std::ostringstream stream;
180     stream << "Available sensors:" << std::endl;
181     for (auto& sensor : mSensors) {
182         SensorInfo info = sensor.second->getSensorInfo();
183         HWSensorBase* hwSensor = static_cast<HWSensorBase*>(sensor.second.get());
184         stream << "Name: " << info.name << std::endl;
185         stream << "handle: " << info.sensorHandle << std::endl;
186         stream << "resolution: " << info.resolution << " minDelay: " << info.minDelay
187                << " maxDelay:" << info.maxDelay << std::endl;
188         stream << "iio path" << hwSensor->miio_data.sysfspath << std::endl;
189     }
190 
191     stream << std::endl;
192 
193     fprintf(out, "%s", stream.str().c_str());
194 
195     fclose(out);
196     return Return<void>();
197 }
198 
initialize(const sp<IHalProxyCallback> & halProxyCallback)199 Return<Result> SensorsSubHal::initialize(const sp<IHalProxyCallback>& halProxyCallback) {
200     mCallback = halProxyCallback;
201     setOperationMode(OperationMode::NORMAL);
202     return Result::OK;
203 }
204 
postEvents(const std::vector<Event> & events,bool wakeup)205 void SensorsSubHal::postEvents(const std::vector<Event>& events, bool wakeup) {
206     ScopedWakelock wakelock = mCallback->createScopedWakelock(wakeup);
207     mCallback->postEvents(events, std::move(wakelock));
208 }
209 
210 }  // namespace implementation
211 }  // namespace subhal
212 }  // namespace V2_0
213 }  // namespace sensors
214 }  // namespace hardware
215 }  // namespace android
216