blob: 2c4bda98b86a4d45e78342671ae323f5527277d9 [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>
Ashutosh Joshi5cafc1e2017-02-09 21:44:04 +000021#include <utils/Atomic.h>
22#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
29using android::hardware::hidl_vec;
30
31using namespace android::hardware::sensors::V1_0;
32using namespace android::hardware::sensors::V1_0::implementation;
Mathias Agopianf001c922010-11-11 17:58:51 -080033
34namespace android {
35// ---------------------------------------------------------------------------
Mathias Agopianf001c922010-11-11 17:58:51 -080036
37ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
38
Steven Morelandd15c0302016-12-20 11:14:50 -080039static status_t StatusFromResult(Result result) {
40 switch (result) {
41 case Result::OK:
42 return OK;
43 case Result::BAD_VALUE:
44 return BAD_VALUE;
45 case Result::PERMISSION_DENIED:
46 return PERMISSION_DENIED;
47 case Result::INVALID_OPERATION:
48 return INVALID_OPERATION;
49 case Result::NO_MEMORY:
50 return NO_MEMORY;
Mathias Agopianf001c922010-11-11 17:58:51 -080051 }
52}
53
Ashutosh Joshi96b12d82017-03-15 16:27:12 -070054SensorDevice::SensorDevice() : mHidlTransportErrors(20) {
Peng Xua8fad9b2017-03-17 12:20:27 -070055 if (!connectHidlService()) {
56 return;
57 }
Ashutosh Joshifea2d262017-04-19 23:27:49 -070058
59 float minPowerMa = 0.001; // 1 microAmp
60
Peng Xua8fad9b2017-03-17 12:20:27 -070061 checkReturn(mSensors->getSensorsList(
62 [&](const auto &list) {
63 const size_t count = list.size();
64
65 mActivationCount.setCapacity(count);
66 Info model;
67 for (size_t i=0 ; i < count; i++) {
68 sensor_t sensor;
69 convertToSensor(list[i], &sensor);
Ashutosh Joshifea2d262017-04-19 23:27:49 -070070 // Sanity check and clamp power if it is 0 (or close)
71 if (sensor.power < minPowerMa) {
72 ALOGE("Reported power %f not deemed sane, clamping to %f",
73 sensor.power, minPowerMa);
74 sensor.power = minPowerMa;
75 }
Peng Xua8fad9b2017-03-17 12:20:27 -070076 mSensorList.push_back(sensor);
77
78 mActivationCount.add(list[i].sensorHandle, model);
79
80 checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
81 }
82 }));
83
84 mIsDirectReportSupported =
85 (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
86}
87
88bool SensorDevice::connectHidlService() {
Peng Xu3889e6e2017-03-02 19:10:38 -080089 // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
90 constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
91 size_t retry = 10;
Steven Morelandd15c0302016-12-20 11:14:50 -080092
Peng Xu3889e6e2017-03-02 19:10:38 -080093 while (true) {
94 int initStep = 0;
95 mSensors = ISensors::getService();
96 if (mSensors != nullptr) {
97 ++initStep;
98 // Poke ISensor service. If it has lingering connection from previous generation of
99 // system server, it will kill itself. There is no intention to handle the poll result,
100 // which will be done since the size is 0.
101 if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
102 // ok to continue
103 break;
104 }
105 // hidl service is restarting, pointer is invalid.
106 mSensors = nullptr;
107 }
108
109 if (--retry <= 0) {
110 ALOGE("Cannot connect to ISensors hidl service!");
Peng Xua8fad9b2017-03-17 12:20:27 -0700111 break;
Peng Xu3889e6e2017-03-02 19:10:38 -0800112 }
113 // Delay 100ms before retry, hidl service is expected to come up in short time after
114 // crash.
115 ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
116 (initStep == 0) ? "getService()" : "poll() check", retry);
117 std::this_thread::sleep_for(RETRY_DELAY);
Steven Morelandd15c0302016-12-20 11:14:50 -0800118 }
Peng Xua8fad9b2017-03-17 12:20:27 -0700119 return (mSensors != nullptr);
Steven Morelandd15c0302016-12-20 11:14:50 -0800120}
121
Peng Xu2576cb62016-01-20 00:22:09 -0800122void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700123 // not need to check mSensors because this is is only called after successful poll()
Peng Xu2576cb62016-01-20 00:22:09 -0800124 if (connected) {
125 Info model;
126 mActivationCount.add(handle, model);
Peng Xu3889e6e2017-03-02 19:10:38 -0800127 checkReturn(mSensors->activate(handle, 0 /* enabled */));
Peng Xu2576cb62016-01-20 00:22:09 -0800128 } else {
129 mActivationCount.removeItem(handle);
130 }
131}
132
Peng Xu6a2d3a02015-12-21 12:00:23 -0800133std::string SensorDevice::dump() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700134 if (mSensors == nullptr) return "HAL not initialized\n";
Mathias Agopianf001c922010-11-11 17:58:51 -0800135
Peng Xu6a2d3a02015-12-21 12:00:23 -0800136 String8 result;
Peng Xua8fad9b2017-03-17 12:20:27 -0700137 result.appendFormat("Total %zu h/w sensors, %zu running:\n",
138 mSensorList.size(), mActivationCount.size());
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700139
Peng Xua8fad9b2017-03-17 12:20:27 -0700140 Mutex::Autolock _l(mLock);
141 for (const auto & s : mSensorList) {
142 int32_t handle = s.handle;
143 const Info& info = mActivationCount.valueFor(handle);
144 if (info.batchParams.isEmpty()) continue;
145
146 result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
147
148 result.append("sampling_period(ms) = {");
149 for (size_t j = 0; j < info.batchParams.size(); j++) {
150 const BatchParams& params = info.batchParams.valueAt(j);
151 result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
152 j < info.batchParams.size() - 1 ? ", " : "");
153 }
154 result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
155
156 result.append("batching_period(ms) = {");
157 for (size_t j = 0; j < info.batchParams.size(); j++) {
158 BatchParams params = info.batchParams.valueAt(j);
159
160 result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
161 j < info.batchParams.size() - 1 ? ", " : "");
162 }
163 result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700164 }
165
Peng Xu6a2d3a02015-12-21 12:00:23 -0800166 return result.string();
Mathias Agopianf001c922010-11-11 17:58:51 -0800167}
168
169ssize_t SensorDevice::getSensorList(sensor_t const** list) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800170 *list = &mSensorList[0];
171
172 return mSensorList.size();
Mathias Agopianf001c922010-11-11 17:58:51 -0800173}
174
175status_t SensorDevice::initCheck() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800176 return mSensors != NULL ? NO_ERROR : NO_INIT;
Mathias Agopianf001c922010-11-11 17:58:51 -0800177}
178
179ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700180 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800181
182 ssize_t err;
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700183 int numHidlTransportErrors = 0;
184 bool hidlTransportError = false;
Steven Morelandd15c0302016-12-20 11:14:50 -0800185
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700186 do {
187 auto ret = mSensors->poll(
188 count,
189 [&](auto result,
190 const auto &events,
191 const auto &dynamicSensorsAdded) {
192 if (result == Result::OK) {
193 convertToSensorEvents(events, dynamicSensorsAdded, buffer);
194 err = (ssize_t)events.size();
195 } else {
196 err = StatusFromResult(result);
197 }
198 });
199
200 if (ret.isOk()) {
201 hidlTransportError = false;
202 } else {
203 hidlTransportError = true;
204 numHidlTransportErrors++;
205 if (numHidlTransportErrors > 50) {
206 // Log error and bail
207 ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
208 handleHidlDeath(ret.description());
209 } else {
210 std::this_thread::sleep_for(std::chrono::milliseconds(10));
211 }
212 }
213 } while (hidlTransportError);
214
215 if(numHidlTransportErrors > 0) {
216 ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
217 HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors);
218 mHidlTransportErrors.add(errLog);
219 mTotalHidlTransportErrors++;
220 }
Steven Morelandd15c0302016-12-20 11:14:50 -0800221
222 return err;
Mathias Agopianf001c922010-11-11 17:58:51 -0800223}
224
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700225void SensorDevice::autoDisable(void *ident, int handle) {
226 Info& info( mActivationCount.editValueFor(handle) );
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700227 Mutex::Autolock _l(mLock);
Aravind Akella724d91d2013-06-27 12:04:23 -0700228 info.removeBatchParamsForIdent(ident);
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700229}
230
Peng Xu6a2d3a02015-12-21 12:00:23 -0800231status_t SensorDevice::activate(void* ident, int handle, int enabled) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700232 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800233
Mathias Agopianf001c922010-11-11 17:58:51 -0800234 status_t err(NO_ERROR);
235 bool actuateHardware = false;
236
Aravind Akella724d91d2013-06-27 12:04:23 -0700237 Mutex::Autolock _l(mLock);
Mathias Agopianf001c922010-11-11 17:58:51 -0800238 Info& info( mActivationCount.editValueFor(handle) );
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700239
Steve Blocka5512372011-12-20 16:23:08 +0000240 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700241 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
Aravind Akella724d91d2013-06-27 12:04:23 -0700242 ident, handle, enabled, info.batchParams.size());
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700243
Mathias Agopianf001c922010-11-11 17:58:51 -0800244 if (enabled) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700245 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700246
Aravind Akella4949c502015-02-11 15:54:35 -0800247 if (isClientDisabledLocked(ident)) {
Peng Xu966fa882016-09-01 16:13:15 -0700248 ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
249 ident, handle);
Aravind Akella4949c502015-02-11 15:54:35 -0800250 return INVALID_OPERATION;
251 }
252
Aravind Akella724d91d2013-06-27 12:04:23 -0700253 if (info.batchParams.indexOfKey(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800254 if (info.numActiveClients() == 1) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700255 // This is the first connection, we need to activate the underlying h/w sensor.
256 actuateHardware = true;
257 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800258 } else {
Aravind Akella724d91d2013-06-27 12:04:23 -0700259 // Log error. Every activate call should be preceded by a batch() call.
260 ALOGE("\t >>>ERROR: activate called without batch");
Mathias Agopianf001c922010-11-11 17:58:51 -0800261 }
262 } else {
Mark Salyzyndb458612014-06-10 14:50:02 -0700263 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700264
Steven Morelandd15c0302016-12-20 11:14:50 -0800265 // If a connected dynamic sensor is deactivated, remove it from the
266 // dictionary.
267 auto it = mConnectedDynamicSensors.find(handle);
268 if (it != mConnectedDynamicSensors.end()) {
269 delete it->second;
270 mConnectedDynamicSensors.erase(it);
271 }
272
Aravind Akella724d91d2013-06-27 12:04:23 -0700273 if (info.removeBatchParamsForIdent(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800274 if (info.numActiveClients() == 0) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700275 // This is the last connection, we need to de-activate the underlying h/w sensor.
Mathias Agopian50b66762010-11-29 17:26:51 -0800276 actuateHardware = true;
Aravind Akella724d91d2013-06-27 12:04:23 -0700277 } else {
Steven Morelandd15c0302016-12-20 11:14:50 -0800278 // Call batch for this sensor with the previously calculated best effort
279 // batch_rate and timeout. One of the apps has unregistered for sensor
280 // events, and the best effort batch parameters might have changed.
281 ALOGD_IF(DEBUG_CONNECTIONS,
282 "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
283 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
284 info.bestBatchParams.batchTimeout);
Peng Xu3889e6e2017-03-02 19:10:38 -0800285 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800286 handle,
287 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800288 info.bestBatchParams.batchTimeout));
Mathias Agopian50b66762010-11-29 17:26:51 -0800289 }
290 } else {
291 // sensor wasn't enabled for this ident
292 }
Aravind Akella4949c502015-02-11 15:54:35 -0800293
294 if (isClientDisabledLocked(ident)) {
295 return NO_ERROR;
296 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800297 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800298
Mathias Agopianf001c922010-11-11 17:58:51 -0800299 if (actuateHardware) {
Aravind Akella4949c502015-02-11 15:54:35 -0800300 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
301 enabled);
Peng Xu3889e6e2017-03-02 19:10:38 -0800302 err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700303 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
304 strerror(-err));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700305
Aravind Akella724d91d2013-06-27 12:04:23 -0700306 if (err != NO_ERROR && enabled) {
307 // Failure when enabling the sensor. Clean up on failure.
308 info.removeBatchParamsForIdent(ident);
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700309 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800310 }
311
Mathias Agopianf001c922010-11-11 17:58:51 -0800312 return err;
313}
314
Steven Morelandd15c0302016-12-20 11:14:50 -0800315status_t SensorDevice::batch(
316 void* ident,
317 int handle,
318 int flags,
319 int64_t samplingPeriodNs,
320 int64_t maxBatchReportLatencyNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700321 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700322
323 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
324 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
325 }
326
Aravind Akella724d91d2013-06-27 12:04:23 -0700327 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700328 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
Aravind Akella724d91d2013-06-27 12:04:23 -0700329 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
330
331 Mutex::Autolock _l(mLock);
332 Info& info(mActivationCount.editValueFor(handle));
333
334 if (info.batchParams.indexOfKey(ident) < 0) {
335 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
336 info.batchParams.add(ident, params);
337 } else {
338 // A batch has already been called with this ident. Update the batch parameters.
339 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
340 }
341
342 BatchParams prevBestBatchParams = info.bestBatchParams;
343 // Find the minimum of all timeouts and batch_rates for this sensor.
344 info.selectBatchParams();
345
346 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700347 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
348 " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
Aravind Akella724d91d2013-06-27 12:04:23 -0700349 prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
350 prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
351
352 status_t err(NO_ERROR);
353 // If the min period or min timeout has changed since the last batch call, call batch.
354 if (prevBestBatchParams != info.bestBatchParams) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800355 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
356 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
357 info.bestBatchParams.batchTimeout);
358 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800359 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800360 handle,
361 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800362 info.bestBatchParams.batchTimeout)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700363 if (err != NO_ERROR) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700364 ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
Steven Morelandd15c0302016-12-20 11:14:50 -0800365 mSensors.get(), handle,
Aravind Akella724d91d2013-06-27 12:04:23 -0700366 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
367 info.bestBatchParams.batchTimeout, strerror(-err));
368 info.removeBatchParamsForIdent(ident);
369 }
370 }
371 return err;
372}
373
Peng Xu6a2d3a02015-12-21 12:00:23 -0800374status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700375 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700376 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
377 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
378 }
Mathias Agopian667102f2011-09-14 16:43:34 -0700379 Mutex::Autolock _l(mLock);
Aravind Akella4949c502015-02-11 15:54:35 -0800380 if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
Mathias Agopianf001c922010-11-11 17:58:51 -0800381 Info& info( mActivationCount.editValueFor(handle) );
Aravind Akella724d91d2013-06-27 12:04:23 -0700382 // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
383 // Calling setDelay() in batch mode is an invalid operation.
384 if (info.bestBatchParams.batchTimeout != 0) {
385 return INVALID_OPERATION;
386 }
387 ssize_t index = info.batchParams.indexOfKey(ident);
388 if (index < 0) {
389 return BAD_INDEX;
390 }
391 BatchParams& params = info.batchParams.editValueAt(index);
392 params.batchDelay = samplingPeriodNs;
393 info.selectBatchParams();
Steven Morelandd15c0302016-12-20 11:14:50 -0800394
395 return StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800396 checkReturn(mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)));
Mathias Agopian667102f2011-09-14 16:43:34 -0700397}
398
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700399int SensorDevice::getHalDeviceVersion() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700400 if (mSensors == nullptr) return -1;
Steven Morelandd15c0302016-12-20 11:14:50 -0800401 return SENSORS_DEVICE_API_VERSION_1_4;
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700402}
403
Aravind Akella9a844cf2014-02-11 18:58:52 -0800404status_t SensorDevice::flush(void* ident, int handle) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700405 if (mSensors == nullptr) return NO_INIT;
Aravind Akella4949c502015-02-11 15:54:35 -0800406 if (isClientDisabled(ident)) return INVALID_OPERATION;
Aravind Akella724d91d2013-06-27 12:04:23 -0700407 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800408 return StatusFromResult(checkReturn(mSensors->flush(handle)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700409}
410
Aravind Akella4949c502015-02-11 15:54:35 -0800411bool SensorDevice::isClientDisabled(void* ident) {
412 Mutex::Autolock _l(mLock);
413 return isClientDisabledLocked(ident);
414}
415
416bool SensorDevice::isClientDisabledLocked(void* ident) {
417 return mDisabledClients.indexOf(ident) >= 0;
418}
419
420void SensorDevice::enableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700421 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800422 Mutex::Autolock _l(mLock);
423 mDisabledClients.clear();
Peng Xu966fa882016-09-01 16:13:15 -0700424 ALOGI("cleared mDisabledClients");
Aravind Akella4949c502015-02-11 15:54:35 -0800425 for (size_t i = 0; i< mActivationCount.size(); ++i) {
426 Info& info = mActivationCount.editValueAt(i);
427 if (info.batchParams.isEmpty()) continue;
428 info.selectBatchParams();
429 const int sensor_handle = mActivationCount.keyAt(i);
430 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
431 sensor_handle);
Steven Morelandd15c0302016-12-20 11:14:50 -0800432 status_t err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800433 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800434 sensor_handle,
435 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800436 info.bestBatchParams.batchTimeout)));
Steven Morelandd15c0302016-12-20 11:14:50 -0800437 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
Aravind Akella4949c502015-02-11 15:54:35 -0800438
439 if (err == NO_ERROR) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800440 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800441 checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
Aravind Akella4949c502015-02-11 15:54:35 -0800442 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
443 }
Aravind Akella4949c502015-02-11 15:54:35 -0800444 }
445}
446
447void SensorDevice::disableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700448 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800449 Mutex::Autolock _l(mLock);
Peng Xua8fad9b2017-03-17 12:20:27 -0700450 for (size_t i = 0; i< mActivationCount.size(); ++i) {
Aravind Akella4949c502015-02-11 15:54:35 -0800451 const Info& info = mActivationCount.valueAt(i);
452 // Check if this sensor has been activated previously and disable it.
453 if (info.batchParams.size() > 0) {
454 const int sensor_handle = mActivationCount.keyAt(i);
455 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
456 sensor_handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800457 checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
Steven Morelandd15c0302016-12-20 11:14:50 -0800458
Aravind Akella4949c502015-02-11 15:54:35 -0800459 // Add all the connections that were registered for this sensor to the disabled
460 // clients list.
Svetoslavb412f6e2015-04-29 16:50:41 -0700461 for (size_t j = 0; j < info.batchParams.size(); ++j) {
Aravind Akella4949c502015-02-11 15:54:35 -0800462 mDisabledClients.add(info.batchParams.keyAt(j));
Peng Xu966fa882016-09-01 16:13:15 -0700463 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
Aravind Akella4949c502015-02-11 15:54:35 -0800464 }
465 }
466 }
467}
468
Steven Morelandd15c0302016-12-20 11:14:50 -0800469status_t SensorDevice::injectSensorData(
470 const sensors_event_t *injected_sensor_event) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700471 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800472 ALOGD_IF(DEBUG_CONNECTIONS,
473 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
474 injected_sensor_event->sensor,
475 injected_sensor_event->timestamp, injected_sensor_event->data[0],
476 injected_sensor_event->data[1], injected_sensor_event->data[2],
477 injected_sensor_event->data[3], injected_sensor_event->data[4],
478 injected_sensor_event->data[5]);
479
480 Event ev;
481 convertFromSensorEvent(*injected_sensor_event, &ev);
482
Peng Xu3889e6e2017-03-02 19:10:38 -0800483 return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700484}
485
486status_t SensorDevice::setMode(uint32_t mode) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700487 if (mSensors == nullptr) return NO_INIT;
488 return StatusFromResult(
489 checkReturn(mSensors->setOperationMode(
490 static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
491}
Steven Morelandd15c0302016-12-20 11:14:50 -0800492
Peng Xua8fad9b2017-03-17 12:20:27 -0700493int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
494 if (mSensors == nullptr) return NO_INIT;
495 Mutex::Autolock _l(mLock);
496
497 SharedMemType type;
498 switch (memory->type) {
499 case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
500 type = SharedMemType::ASHMEM;
501 break;
502 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
503 type = SharedMemType::GRALLOC;
504 break;
505 default:
506 return BAD_VALUE;
507 }
508
509 SharedMemFormat format;
510 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
511 return BAD_VALUE;
512 }
513 format = SharedMemFormat::SENSORS_EVENT;
514
515 SharedMemInfo mem = {
516 .type = type,
517 .format = format,
518 .size = static_cast<uint32_t>(memory->size),
519 .memoryHandle = memory->handle,
520 };
521
522 int32_t ret;
523 checkReturn(mSensors->registerDirectChannel(mem,
524 [&ret](auto result, auto channelHandle) {
525 if (result == Result::OK) {
526 ret = channelHandle;
527 } else {
528 ret = StatusFromResult(result);
529 }
530 }));
531 return ret;
532}
533
534void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
535 if (mSensors == nullptr) return;
536 Mutex::Autolock _l(mLock);
537 checkReturn(mSensors->unregisterDirectChannel(channelHandle));
538}
539
540int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
541 int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
542 if (mSensors == nullptr) return NO_INIT;
543 Mutex::Autolock _l(mLock);
544
545 RateLevel rate;
546 switch(config->rate_level) {
547 case SENSOR_DIRECT_RATE_STOP:
548 rate = RateLevel::STOP;
549 break;
550 case SENSOR_DIRECT_RATE_NORMAL:
551 rate = RateLevel::NORMAL;
552 break;
553 case SENSOR_DIRECT_RATE_FAST:
554 rate = RateLevel::FAST;
555 break;
556 case SENSOR_DIRECT_RATE_VERY_FAST:
557 rate = RateLevel::VERY_FAST;
558 break;
559 default:
560 return BAD_VALUE;
561 }
562
563 int32_t ret;
564 checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
565 [&ret, rate] (auto result, auto token) {
566 if (rate == RateLevel::STOP) {
567 ret = StatusFromResult(result);
568 } else {
569 if (result == Result::OK) {
570 ret = token;
571 } else {
572 ret = StatusFromResult(result);
573 }
574 }
575 }));
576
577 return ret;
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700578}
579
Mathias Agopian667102f2011-09-14 16:43:34 -0700580// ---------------------------------------------------------------------------
581
Aravind Akella4949c502015-02-11 15:54:35 -0800582int SensorDevice::Info::numActiveClients() {
583 SensorDevice& device(SensorDevice::getInstance());
584 int num = 0;
585 for (size_t i = 0; i < batchParams.size(); ++i) {
586 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
587 ++num;
588 }
589 }
590 return num;
591}
592
Aravind Akella724d91d2013-06-27 12:04:23 -0700593status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
594 int64_t samplingPeriodNs,
595 int64_t maxBatchReportLatencyNs) {
596 ssize_t index = batchParams.indexOfKey(ident);
Mathias Agopian667102f2011-09-14 16:43:34 -0700597 if (index < 0) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700598 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
Aravind Akella724d91d2013-06-27 12:04:23 -0700599 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
Mathias Agopian667102f2011-09-14 16:43:34 -0700600 return BAD_INDEX;
601 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700602 BatchParams& params = batchParams.editValueAt(index);
603 params.flags = flags;
604 params.batchDelay = samplingPeriodNs;
605 params.batchTimeout = maxBatchReportLatencyNs;
Mathias Agopian667102f2011-09-14 16:43:34 -0700606 return NO_ERROR;
607}
608
Aravind Akella724d91d2013-06-27 12:04:23 -0700609void SensorDevice::Info::selectBatchParams() {
Aravind Akella4949c502015-02-11 15:54:35 -0800610 BatchParams bestParams(0, -1, -1);
611 SensorDevice& device(SensorDevice::getInstance());
Aravind Akella724d91d2013-06-27 12:04:23 -0700612
Aravind Akella4949c502015-02-11 15:54:35 -0800613 for (size_t i = 0; i < batchParams.size(); ++i) {
614 if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
Aravind Akella724d91d2013-06-27 12:04:23 -0700615 BatchParams params = batchParams.valueAt(i);
Aravind Akella4949c502015-02-11 15:54:35 -0800616 if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700617 bestParams.batchDelay = params.batchDelay;
618 }
Aravind Akella4949c502015-02-11 15:54:35 -0800619 if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700620 bestParams.batchTimeout = params.batchTimeout;
Mathias Agopianf001c922010-11-11 17:58:51 -0800621 }
622 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700623 bestBatchParams = bestParams;
624}
625
626ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
627 ssize_t idx = batchParams.removeItem(ident);
628 if (idx >= 0) {
629 selectBatchParams();
630 }
631 return idx;
Mathias Agopianf001c922010-11-11 17:58:51 -0800632}
633
Peng Xu4f707f82016-09-26 11:28:32 -0700634void SensorDevice::notifyConnectionDestroyed(void* ident) {
635 Mutex::Autolock _l(mLock);
636 mDisabledClients.remove(ident);
637}
638
Peng Xu53632542017-01-23 20:06:27 -0800639bool SensorDevice::isDirectReportSupported() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800640 return mIsDirectReportSupported;
Peng Xu53632542017-01-23 20:06:27 -0800641}
Steven Morelandd15c0302016-12-20 11:14:50 -0800642
643void SensorDevice::convertToSensorEvent(
644 const Event &src, sensors_event_t *dst) {
645 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
646 src, dst);
647
648 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
649 const DynamicSensorInfo &dyn = src.u.dynamic;
650
651 dst->dynamic_sensor_meta.connected = dyn.connected;
652 dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
653 if (dyn.connected) {
654 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
655 CHECK(it != mConnectedDynamicSensors.end());
656
657 dst->dynamic_sensor_meta.sensor = it->second;
658
659 memcpy(dst->dynamic_sensor_meta.uuid,
660 dyn.uuid.data(),
661 sizeof(dst->dynamic_sensor_meta.uuid));
662 }
663 }
664}
665
666void SensorDevice::convertToSensorEvents(
667 const hidl_vec<Event> &src,
668 const hidl_vec<SensorInfo> &dynamicSensorsAdded,
669 sensors_event_t *dst) {
670 // Allocate a sensor_t structure for each dynamic sensor added and insert
671 // it into the dictionary of connected dynamic sensors keyed by handle.
672 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
673 const SensorInfo &info = dynamicSensorsAdded[i];
674
675 auto it = mConnectedDynamicSensors.find(info.sensorHandle);
676 CHECK(it == mConnectedDynamicSensors.end());
677
678 sensor_t *sensor = new sensor_t;
679 convertToSensor(info, sensor);
680
681 mConnectedDynamicSensors.insert(
682 std::make_pair(sensor->handle, sensor));
683 }
684
685 for (size_t i = 0; i < src.size(); ++i) {
686 convertToSensorEvent(src[i], &dst[i]);
687 }
688}
689
Peng Xu3889e6e2017-03-02 19:10:38 -0800690void SensorDevice::handleHidlDeath(const std::string & detail) {
691 // restart is the only option at present.
692 LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
693}
694
Mathias Agopianf001c922010-11-11 17:58:51 -0800695// ---------------------------------------------------------------------------
696}; // namespace android