blob: 080c02bc91410ffa68be0a0a91fcad431952d2e5 [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 }
58 checkReturn(mSensors->getSensorsList(
59 [&](const auto &list) {
60 const size_t count = list.size();
61
62 mActivationCount.setCapacity(count);
63 Info model;
64 for (size_t i=0 ; i < count; i++) {
65 sensor_t sensor;
66 convertToSensor(list[i], &sensor);
67 mSensorList.push_back(sensor);
68
69 mActivationCount.add(list[i].sensorHandle, model);
70
71 checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
72 }
73 }));
74
75 mIsDirectReportSupported =
76 (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
77}
78
79bool SensorDevice::connectHidlService() {
Peng Xu3889e6e2017-03-02 19:10:38 -080080 // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
81 constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
82 size_t retry = 10;
Steven Morelandd15c0302016-12-20 11:14:50 -080083
Peng Xu3889e6e2017-03-02 19:10:38 -080084 while (true) {
85 int initStep = 0;
86 mSensors = ISensors::getService();
87 if (mSensors != nullptr) {
88 ++initStep;
89 // Poke ISensor service. If it has lingering connection from previous generation of
90 // system server, it will kill itself. There is no intention to handle the poll result,
91 // which will be done since the size is 0.
92 if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
93 // ok to continue
94 break;
95 }
96 // hidl service is restarting, pointer is invalid.
97 mSensors = nullptr;
98 }
99
100 if (--retry <= 0) {
101 ALOGE("Cannot connect to ISensors hidl service!");
Peng Xua8fad9b2017-03-17 12:20:27 -0700102 break;
Peng Xu3889e6e2017-03-02 19:10:38 -0800103 }
104 // Delay 100ms before retry, hidl service is expected to come up in short time after
105 // crash.
106 ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
107 (initStep == 0) ? "getService()" : "poll() check", retry);
108 std::this_thread::sleep_for(RETRY_DELAY);
Steven Morelandd15c0302016-12-20 11:14:50 -0800109 }
Peng Xua8fad9b2017-03-17 12:20:27 -0700110 return (mSensors != nullptr);
Steven Morelandd15c0302016-12-20 11:14:50 -0800111}
112
Peng Xu2576cb62016-01-20 00:22:09 -0800113void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700114 // not need to check mSensors because this is is only called after successful poll()
Peng Xu2576cb62016-01-20 00:22:09 -0800115 if (connected) {
116 Info model;
117 mActivationCount.add(handle, model);
Peng Xu3889e6e2017-03-02 19:10:38 -0800118 checkReturn(mSensors->activate(handle, 0 /* enabled */));
Peng Xu2576cb62016-01-20 00:22:09 -0800119 } else {
120 mActivationCount.removeItem(handle);
121 }
122}
123
Peng Xu6a2d3a02015-12-21 12:00:23 -0800124std::string SensorDevice::dump() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700125 if (mSensors == nullptr) return "HAL not initialized\n";
Mathias Agopianf001c922010-11-11 17:58:51 -0800126
Peng Xu6a2d3a02015-12-21 12:00:23 -0800127 String8 result;
Peng Xua8fad9b2017-03-17 12:20:27 -0700128 result.appendFormat("Total %zu h/w sensors, %zu running:\n",
129 mSensorList.size(), mActivationCount.size());
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700130
Peng Xua8fad9b2017-03-17 12:20:27 -0700131 Mutex::Autolock _l(mLock);
132 for (const auto & s : mSensorList) {
133 int32_t handle = s.handle;
134 const Info& info = mActivationCount.valueFor(handle);
135 if (info.batchParams.isEmpty()) continue;
136
137 result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
138
139 result.append("sampling_period(ms) = {");
140 for (size_t j = 0; j < info.batchParams.size(); j++) {
141 const BatchParams& params = info.batchParams.valueAt(j);
142 result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
143 j < info.batchParams.size() - 1 ? ", " : "");
144 }
145 result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
146
147 result.append("batching_period(ms) = {");
148 for (size_t j = 0; j < info.batchParams.size(); j++) {
149 BatchParams params = info.batchParams.valueAt(j);
150
151 result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
152 j < info.batchParams.size() - 1 ? ", " : "");
153 }
154 result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700155 }
156
Peng Xu6a2d3a02015-12-21 12:00:23 -0800157 return result.string();
Mathias Agopianf001c922010-11-11 17:58:51 -0800158}
159
160ssize_t SensorDevice::getSensorList(sensor_t const** list) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800161 *list = &mSensorList[0];
162
163 return mSensorList.size();
Mathias Agopianf001c922010-11-11 17:58:51 -0800164}
165
166status_t SensorDevice::initCheck() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800167 return mSensors != NULL ? NO_ERROR : NO_INIT;
Mathias Agopianf001c922010-11-11 17:58:51 -0800168}
169
170ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700171 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800172
173 ssize_t err;
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700174 int numHidlTransportErrors = 0;
175 bool hidlTransportError = false;
Steven Morelandd15c0302016-12-20 11:14:50 -0800176
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700177 do {
178 auto ret = mSensors->poll(
179 count,
180 [&](auto result,
181 const auto &events,
182 const auto &dynamicSensorsAdded) {
183 if (result == Result::OK) {
184 convertToSensorEvents(events, dynamicSensorsAdded, buffer);
185 err = (ssize_t)events.size();
186 } else {
187 err = StatusFromResult(result);
188 }
189 });
190
191 if (ret.isOk()) {
192 hidlTransportError = false;
193 } else {
194 hidlTransportError = true;
195 numHidlTransportErrors++;
196 if (numHidlTransportErrors > 50) {
197 // Log error and bail
198 ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
199 handleHidlDeath(ret.description());
200 } else {
201 std::this_thread::sleep_for(std::chrono::milliseconds(10));
202 }
203 }
204 } while (hidlTransportError);
205
206 if(numHidlTransportErrors > 0) {
207 ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
208 HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors);
209 mHidlTransportErrors.add(errLog);
210 mTotalHidlTransportErrors++;
211 }
Steven Morelandd15c0302016-12-20 11:14:50 -0800212
213 return err;
Mathias Agopianf001c922010-11-11 17:58:51 -0800214}
215
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700216void SensorDevice::autoDisable(void *ident, int handle) {
217 Info& info( mActivationCount.editValueFor(handle) );
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700218 Mutex::Autolock _l(mLock);
Aravind Akella724d91d2013-06-27 12:04:23 -0700219 info.removeBatchParamsForIdent(ident);
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700220}
221
Peng Xu6a2d3a02015-12-21 12:00:23 -0800222status_t SensorDevice::activate(void* ident, int handle, int enabled) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700223 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800224
Mathias Agopianf001c922010-11-11 17:58:51 -0800225 status_t err(NO_ERROR);
226 bool actuateHardware = false;
227
Aravind Akella724d91d2013-06-27 12:04:23 -0700228 Mutex::Autolock _l(mLock);
Mathias Agopianf001c922010-11-11 17:58:51 -0800229 Info& info( mActivationCount.editValueFor(handle) );
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700230
Steve Blocka5512372011-12-20 16:23:08 +0000231 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700232 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
Aravind Akella724d91d2013-06-27 12:04:23 -0700233 ident, handle, enabled, info.batchParams.size());
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700234
Mathias Agopianf001c922010-11-11 17:58:51 -0800235 if (enabled) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700236 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700237
Aravind Akella4949c502015-02-11 15:54:35 -0800238 if (isClientDisabledLocked(ident)) {
Peng Xu966fa882016-09-01 16:13:15 -0700239 ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
240 ident, handle);
Aravind Akella4949c502015-02-11 15:54:35 -0800241 return INVALID_OPERATION;
242 }
243
Aravind Akella724d91d2013-06-27 12:04:23 -0700244 if (info.batchParams.indexOfKey(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800245 if (info.numActiveClients() == 1) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700246 // This is the first connection, we need to activate the underlying h/w sensor.
247 actuateHardware = true;
248 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800249 } else {
Aravind Akella724d91d2013-06-27 12:04:23 -0700250 // Log error. Every activate call should be preceded by a batch() call.
251 ALOGE("\t >>>ERROR: activate called without batch");
Mathias Agopianf001c922010-11-11 17:58:51 -0800252 }
253 } else {
Mark Salyzyndb458612014-06-10 14:50:02 -0700254 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700255
Steven Morelandd15c0302016-12-20 11:14:50 -0800256 // If a connected dynamic sensor is deactivated, remove it from the
257 // dictionary.
258 auto it = mConnectedDynamicSensors.find(handle);
259 if (it != mConnectedDynamicSensors.end()) {
260 delete it->second;
261 mConnectedDynamicSensors.erase(it);
262 }
263
Aravind Akella724d91d2013-06-27 12:04:23 -0700264 if (info.removeBatchParamsForIdent(ident) >= 0) {
Aravind Akella4949c502015-02-11 15:54:35 -0800265 if (info.numActiveClients() == 0) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700266 // This is the last connection, we need to de-activate the underlying h/w sensor.
Mathias Agopian50b66762010-11-29 17:26:51 -0800267 actuateHardware = true;
Aravind Akella724d91d2013-06-27 12:04:23 -0700268 } else {
Steven Morelandd15c0302016-12-20 11:14:50 -0800269 // Call batch for this sensor with the previously calculated best effort
270 // batch_rate and timeout. One of the apps has unregistered for sensor
271 // events, and the best effort batch parameters might have changed.
272 ALOGD_IF(DEBUG_CONNECTIONS,
273 "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
274 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
275 info.bestBatchParams.batchTimeout);
Peng Xu3889e6e2017-03-02 19:10:38 -0800276 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800277 handle,
278 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800279 info.bestBatchParams.batchTimeout));
Mathias Agopian50b66762010-11-29 17:26:51 -0800280 }
281 } else {
282 // sensor wasn't enabled for this ident
283 }
Aravind Akella4949c502015-02-11 15:54:35 -0800284
285 if (isClientDisabledLocked(ident)) {
286 return NO_ERROR;
287 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800288 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800289
Mathias Agopianf001c922010-11-11 17:58:51 -0800290 if (actuateHardware) {
Aravind Akella4949c502015-02-11 15:54:35 -0800291 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
292 enabled);
Peng Xu3889e6e2017-03-02 19:10:38 -0800293 err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700294 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
295 strerror(-err));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700296
Aravind Akella724d91d2013-06-27 12:04:23 -0700297 if (err != NO_ERROR && enabled) {
298 // Failure when enabling the sensor. Clean up on failure.
299 info.removeBatchParamsForIdent(ident);
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700300 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800301 }
302
Mathias Agopianf001c922010-11-11 17:58:51 -0800303 return err;
304}
305
Steven Morelandd15c0302016-12-20 11:14:50 -0800306status_t SensorDevice::batch(
307 void* ident,
308 int handle,
309 int flags,
310 int64_t samplingPeriodNs,
311 int64_t maxBatchReportLatencyNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700312 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700313
314 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
315 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
316 }
317
Aravind Akella724d91d2013-06-27 12:04:23 -0700318 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700319 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
Aravind Akella724d91d2013-06-27 12:04:23 -0700320 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
321
322 Mutex::Autolock _l(mLock);
323 Info& info(mActivationCount.editValueFor(handle));
324
325 if (info.batchParams.indexOfKey(ident) < 0) {
326 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
327 info.batchParams.add(ident, params);
328 } else {
329 // A batch has already been called with this ident. Update the batch parameters.
330 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
331 }
332
333 BatchParams prevBestBatchParams = info.bestBatchParams;
334 // Find the minimum of all timeouts and batch_rates for this sensor.
335 info.selectBatchParams();
336
337 ALOGD_IF(DEBUG_CONNECTIONS,
Mark Salyzyndb458612014-06-10 14:50:02 -0700338 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
339 " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
Aravind Akella724d91d2013-06-27 12:04:23 -0700340 prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
341 prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
342
343 status_t err(NO_ERROR);
344 // If the min period or min timeout has changed since the last batch call, call batch.
345 if (prevBestBatchParams != info.bestBatchParams) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800346 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
347 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
348 info.bestBatchParams.batchTimeout);
349 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800350 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800351 handle,
352 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800353 info.bestBatchParams.batchTimeout)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700354 if (err != NO_ERROR) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700355 ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
Steven Morelandd15c0302016-12-20 11:14:50 -0800356 mSensors.get(), handle,
Aravind Akella724d91d2013-06-27 12:04:23 -0700357 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
358 info.bestBatchParams.batchTimeout, strerror(-err));
359 info.removeBatchParamsForIdent(ident);
360 }
361 }
362 return err;
363}
364
Peng Xu6a2d3a02015-12-21 12:00:23 -0800365status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700366 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700367 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
368 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
369 }
Mathias Agopian667102f2011-09-14 16:43:34 -0700370 Mutex::Autolock _l(mLock);
Aravind Akella4949c502015-02-11 15:54:35 -0800371 if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
Mathias Agopianf001c922010-11-11 17:58:51 -0800372 Info& info( mActivationCount.editValueFor(handle) );
Aravind Akella724d91d2013-06-27 12:04:23 -0700373 // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
374 // Calling setDelay() in batch mode is an invalid operation.
375 if (info.bestBatchParams.batchTimeout != 0) {
376 return INVALID_OPERATION;
377 }
378 ssize_t index = info.batchParams.indexOfKey(ident);
379 if (index < 0) {
380 return BAD_INDEX;
381 }
382 BatchParams& params = info.batchParams.editValueAt(index);
383 params.batchDelay = samplingPeriodNs;
384 info.selectBatchParams();
Steven Morelandd15c0302016-12-20 11:14:50 -0800385
386 return StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800387 checkReturn(mSensors->batch(handle, info.bestBatchParams.batchDelay, 0)));
Mathias Agopian667102f2011-09-14 16:43:34 -0700388}
389
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700390int SensorDevice::getHalDeviceVersion() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700391 if (mSensors == nullptr) return -1;
Steven Morelandd15c0302016-12-20 11:14:50 -0800392 return SENSORS_DEVICE_API_VERSION_1_4;
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700393}
394
Aravind Akella9a844cf2014-02-11 18:58:52 -0800395status_t SensorDevice::flush(void* ident, int handle) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700396 if (mSensors == nullptr) return NO_INIT;
Aravind Akella4949c502015-02-11 15:54:35 -0800397 if (isClientDisabled(ident)) return INVALID_OPERATION;
Aravind Akella724d91d2013-06-27 12:04:23 -0700398 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800399 return StatusFromResult(checkReturn(mSensors->flush(handle)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700400}
401
Aravind Akella4949c502015-02-11 15:54:35 -0800402bool SensorDevice::isClientDisabled(void* ident) {
403 Mutex::Autolock _l(mLock);
404 return isClientDisabledLocked(ident);
405}
406
407bool SensorDevice::isClientDisabledLocked(void* ident) {
408 return mDisabledClients.indexOf(ident) >= 0;
409}
410
411void SensorDevice::enableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700412 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800413 Mutex::Autolock _l(mLock);
414 mDisabledClients.clear();
Peng Xu966fa882016-09-01 16:13:15 -0700415 ALOGI("cleared mDisabledClients");
Aravind Akella4949c502015-02-11 15:54:35 -0800416 for (size_t i = 0; i< mActivationCount.size(); ++i) {
417 Info& info = mActivationCount.editValueAt(i);
418 if (info.batchParams.isEmpty()) continue;
419 info.selectBatchParams();
420 const int sensor_handle = mActivationCount.keyAt(i);
421 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
422 sensor_handle);
Steven Morelandd15c0302016-12-20 11:14:50 -0800423 status_t err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800424 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800425 sensor_handle,
426 info.bestBatchParams.batchDelay,
Peng Xu3889e6e2017-03-02 19:10:38 -0800427 info.bestBatchParams.batchTimeout)));
Steven Morelandd15c0302016-12-20 11:14:50 -0800428 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
Aravind Akella4949c502015-02-11 15:54:35 -0800429
430 if (err == NO_ERROR) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800431 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800432 checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
Aravind Akella4949c502015-02-11 15:54:35 -0800433 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
434 }
Aravind Akella4949c502015-02-11 15:54:35 -0800435 }
436}
437
438void SensorDevice::disableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700439 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800440 Mutex::Autolock _l(mLock);
Peng Xua8fad9b2017-03-17 12:20:27 -0700441 for (size_t i = 0; i< mActivationCount.size(); ++i) {
Aravind Akella4949c502015-02-11 15:54:35 -0800442 const Info& info = mActivationCount.valueAt(i);
443 // Check if this sensor has been activated previously and disable it.
444 if (info.batchParams.size() > 0) {
445 const int sensor_handle = mActivationCount.keyAt(i);
446 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
447 sensor_handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800448 checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
Steven Morelandd15c0302016-12-20 11:14:50 -0800449
Aravind Akella4949c502015-02-11 15:54:35 -0800450 // Add all the connections that were registered for this sensor to the disabled
451 // clients list.
Svetoslavb412f6e2015-04-29 16:50:41 -0700452 for (size_t j = 0; j < info.batchParams.size(); ++j) {
Aravind Akella4949c502015-02-11 15:54:35 -0800453 mDisabledClients.add(info.batchParams.keyAt(j));
Peng Xu966fa882016-09-01 16:13:15 -0700454 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
Aravind Akella4949c502015-02-11 15:54:35 -0800455 }
456 }
457 }
458}
459
Steven Morelandd15c0302016-12-20 11:14:50 -0800460status_t SensorDevice::injectSensorData(
461 const sensors_event_t *injected_sensor_event) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700462 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800463 ALOGD_IF(DEBUG_CONNECTIONS,
464 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
465 injected_sensor_event->sensor,
466 injected_sensor_event->timestamp, injected_sensor_event->data[0],
467 injected_sensor_event->data[1], injected_sensor_event->data[2],
468 injected_sensor_event->data[3], injected_sensor_event->data[4],
469 injected_sensor_event->data[5]);
470
471 Event ev;
472 convertFromSensorEvent(*injected_sensor_event, &ev);
473
Peng Xu3889e6e2017-03-02 19:10:38 -0800474 return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700475}
476
477status_t SensorDevice::setMode(uint32_t mode) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700478 if (mSensors == nullptr) return NO_INIT;
479 return StatusFromResult(
480 checkReturn(mSensors->setOperationMode(
481 static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
482}
Steven Morelandd15c0302016-12-20 11:14:50 -0800483
Peng Xua8fad9b2017-03-17 12:20:27 -0700484int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
485 if (mSensors == nullptr) return NO_INIT;
486 Mutex::Autolock _l(mLock);
487
488 SharedMemType type;
489 switch (memory->type) {
490 case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
491 type = SharedMemType::ASHMEM;
492 break;
493 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
494 type = SharedMemType::GRALLOC;
495 break;
496 default:
497 return BAD_VALUE;
498 }
499
500 SharedMemFormat format;
501 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
502 return BAD_VALUE;
503 }
504 format = SharedMemFormat::SENSORS_EVENT;
505
506 SharedMemInfo mem = {
507 .type = type,
508 .format = format,
509 .size = static_cast<uint32_t>(memory->size),
510 .memoryHandle = memory->handle,
511 };
512
513 int32_t ret;
514 checkReturn(mSensors->registerDirectChannel(mem,
515 [&ret](auto result, auto channelHandle) {
516 if (result == Result::OK) {
517 ret = channelHandle;
518 } else {
519 ret = StatusFromResult(result);
520 }
521 }));
522 return ret;
523}
524
525void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
526 if (mSensors == nullptr) return;
527 Mutex::Autolock _l(mLock);
528 checkReturn(mSensors->unregisterDirectChannel(channelHandle));
529}
530
531int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
532 int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
533 if (mSensors == nullptr) return NO_INIT;
534 Mutex::Autolock _l(mLock);
535
536 RateLevel rate;
537 switch(config->rate_level) {
538 case SENSOR_DIRECT_RATE_STOP:
539 rate = RateLevel::STOP;
540 break;
541 case SENSOR_DIRECT_RATE_NORMAL:
542 rate = RateLevel::NORMAL;
543 break;
544 case SENSOR_DIRECT_RATE_FAST:
545 rate = RateLevel::FAST;
546 break;
547 case SENSOR_DIRECT_RATE_VERY_FAST:
548 rate = RateLevel::VERY_FAST;
549 break;
550 default:
551 return BAD_VALUE;
552 }
553
554 int32_t ret;
555 checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
556 [&ret, rate] (auto result, auto token) {
557 if (rate == RateLevel::STOP) {
558 ret = StatusFromResult(result);
559 } else {
560 if (result == Result::OK) {
561 ret = token;
562 } else {
563 ret = StatusFromResult(result);
564 }
565 }
566 }));
567
568 return ret;
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700569}
570
Mathias Agopian667102f2011-09-14 16:43:34 -0700571// ---------------------------------------------------------------------------
572
Aravind Akella4949c502015-02-11 15:54:35 -0800573int SensorDevice::Info::numActiveClients() {
574 SensorDevice& device(SensorDevice::getInstance());
575 int num = 0;
576 for (size_t i = 0; i < batchParams.size(); ++i) {
577 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
578 ++num;
579 }
580 }
581 return num;
582}
583
Aravind Akella724d91d2013-06-27 12:04:23 -0700584status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
585 int64_t samplingPeriodNs,
586 int64_t maxBatchReportLatencyNs) {
587 ssize_t index = batchParams.indexOfKey(ident);
Mathias Agopian667102f2011-09-14 16:43:34 -0700588 if (index < 0) {
Mark Salyzyndb458612014-06-10 14:50:02 -0700589 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
Aravind Akella724d91d2013-06-27 12:04:23 -0700590 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
Mathias Agopian667102f2011-09-14 16:43:34 -0700591 return BAD_INDEX;
592 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700593 BatchParams& params = batchParams.editValueAt(index);
594 params.flags = flags;
595 params.batchDelay = samplingPeriodNs;
596 params.batchTimeout = maxBatchReportLatencyNs;
Mathias Agopian667102f2011-09-14 16:43:34 -0700597 return NO_ERROR;
598}
599
Aravind Akella724d91d2013-06-27 12:04:23 -0700600void SensorDevice::Info::selectBatchParams() {
Aravind Akella4949c502015-02-11 15:54:35 -0800601 BatchParams bestParams(0, -1, -1);
602 SensorDevice& device(SensorDevice::getInstance());
Aravind Akella724d91d2013-06-27 12:04:23 -0700603
Aravind Akella4949c502015-02-11 15:54:35 -0800604 for (size_t i = 0; i < batchParams.size(); ++i) {
605 if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
Aravind Akella724d91d2013-06-27 12:04:23 -0700606 BatchParams params = batchParams.valueAt(i);
Aravind Akella4949c502015-02-11 15:54:35 -0800607 if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700608 bestParams.batchDelay = params.batchDelay;
609 }
Aravind Akella4949c502015-02-11 15:54:35 -0800610 if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700611 bestParams.batchTimeout = params.batchTimeout;
Mathias Agopianf001c922010-11-11 17:58:51 -0800612 }
613 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700614 bestBatchParams = bestParams;
615}
616
617ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
618 ssize_t idx = batchParams.removeItem(ident);
619 if (idx >= 0) {
620 selectBatchParams();
621 }
622 return idx;
Mathias Agopianf001c922010-11-11 17:58:51 -0800623}
624
Peng Xu4f707f82016-09-26 11:28:32 -0700625void SensorDevice::notifyConnectionDestroyed(void* ident) {
626 Mutex::Autolock _l(mLock);
627 mDisabledClients.remove(ident);
628}
629
Peng Xu53632542017-01-23 20:06:27 -0800630bool SensorDevice::isDirectReportSupported() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800631 return mIsDirectReportSupported;
Peng Xu53632542017-01-23 20:06:27 -0800632}
Steven Morelandd15c0302016-12-20 11:14:50 -0800633
634void SensorDevice::convertToSensorEvent(
635 const Event &src, sensors_event_t *dst) {
636 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
637 src, dst);
638
639 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
640 const DynamicSensorInfo &dyn = src.u.dynamic;
641
642 dst->dynamic_sensor_meta.connected = dyn.connected;
643 dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
644 if (dyn.connected) {
645 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
646 CHECK(it != mConnectedDynamicSensors.end());
647
648 dst->dynamic_sensor_meta.sensor = it->second;
649
650 memcpy(dst->dynamic_sensor_meta.uuid,
651 dyn.uuid.data(),
652 sizeof(dst->dynamic_sensor_meta.uuid));
653 }
654 }
655}
656
657void SensorDevice::convertToSensorEvents(
658 const hidl_vec<Event> &src,
659 const hidl_vec<SensorInfo> &dynamicSensorsAdded,
660 sensors_event_t *dst) {
661 // Allocate a sensor_t structure for each dynamic sensor added and insert
662 // it into the dictionary of connected dynamic sensors keyed by handle.
663 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
664 const SensorInfo &info = dynamicSensorsAdded[i];
665
666 auto it = mConnectedDynamicSensors.find(info.sensorHandle);
667 CHECK(it == mConnectedDynamicSensors.end());
668
669 sensor_t *sensor = new sensor_t;
670 convertToSensor(info, sensor);
671
672 mConnectedDynamicSensors.insert(
673 std::make_pair(sensor->handle, sensor));
674 }
675
676 for (size_t i = 0; i < src.size(); ++i) {
677 convertToSensorEvent(src[i], &dst[i]);
678 }
679}
680
Peng Xu3889e6e2017-03-02 19:10:38 -0800681void SensorDevice::handleHidlDeath(const std::string & detail) {
682 // restart is the only option at present.
683 LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
684}
685
Mathias Agopianf001c922010-11-11 17:58:51 -0800686// ---------------------------------------------------------------------------
687}; // namespace android