blob: 7237bc8e0d5d331b0cd665fe9f9e3fecc2b49258 [file] [log] [blame]
Mathias Agopianf001c922010-11-11 17:58:51 -08001/*
2 * Copyright (C) 2010 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 */
Peng Xu3889e6e2017-03-02 19:10:38 -080016#include "SensorDevice.h"
17#include "SensorService.h"
Mathias Agopianf001c922010-11-11 17:58:51 -080018
Steven Morelandd15c0302016-12-20 11:14:50 -080019#include <android-base/logging.h>
Peng Xu3889e6e2017-03-02 19:10:38 -080020#include <sensors/convert.h>
Steven Moreland2716e112018-02-23 14:57:20 -080021#include <cutils/atomic.h>
Ashutosh Joshi5cafc1e2017-02-09 21:44:04 +000022#include <utils/Errors.h>
23#include <utils/Singleton.h>
Steven Morelandd3335112016-12-20 11:14:50 -080024
Peng Xu3889e6e2017-03-02 19:10:38 -080025#include <chrono>
26#include <cinttypes>
27#include <thread>
Steven Morelandd15c0302016-12-20 11:14:50 -080028
Brian Stack12f4d322018-09-14 16:18:59 -070029using namespace android::hardware::sensors;
Steven Morelandd15c0302016-12-20 11:14:50 -080030using namespace android::hardware::sensors::V1_0;
31using namespace android::hardware::sensors::V1_0::implementation;
Peng Xu1a00e2d2017-09-27 23:08:30 -070032using android::hardware::hidl_vec;
33using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
Peng Xu2bec6232016-07-01 17:13:10 -070034
Mathias Agopianf001c922010-11-11 17:58:51 -080035namespace android {
36// ---------------------------------------------------------------------------
Mathias Agopianf001c922010-11-11 17:58:51 -080037
38ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39
Steven Morelandd15c0302016-12-20 11:14:50 -080040static status_t StatusFromResult(Result result) {
41 switch (result) {
42 case Result::OK:
43 return OK;
44 case Result::BAD_VALUE:
45 return BAD_VALUE;
46 case Result::PERMISSION_DENIED:
47 return PERMISSION_DENIED;
48 case Result::INVALID_OPERATION:
49 return INVALID_OPERATION;
50 case Result::NO_MEMORY:
51 return NO_MEMORY;
Mathias Agopianf001c922010-11-11 17:58:51 -080052 }
53}
54
Peng Xu1a00e2d2017-09-27 23:08:30 -070055SensorDevice::SensorDevice()
56 : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
Peng Xua8fad9b2017-03-17 12:20:27 -070057 if (!connectHidlService()) {
58 return;
59 }
Ashutosh Joshifea2d262017-04-19 23:27:49 -070060
61 float minPowerMa = 0.001; // 1 microAmp
62
Peng Xua8fad9b2017-03-17 12:20:27 -070063 checkReturn(mSensors->getSensorsList(
64 [&](const auto &list) {
65 const size_t count = list.size();
66
67 mActivationCount.setCapacity(count);
68 Info model;
69 for (size_t i=0 ; i < count; i++) {
70 sensor_t sensor;
71 convertToSensor(list[i], &sensor);
Ashutosh Joshifea2d262017-04-19 23:27:49 -070072 // Sanity check and clamp power if it is 0 (or close)
73 if (sensor.power < minPowerMa) {
74 ALOGE("Reported power %f not deemed sane, clamping to %f",
75 sensor.power, minPowerMa);
76 sensor.power = minPowerMa;
77 }
Peng Xua8fad9b2017-03-17 12:20:27 -070078 mSensorList.push_back(sensor);
79
80 mActivationCount.add(list[i].sensorHandle, model);
81
82 checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
83 }
84 }));
85
86 mIsDirectReportSupported =
87 (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
88}
89
90bool SensorDevice::connectHidlService() {
Brian Stack12f4d322018-09-14 16:18:59 -070091 bool connected = connectHidlServiceV2_0();
92 if (!connected) {
93 connected = connectHidlServiceV1_0();
94 }
95 return connected;
96}
97
98bool SensorDevice::connectHidlServiceV1_0() {
Peng Xu1a00e2d2017-09-27 23:08:30 -070099 // SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
Peng Xu3889e6e2017-03-02 19:10:38 -0800100 size_t retry = 10;
Steven Morelandd15c0302016-12-20 11:14:50 -0800101
Peng Xu1a00e2d2017-09-27 23:08:30 -0700102 while (retry-- > 0) {
Brian Stack12f4d322018-09-14 16:18:59 -0700103 sp<V1_0::ISensors> sensors = V1_0::ISensors::getService();
104 if (sensors == nullptr) {
Peng Xu1a00e2d2017-09-27 23:08:30 -0700105 // no sensor hidl service found
Peng Xua8fad9b2017-03-17 12:20:27 -0700106 break;
Peng Xu3889e6e2017-03-02 19:10:38 -0800107 }
Peng Xu1a00e2d2017-09-27 23:08:30 -0700108
Brian Stack12f4d322018-09-14 16:18:59 -0700109 mSensors = new SensorServiceUtil::SensorsWrapperV1_0(sensors);
Peng Xu1a00e2d2017-09-27 23:08:30 -0700110 mRestartWaiter->reset();
111 // Poke ISensor service. If it has lingering connection from previous generation of
112 // system server, it will kill itself. There is no intention to handle the poll result,
113 // which will be done since the size is 0.
114 if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
115 // ok to continue
116 break;
117 }
118
119 // hidl service is restarting, pointer is invalid.
120 mSensors = nullptr;
121 ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
122 mRestartWaiter->wait();
Steven Morelandd15c0302016-12-20 11:14:50 -0800123 }
Peng Xua8fad9b2017-03-17 12:20:27 -0700124 return (mSensors != nullptr);
Steven Morelandd15c0302016-12-20 11:14:50 -0800125}
126
Brian Stack12f4d322018-09-14 16:18:59 -0700127bool SensorDevice::connectHidlServiceV2_0() {
128 sp<V2_0::ISensors> sensors = V2_0::ISensors::getService();
129 if (sensors != nullptr) {
130 mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors);
131
132 // TODO: initialize message queues
133 }
134 return (mSensors != nullptr);
135}
136
Peng Xu2576cb62016-01-20 00:22:09 -0800137void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700138 // not need to check mSensors because this is is only called after successful poll()
Peng Xu2576cb62016-01-20 00:22:09 -0800139 if (connected) {
140 Info model;
141 mActivationCount.add(handle, model);
Peng Xu3889e6e2017-03-02 19:10:38 -0800142 checkReturn(mSensors->activate(handle, 0 /* enabled */));
Peng Xu2576cb62016-01-20 00:22:09 -0800143 } else {
144 mActivationCount.removeItem(handle);
145 }
146}
147
Peng Xu6a2d3a02015-12-21 12:00:23 -0800148std::string SensorDevice::dump() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700149 if (mSensors == nullptr) return "HAL not initialized\n";
Mathias Agopianf001c922010-11-11 17:58:51 -0800150
Peng Xu6a2d3a02015-12-21 12:00:23 -0800151 String8 result;
Peng Xua8fad9b2017-03-17 12:20:27 -0700152 result.appendFormat("Total %zu h/w sensors, %zu running:\n",
153 mSensorList.size(), mActivationCount.size());
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700154
Peng Xua8fad9b2017-03-17 12:20:27 -0700155 Mutex::Autolock _l(mLock);
156 for (const auto & s : mSensorList) {
157 int32_t handle = s.handle;
158 const Info& info = mActivationCount.valueFor(handle);
159 if (info.batchParams.isEmpty()) continue;
160
161 result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
162
163 result.append("sampling_period(ms) = {");
164 for (size_t j = 0; j < info.batchParams.size(); j++) {
Peng Xu2bec6232016-07-01 17:13:10 -0700165 const BatchParams& params = info.batchParams[j];
166 result.appendFormat("%.1f%s", params.mTSample / 1e6f,
Peng Xua8fad9b2017-03-17 12:20:27 -0700167 j < info.batchParams.size() - 1 ? ", " : "");
168 }
Peng Xu2bec6232016-07-01 17:13:10 -0700169 result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
Peng Xua8fad9b2017-03-17 12:20:27 -0700170
171 result.append("batching_period(ms) = {");
172 for (size_t j = 0; j < info.batchParams.size(); j++) {
Peng Xu2bec6232016-07-01 17:13:10 -0700173 const BatchParams& params = info.batchParams[j];
174 result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
Peng Xua8fad9b2017-03-17 12:20:27 -0700175 j < info.batchParams.size() - 1 ? ", " : "");
176 }
Peng Xu2bec6232016-07-01 17:13:10 -0700177 result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700178 }
179
Peng Xu6a2d3a02015-12-21 12:00:23 -0800180 return result.string();
Mathias Agopianf001c922010-11-11 17:58:51 -0800181}
182
183ssize_t SensorDevice::getSensorList(sensor_t const** list) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800184 *list = &mSensorList[0];
185
186 return mSensorList.size();
Mathias Agopianf001c922010-11-11 17:58:51 -0800187}
188
189status_t SensorDevice::initCheck() const {
Peng Xu1a00e2d2017-09-27 23:08:30 -0700190 return mSensors != nullptr ? NO_ERROR : NO_INIT;
Mathias Agopianf001c922010-11-11 17:58:51 -0800191}
192
193ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700194 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800195
196 ssize_t err;
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700197 int numHidlTransportErrors = 0;
198 bool hidlTransportError = false;
Steven Morelandd15c0302016-12-20 11:14:50 -0800199
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700200 do {
201 auto ret = mSensors->poll(
202 count,
203 [&](auto result,
204 const auto &events,
205 const auto &dynamicSensorsAdded) {
206 if (result == Result::OK) {
207 convertToSensorEvents(events, dynamicSensorsAdded, buffer);
208 err = (ssize_t)events.size();
209 } else {
210 err = StatusFromResult(result);
211 }
212 });
213
214 if (ret.isOk()) {
215 hidlTransportError = false;
216 } else {
217 hidlTransportError = true;
218 numHidlTransportErrors++;
219 if (numHidlTransportErrors > 50) {
220 // Log error and bail
221 ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
222 handleHidlDeath(ret.description());
223 } else {
224 std::this_thread::sleep_for(std::chrono::milliseconds(10));
225 }
226 }
227 } while (hidlTransportError);
228
229 if(numHidlTransportErrors > 0) {
230 ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
Yi Kong8f313e32018-07-17 14:13:29 -0700231 HidlTransportErrorLog errLog(time(nullptr), numHidlTransportErrors);
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700232 mHidlTransportErrors.add(errLog);
233 mTotalHidlTransportErrors++;
234 }
Steven Morelandd15c0302016-12-20 11:14:50 -0800235
236 return err;
Mathias Agopianf001c922010-11-11 17:58:51 -0800237}
238
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700239void SensorDevice::autoDisable(void *ident, int handle) {
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700240 Mutex::Autolock _l(mLock);
Peng Xu042baec2017-08-09 19:28:27 -0700241 ssize_t activationIndex = mActivationCount.indexOfKey(handle);
242 if (activationIndex < 0) {
243 ALOGW("Handle %d cannot be found in activation record", handle);
244 return;
245 }
246 Info& info(mActivationCount.editValueAt(activationIndex));
Aravind Akella724d91d2013-06-27 12:04:23 -0700247 info.removeBatchParamsForIdent(ident);
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700248}
249
Peng Xu6a2d3a02015-12-21 12:00:23 -0800250status_t SensorDevice::activate(void* ident, int handle, int enabled) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700251 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800252
Mathias Agopianf001c922010-11-11 17:58:51 -0800253 status_t err(NO_ERROR);
254 bool actuateHardware = false;
255
Aravind Akella724d91d2013-06-27 12:04:23 -0700256 Mutex::Autolock _l(mLock);
Peng Xu042baec2017-08-09 19:28:27 -0700257 ssize_t activationIndex = mActivationCount.indexOfKey(handle);
258 if (activationIndex < 0) {
259 ALOGW("Handle %d cannot be found in activation record", handle);
260 return BAD_VALUE;
261 }
262 Info& info(mActivationCount.editValueAt(activationIndex));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700263
Steve Blocka5512372011-12-20 16:23:08 +0000264 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700265 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
Aravind Akella724d91d2013-06-27 12:04:23 -0700266 ident, handle, enabled, info.batchParams.size());
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700267
Mathias Agopianf001c922010-11-11 17:58:51 -0800268 if (enabled) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700269 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700270
Aravind Akella4949c502015-02-11 15:54:35 -0800271 if (isClientDisabledLocked(ident)) {
Peng Xu966fa882016-09-01 16:13:15 -0700272 ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
273 ident, handle);
Aravind Akella4949c502015-02-11 15:54:35 -0800274 return INVALID_OPERATION;
275 }
276
Aravind Akella724d91d2013-06-27 12:04:23 -0700277 if (info.batchParams.indexOfKey(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800278 if (info.numActiveClients() == 1) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700279 // This is the first connection, we need to activate the underlying h/w sensor.
280 actuateHardware = true;
281 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800282 } else {
Aravind Akella724d91d2013-06-27 12:04:23 -0700283 // Log error. Every activate call should be preceded by a batch() call.
284 ALOGE("\t >>>ERROR: activate called without batch");
Mathias Agopianf001c922010-11-11 17:58:51 -0800285 }
286 } else {
Mark Salyzyndb458612014-06-10 14:50:02 -0700287 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700288
Steven Morelandd15c0302016-12-20 11:14:50 -0800289 // If a connected dynamic sensor is deactivated, remove it from the
290 // dictionary.
291 auto it = mConnectedDynamicSensors.find(handle);
292 if (it != mConnectedDynamicSensors.end()) {
293 delete it->second;
294 mConnectedDynamicSensors.erase(it);
295 }
296
Aravind Akella724d91d2013-06-27 12:04:23 -0700297 if (info.removeBatchParamsForIdent(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800298 if (info.numActiveClients() == 0) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700299 // This is the last connection, we need to de-activate the underlying h/w sensor.
Mathias Agopian50b66762010-11-29 17:26:51 -0800300 actuateHardware = true;
Aravind Akella724d91d2013-06-27 12:04:23 -0700301 } else {
Steven Morelandd15c0302016-12-20 11:14:50 -0800302 // Call batch for this sensor with the previously calculated best effort
303 // batch_rate and timeout. One of the apps has unregistered for sensor
304 // events, and the best effort batch parameters might have changed.
305 ALOGD_IF(DEBUG_CONNECTIONS,
Peng Xu2bec6232016-07-01 17:13:10 -0700306 "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
307 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
Peng Xu3889e6e2017-03-02 19:10:38 -0800308 checkReturn(mSensors->batch(
Peng Xu2bec6232016-07-01 17:13:10 -0700309 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
Mathias Agopian50b66762010-11-29 17:26:51 -0800310 }
311 } else {
312 // sensor wasn't enabled for this ident
313 }
Aravind Akella4949c502015-02-11 15:54:35 -0800314
315 if (isClientDisabledLocked(ident)) {
316 return NO_ERROR;
317 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800318 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800319
Mathias Agopianf001c922010-11-11 17:58:51 -0800320 if (actuateHardware) {
Aravind Akella4949c502015-02-11 15:54:35 -0800321 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
322 enabled);
Peng Xu3889e6e2017-03-02 19:10:38 -0800323 err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700324 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
325 strerror(-err));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700326
Aravind Akella724d91d2013-06-27 12:04:23 -0700327 if (err != NO_ERROR && enabled) {
328 // Failure when enabling the sensor. Clean up on failure.
329 info.removeBatchParamsForIdent(ident);
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700330 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800331 }
332
Mathias Agopianf001c922010-11-11 17:58:51 -0800333 return err;
334}
335
Steven Morelandd15c0302016-12-20 11:14:50 -0800336status_t SensorDevice::batch(
337 void* ident,
338 int handle,
339 int flags,
340 int64_t samplingPeriodNs,
341 int64_t maxBatchReportLatencyNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700342 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700343
344 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
345 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
346 }
Peng Xu2bec6232016-07-01 17:13:10 -0700347 if (maxBatchReportLatencyNs < 0) {
348 maxBatchReportLatencyNs = 0;
349 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700350
Aravind Akella724d91d2013-06-27 12:04:23 -0700351 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700352 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
Aravind Akella724d91d2013-06-27 12:04:23 -0700353 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
354
355 Mutex::Autolock _l(mLock);
Peng Xu042baec2017-08-09 19:28:27 -0700356 ssize_t activationIndex = mActivationCount.indexOfKey(handle);
357 if (activationIndex < 0) {
358 ALOGW("Handle %d cannot be found in activation record", handle);
359 return BAD_VALUE;
360 }
361 Info& info(mActivationCount.editValueAt(activationIndex));
Aravind Akella724d91d2013-06-27 12:04:23 -0700362
363 if (info.batchParams.indexOfKey(ident) < 0) {
Peng Xu2bec6232016-07-01 17:13:10 -0700364 BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
Aravind Akella724d91d2013-06-27 12:04:23 -0700365 info.batchParams.add(ident, params);
366 } else {
367 // A batch has already been called with this ident. Update the batch parameters.
368 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
369 }
370
371 BatchParams prevBestBatchParams = info.bestBatchParams;
372 // Find the minimum of all timeouts and batch_rates for this sensor.
373 info.selectBatchParams();
374
375 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700376 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
377 " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
Peng Xu2bec6232016-07-01 17:13:10 -0700378 prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
379 prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
Aravind Akella724d91d2013-06-27 12:04:23 -0700380
381 status_t err(NO_ERROR);
382 // If the min period or min timeout has changed since the last batch call, call batch.
383 if (prevBestBatchParams != info.bestBatchParams) {
Peng Xu2bec6232016-07-01 17:13:10 -0700384 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
385 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
Steven Morelandd15c0302016-12-20 11:14:50 -0800386 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800387 checkReturn(mSensors->batch(
Peng Xu2bec6232016-07-01 17:13:10 -0700388 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700389 if (err != NO_ERROR) {
Peng Xu2bec6232016-07-01 17:13:10 -0700390 ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
391 mSensors.get(), handle, info.bestBatchParams.mTSample,
392 info.bestBatchParams.mTBatch, strerror(-err));
Aravind Akella724d91d2013-06-27 12:04:23 -0700393 info.removeBatchParamsForIdent(ident);
394 }
395 }
396 return err;
397}
398
Peng Xu6a2d3a02015-12-21 12:00:23 -0800399status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
Peng Xu2bec6232016-07-01 17:13:10 -0700400 return batch(ident, handle, 0, samplingPeriodNs, 0);
Mathias Agopian667102f2011-09-14 16:43:34 -0700401}
402
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700403int SensorDevice::getHalDeviceVersion() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700404 if (mSensors == nullptr) return -1;
Steven Morelandd15c0302016-12-20 11:14:50 -0800405 return SENSORS_DEVICE_API_VERSION_1_4;
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700406}
407
Aravind Akella9a844cf2014-02-11 18:58:52 -0800408status_t SensorDevice::flush(void* ident, int handle) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700409 if (mSensors == nullptr) return NO_INIT;
Aravind Akella4949c502015-02-11 15:54:35 -0800410 if (isClientDisabled(ident)) return INVALID_OPERATION;
Aravind Akella724d91d2013-06-27 12:04:23 -0700411 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800412 return StatusFromResult(checkReturn(mSensors->flush(handle)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700413}
414
Aravind Akella4949c502015-02-11 15:54:35 -0800415bool SensorDevice::isClientDisabled(void* ident) {
416 Mutex::Autolock _l(mLock);
417 return isClientDisabledLocked(ident);
418}
419
420bool SensorDevice::isClientDisabledLocked(void* ident) {
421 return mDisabledClients.indexOf(ident) >= 0;
422}
423
424void SensorDevice::enableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700425 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800426 Mutex::Autolock _l(mLock);
427 mDisabledClients.clear();
Peng Xu966fa882016-09-01 16:13:15 -0700428 ALOGI("cleared mDisabledClients");
Aravind Akella4949c502015-02-11 15:54:35 -0800429 for (size_t i = 0; i< mActivationCount.size(); ++i) {
430 Info& info = mActivationCount.editValueAt(i);
431 if (info.batchParams.isEmpty()) continue;
432 info.selectBatchParams();
433 const int sensor_handle = mActivationCount.keyAt(i);
434 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
435 sensor_handle);
Steven Morelandd15c0302016-12-20 11:14:50 -0800436 status_t err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800437 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800438 sensor_handle,
Peng Xu2bec6232016-07-01 17:13:10 -0700439 info.bestBatchParams.mTSample,
440 info.bestBatchParams.mTBatch)));
Steven Morelandd15c0302016-12-20 11:14:50 -0800441 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
Aravind Akella4949c502015-02-11 15:54:35 -0800442
443 if (err == NO_ERROR) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800444 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800445 checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
Aravind Akella4949c502015-02-11 15:54:35 -0800446 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
447 }
Aravind Akella4949c502015-02-11 15:54:35 -0800448 }
449}
450
451void SensorDevice::disableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700452 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800453 Mutex::Autolock _l(mLock);
Peng Xua8fad9b2017-03-17 12:20:27 -0700454 for (size_t i = 0; i< mActivationCount.size(); ++i) {
Aravind Akella4949c502015-02-11 15:54:35 -0800455 const Info& info = mActivationCount.valueAt(i);
456 // Check if this sensor has been activated previously and disable it.
457 if (info.batchParams.size() > 0) {
458 const int sensor_handle = mActivationCount.keyAt(i);
459 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
460 sensor_handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800461 checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
Steven Morelandd15c0302016-12-20 11:14:50 -0800462
Aravind Akella4949c502015-02-11 15:54:35 -0800463 // Add all the connections that were registered for this sensor to the disabled
464 // clients list.
Svetoslavb412f6e2015-04-29 16:50:41 -0700465 for (size_t j = 0; j < info.batchParams.size(); ++j) {
Aravind Akella4949c502015-02-11 15:54:35 -0800466 mDisabledClients.add(info.batchParams.keyAt(j));
Peng Xu966fa882016-09-01 16:13:15 -0700467 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
Aravind Akella4949c502015-02-11 15:54:35 -0800468 }
469 }
470 }
471}
472
Steven Morelandd15c0302016-12-20 11:14:50 -0800473status_t SensorDevice::injectSensorData(
474 const sensors_event_t *injected_sensor_event) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700475 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800476 ALOGD_IF(DEBUG_CONNECTIONS,
477 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
478 injected_sensor_event->sensor,
479 injected_sensor_event->timestamp, injected_sensor_event->data[0],
480 injected_sensor_event->data[1], injected_sensor_event->data[2],
481 injected_sensor_event->data[3], injected_sensor_event->data[4],
482 injected_sensor_event->data[5]);
483
484 Event ev;
485 convertFromSensorEvent(*injected_sensor_event, &ev);
486
Peng Xu3889e6e2017-03-02 19:10:38 -0800487 return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700488}
489
490status_t SensorDevice::setMode(uint32_t mode) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700491 if (mSensors == nullptr) return NO_INIT;
492 return StatusFromResult(
493 checkReturn(mSensors->setOperationMode(
494 static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
495}
Steven Morelandd15c0302016-12-20 11:14:50 -0800496
Peng Xua8fad9b2017-03-17 12:20:27 -0700497int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
498 if (mSensors == nullptr) return NO_INIT;
499 Mutex::Autolock _l(mLock);
500
501 SharedMemType type;
502 switch (memory->type) {
503 case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
504 type = SharedMemType::ASHMEM;
505 break;
506 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
507 type = SharedMemType::GRALLOC;
508 break;
509 default:
510 return BAD_VALUE;
511 }
512
513 SharedMemFormat format;
514 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
515 return BAD_VALUE;
516 }
517 format = SharedMemFormat::SENSORS_EVENT;
518
519 SharedMemInfo mem = {
520 .type = type,
521 .format = format,
522 .size = static_cast<uint32_t>(memory->size),
523 .memoryHandle = memory->handle,
524 };
525
526 int32_t ret;
527 checkReturn(mSensors->registerDirectChannel(mem,
528 [&ret](auto result, auto channelHandle) {
529 if (result == Result::OK) {
530 ret = channelHandle;
531 } else {
532 ret = StatusFromResult(result);
533 }
534 }));
535 return ret;
536}
537
538void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
539 if (mSensors == nullptr) return;
540 Mutex::Autolock _l(mLock);
541 checkReturn(mSensors->unregisterDirectChannel(channelHandle));
542}
543
544int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
545 int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
546 if (mSensors == nullptr) return NO_INIT;
547 Mutex::Autolock _l(mLock);
548
549 RateLevel rate;
550 switch(config->rate_level) {
551 case SENSOR_DIRECT_RATE_STOP:
552 rate = RateLevel::STOP;
553 break;
554 case SENSOR_DIRECT_RATE_NORMAL:
555 rate = RateLevel::NORMAL;
556 break;
557 case SENSOR_DIRECT_RATE_FAST:
558 rate = RateLevel::FAST;
559 break;
560 case SENSOR_DIRECT_RATE_VERY_FAST:
561 rate = RateLevel::VERY_FAST;
562 break;
563 default:
564 return BAD_VALUE;
565 }
566
567 int32_t ret;
568 checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
569 [&ret, rate] (auto result, auto token) {
570 if (rate == RateLevel::STOP) {
571 ret = StatusFromResult(result);
572 } else {
573 if (result == Result::OK) {
574 ret = token;
575 } else {
576 ret = StatusFromResult(result);
577 }
578 }
579 }));
580
581 return ret;
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700582}
583
Mathias Agopian667102f2011-09-14 16:43:34 -0700584// ---------------------------------------------------------------------------
585
Aravind Akella4949c502015-02-11 15:54:35 -0800586int SensorDevice::Info::numActiveClients() {
587 SensorDevice& device(SensorDevice::getInstance());
588 int num = 0;
589 for (size_t i = 0; i < batchParams.size(); ++i) {
590 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
591 ++num;
592 }
593 }
594 return num;
595}
596
Peng Xu2bec6232016-07-01 17:13:10 -0700597status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
Aravind Akella724d91d2013-06-27 12:04:23 -0700598 int64_t samplingPeriodNs,
599 int64_t maxBatchReportLatencyNs) {
600 ssize_t index = batchParams.indexOfKey(ident);
Mathias Agopian667102f2011-09-14 16:43:34 -0700601 if (index < 0) {
Peng Xu2bec6232016-07-01 17:13:10 -0700602 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
603 " timeout=%" PRId64 ") failed (%s)",
Aravind Akella724d91d2013-06-27 12:04:23 -0700604 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
Mathias Agopian667102f2011-09-14 16:43:34 -0700605 return BAD_INDEX;
606 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700607 BatchParams& params = batchParams.editValueAt(index);
Peng Xu2bec6232016-07-01 17:13:10 -0700608 params.mTSample = samplingPeriodNs;
609 params.mTBatch = maxBatchReportLatencyNs;
Mathias Agopian667102f2011-09-14 16:43:34 -0700610 return NO_ERROR;
611}
612
Aravind Akella724d91d2013-06-27 12:04:23 -0700613void SensorDevice::Info::selectBatchParams() {
Peng Xu2bec6232016-07-01 17:13:10 -0700614 BatchParams bestParams; // default to max Tsample and max Tbatch
Aravind Akella4949c502015-02-11 15:54:35 -0800615 SensorDevice& device(SensorDevice::getInstance());
Aravind Akella724d91d2013-06-27 12:04:23 -0700616
Aravind Akella4949c502015-02-11 15:54:35 -0800617 for (size_t i = 0; i < batchParams.size(); ++i) {
Peng Xu2bec6232016-07-01 17:13:10 -0700618 if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
619 continue;
Aravind Akella724d91d2013-06-27 12:04:23 -0700620 }
Peng Xu2bec6232016-07-01 17:13:10 -0700621 bestParams.merge(batchParams[i]);
622 }
623 // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
624 if (bestParams.mTBatch <= bestParams.mTSample) {
625 bestParams.mTBatch = 0;
Mathias Agopianf001c922010-11-11 17:58:51 -0800626 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700627 bestBatchParams = bestParams;
628}
629
630ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
631 ssize_t idx = batchParams.removeItem(ident);
632 if (idx >= 0) {
633 selectBatchParams();
634 }
635 return idx;
Mathias Agopianf001c922010-11-11 17:58:51 -0800636}
637
Peng Xu4f707f82016-09-26 11:28:32 -0700638void SensorDevice::notifyConnectionDestroyed(void* ident) {
639 Mutex::Autolock _l(mLock);
640 mDisabledClients.remove(ident);
641}
642
Peng Xu53632542017-01-23 20:06:27 -0800643bool SensorDevice::isDirectReportSupported() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800644 return mIsDirectReportSupported;
Peng Xu53632542017-01-23 20:06:27 -0800645}
Steven Morelandd15c0302016-12-20 11:14:50 -0800646
647void SensorDevice::convertToSensorEvent(
648 const Event &src, sensors_event_t *dst) {
649 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
650 src, dst);
651
652 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
653 const DynamicSensorInfo &dyn = src.u.dynamic;
654
655 dst->dynamic_sensor_meta.connected = dyn.connected;
656 dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
657 if (dyn.connected) {
658 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
659 CHECK(it != mConnectedDynamicSensors.end());
660
661 dst->dynamic_sensor_meta.sensor = it->second;
662
663 memcpy(dst->dynamic_sensor_meta.uuid,
664 dyn.uuid.data(),
665 sizeof(dst->dynamic_sensor_meta.uuid));
666 }
667 }
668}
669
670void SensorDevice::convertToSensorEvents(
671 const hidl_vec<Event> &src,
672 const hidl_vec<SensorInfo> &dynamicSensorsAdded,
673 sensors_event_t *dst) {
674 // Allocate a sensor_t structure for each dynamic sensor added and insert
675 // it into the dictionary of connected dynamic sensors keyed by handle.
676 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
677 const SensorInfo &info = dynamicSensorsAdded[i];
678
679 auto it = mConnectedDynamicSensors.find(info.sensorHandle);
680 CHECK(it == mConnectedDynamicSensors.end());
681
682 sensor_t *sensor = new sensor_t;
683 convertToSensor(info, sensor);
684
685 mConnectedDynamicSensors.insert(
686 std::make_pair(sensor->handle, sensor));
687 }
688
689 for (size_t i = 0; i < src.size(); ++i) {
690 convertToSensorEvent(src[i], &dst[i]);
691 }
692}
693
Peng Xu3889e6e2017-03-02 19:10:38 -0800694void SensorDevice::handleHidlDeath(const std::string & detail) {
695 // restart is the only option at present.
696 LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
697}
698
Mathias Agopianf001c922010-11-11 17:58:51 -0800699// ---------------------------------------------------------------------------
700}; // namespace android