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