blob: 986c268ba24d428cd28c0447082f144239c5cdb9 [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
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
Ashutosh Joshi96b12d82017-03-15 16:27:12 -070055SensorDevice::SensorDevice() : mHidlTransportErrors(20) {
Peng Xua8fad9b2017-03-17 12:20:27 -070056 if (!connectHidlService()) {
57 return;
58 }
59 checkReturn(mSensors->getSensorsList(
60 [&](const auto &list) {
61 const size_t count = list.size();
62
63 mActivationCount.setCapacity(count);
64 Info model;
65 for (size_t i=0 ; i < count; i++) {
66 sensor_t sensor;
67 convertToSensor(list[i], &sensor);
68 mSensorList.push_back(sensor);
69
70 mActivationCount.add(list[i].sensorHandle, model);
71
72 checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
73 }
74 }));
75
76 mIsDirectReportSupported =
77 (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
78}
79
80bool SensorDevice::connectHidlService() {
Peng Xu3889e6e2017-03-02 19:10:38 -080081 // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
82 constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
83 size_t retry = 10;
Steven Morelandd15c0302016-12-20 11:14:50 -080084
Peng Xu3889e6e2017-03-02 19:10:38 -080085 while (true) {
86 int initStep = 0;
87 mSensors = ISensors::getService();
88 if (mSensors != nullptr) {
89 ++initStep;
90 // Poke ISensor service. If it has lingering connection from previous generation of
91 // system server, it will kill itself. There is no intention to handle the poll result,
92 // which will be done since the size is 0.
93 if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
94 // ok to continue
95 break;
96 }
97 // hidl service is restarting, pointer is invalid.
98 mSensors = nullptr;
99 }
100
101 if (--retry <= 0) {
102 ALOGE("Cannot connect to ISensors hidl service!");
Peng Xua8fad9b2017-03-17 12:20:27 -0700103 break;
Peng Xu3889e6e2017-03-02 19:10:38 -0800104 }
105 // Delay 100ms before retry, hidl service is expected to come up in short time after
106 // crash.
107 ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
108 (initStep == 0) ? "getService()" : "poll() check", retry);
109 std::this_thread::sleep_for(RETRY_DELAY);
Steven Morelandd15c0302016-12-20 11:14:50 -0800110 }
Peng Xua8fad9b2017-03-17 12:20:27 -0700111 return (mSensors != nullptr);
Steven Morelandd15c0302016-12-20 11:14:50 -0800112}
113
Peng Xu2576cb62016-01-20 00:22:09 -0800114void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700115 // not need to check mSensors because this is is only called after successful poll()
Peng Xu2576cb62016-01-20 00:22:09 -0800116 if (connected) {
117 Info model;
118 mActivationCount.add(handle, model);
Peng Xu3889e6e2017-03-02 19:10:38 -0800119 checkReturn(mSensors->activate(handle, 0 /* enabled */));
Peng Xu2576cb62016-01-20 00:22:09 -0800120 } else {
121 mActivationCount.removeItem(handle);
122 }
123}
124
Peng Xu6a2d3a02015-12-21 12:00:23 -0800125std::string SensorDevice::dump() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700126 if (mSensors == nullptr) return "HAL not initialized\n";
Mathias Agopianf001c922010-11-11 17:58:51 -0800127
Peng Xu6a2d3a02015-12-21 12:00:23 -0800128 String8 result;
Peng Xua8fad9b2017-03-17 12:20:27 -0700129 result.appendFormat("Total %zu h/w sensors, %zu running:\n",
130 mSensorList.size(), mActivationCount.size());
Ashutosh Joshi96b12d82017-03-15 16:27:12 -0700131
Peng Xua8fad9b2017-03-17 12:20:27 -0700132 Mutex::Autolock _l(mLock);
133 for (const auto & s : mSensorList) {
134 int32_t handle = s.handle;
135 const Info& info = mActivationCount.valueFor(handle);
136 if (info.batchParams.isEmpty()) continue;
137
138 result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
139
140 result.append("sampling_period(ms) = {");
141 for (size_t j = 0; j < info.batchParams.size(); j++) {
Peng Xu2bec6232016-07-01 17:13:10 -0700142 const BatchParams& params = info.batchParams[j];
143 result.appendFormat("%.1f%s", params.mTSample / 1e6f,
Peng Xua8fad9b2017-03-17 12:20:27 -0700144 j < info.batchParams.size() - 1 ? ", " : "");
145 }
Peng Xu2bec6232016-07-01 17:13:10 -0700146 result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
Peng Xua8fad9b2017-03-17 12:20:27 -0700147
148 result.append("batching_period(ms) = {");
149 for (size_t j = 0; j < info.batchParams.size(); j++) {
Peng Xu2bec6232016-07-01 17:13:10 -0700150 const BatchParams& params = info.batchParams[j];
151 result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
Peng Xua8fad9b2017-03-17 12:20:27 -0700152 j < info.batchParams.size() - 1 ? ", " : "");
153 }
Peng Xu2bec6232016-07-01 17:13:10 -0700154 result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 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,
Peng Xu2bec6232016-07-01 17:13:10 -0700273 "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
274 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
Peng Xu3889e6e2017-03-02 19:10:38 -0800275 checkReturn(mSensors->batch(
Peng Xu2bec6232016-07-01 17:13:10 -0700276 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
Mathias Agopian50b66762010-11-29 17:26:51 -0800277 }
278 } else {
279 // sensor wasn't enabled for this ident
280 }
Aravind Akella4949c502015-02-11 15:54:35 -0800281
282 if (isClientDisabledLocked(ident)) {
283 return NO_ERROR;
284 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800285 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800286
Mathias Agopianf001c922010-11-11 17:58:51 -0800287 if (actuateHardware) {
Aravind Akella4949c502015-02-11 15:54:35 -0800288 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
289 enabled);
Peng Xu3889e6e2017-03-02 19:10:38 -0800290 err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700291 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
292 strerror(-err));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700293
Aravind Akella724d91d2013-06-27 12:04:23 -0700294 if (err != NO_ERROR && enabled) {
295 // Failure when enabling the sensor. Clean up on failure.
296 info.removeBatchParamsForIdent(ident);
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700297 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800298 }
299
Mathias Agopianf001c922010-11-11 17:58:51 -0800300 return err;
301}
302
Steven Morelandd15c0302016-12-20 11:14:50 -0800303status_t SensorDevice::batch(
304 void* ident,
305 int handle,
306 int flags,
307 int64_t samplingPeriodNs,
308 int64_t maxBatchReportLatencyNs) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700309 if (mSensors == nullptr) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700310
311 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
312 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
313 }
Peng Xu2bec6232016-07-01 17:13:10 -0700314 if (maxBatchReportLatencyNs < 0) {
315 maxBatchReportLatencyNs = 0;
316 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700317
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) {
Peng Xu2bec6232016-07-01 17:13:10 -0700326 BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
Aravind Akella724d91d2013-06-27 12:04:23 -0700327 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,
Peng Xu2bec6232016-07-01 17:13:10 -0700340 prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
341 prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
Aravind Akella724d91d2013-06-27 12:04:23 -0700342
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) {
Peng Xu2bec6232016-07-01 17:13:10 -0700346 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
347 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
Steven Morelandd15c0302016-12-20 11:14:50 -0800348 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800349 checkReturn(mSensors->batch(
Peng Xu2bec6232016-07-01 17:13:10 -0700350 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700351 if (err != NO_ERROR) {
Peng Xu2bec6232016-07-01 17:13:10 -0700352 ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
353 mSensors.get(), handle, info.bestBatchParams.mTSample,
354 info.bestBatchParams.mTBatch, strerror(-err));
Aravind Akella724d91d2013-06-27 12:04:23 -0700355 info.removeBatchParamsForIdent(ident);
356 }
357 }
358 return err;
359}
360
Peng Xu6a2d3a02015-12-21 12:00:23 -0800361status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
Peng Xu2bec6232016-07-01 17:13:10 -0700362 return batch(ident, handle, 0, samplingPeriodNs, 0);
Mathias Agopian667102f2011-09-14 16:43:34 -0700363}
364
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700365int SensorDevice::getHalDeviceVersion() const {
Peng Xua8fad9b2017-03-17 12:20:27 -0700366 if (mSensors == nullptr) return -1;
Steven Morelandd15c0302016-12-20 11:14:50 -0800367 return SENSORS_DEVICE_API_VERSION_1_4;
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700368}
369
Aravind Akella9a844cf2014-02-11 18:58:52 -0800370status_t SensorDevice::flush(void* ident, int handle) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700371 if (mSensors == nullptr) return NO_INIT;
Aravind Akella4949c502015-02-11 15:54:35 -0800372 if (isClientDisabled(ident)) return INVALID_OPERATION;
Aravind Akella724d91d2013-06-27 12:04:23 -0700373 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800374 return StatusFromResult(checkReturn(mSensors->flush(handle)));
Aravind Akella724d91d2013-06-27 12:04:23 -0700375}
376
Aravind Akella4949c502015-02-11 15:54:35 -0800377bool SensorDevice::isClientDisabled(void* ident) {
378 Mutex::Autolock _l(mLock);
379 return isClientDisabledLocked(ident);
380}
381
382bool SensorDevice::isClientDisabledLocked(void* ident) {
383 return mDisabledClients.indexOf(ident) >= 0;
384}
385
386void SensorDevice::enableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700387 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800388 Mutex::Autolock _l(mLock);
389 mDisabledClients.clear();
Peng Xu966fa882016-09-01 16:13:15 -0700390 ALOGI("cleared mDisabledClients");
Aravind Akella4949c502015-02-11 15:54:35 -0800391 for (size_t i = 0; i< mActivationCount.size(); ++i) {
392 Info& info = mActivationCount.editValueAt(i);
393 if (info.batchParams.isEmpty()) continue;
394 info.selectBatchParams();
395 const int sensor_handle = mActivationCount.keyAt(i);
396 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
397 sensor_handle);
Steven Morelandd15c0302016-12-20 11:14:50 -0800398 status_t err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800399 checkReturn(mSensors->batch(
Steven Morelandd15c0302016-12-20 11:14:50 -0800400 sensor_handle,
Peng Xu2bec6232016-07-01 17:13:10 -0700401 info.bestBatchParams.mTSample,
402 info.bestBatchParams.mTBatch)));
Steven Morelandd15c0302016-12-20 11:14:50 -0800403 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
Aravind Akella4949c502015-02-11 15:54:35 -0800404
405 if (err == NO_ERROR) {
Steven Morelandd15c0302016-12-20 11:14:50 -0800406 err = StatusFromResult(
Peng Xu3889e6e2017-03-02 19:10:38 -0800407 checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
Aravind Akella4949c502015-02-11 15:54:35 -0800408 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
409 }
Aravind Akella4949c502015-02-11 15:54:35 -0800410 }
411}
412
413void SensorDevice::disableAllSensors() {
Peng Xua8fad9b2017-03-17 12:20:27 -0700414 if (mSensors == nullptr) return;
Aravind Akella4949c502015-02-11 15:54:35 -0800415 Mutex::Autolock _l(mLock);
Peng Xua8fad9b2017-03-17 12:20:27 -0700416 for (size_t i = 0; i< mActivationCount.size(); ++i) {
Aravind Akella4949c502015-02-11 15:54:35 -0800417 const Info& info = mActivationCount.valueAt(i);
418 // Check if this sensor has been activated previously and disable it.
419 if (info.batchParams.size() > 0) {
420 const int sensor_handle = mActivationCount.keyAt(i);
421 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
422 sensor_handle);
Peng Xu3889e6e2017-03-02 19:10:38 -0800423 checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
Steven Morelandd15c0302016-12-20 11:14:50 -0800424
Aravind Akella4949c502015-02-11 15:54:35 -0800425 // Add all the connections that were registered for this sensor to the disabled
426 // clients list.
Svetoslavb412f6e2015-04-29 16:50:41 -0700427 for (size_t j = 0; j < info.batchParams.size(); ++j) {
Aravind Akella4949c502015-02-11 15:54:35 -0800428 mDisabledClients.add(info.batchParams.keyAt(j));
Peng Xu966fa882016-09-01 16:13:15 -0700429 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
Aravind Akella4949c502015-02-11 15:54:35 -0800430 }
431 }
432 }
433}
434
Steven Morelandd15c0302016-12-20 11:14:50 -0800435status_t SensorDevice::injectSensorData(
436 const sensors_event_t *injected_sensor_event) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700437 if (mSensors == nullptr) return NO_INIT;
Steven Morelandd15c0302016-12-20 11:14:50 -0800438 ALOGD_IF(DEBUG_CONNECTIONS,
439 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
440 injected_sensor_event->sensor,
441 injected_sensor_event->timestamp, injected_sensor_event->data[0],
442 injected_sensor_event->data[1], injected_sensor_event->data[2],
443 injected_sensor_event->data[3], injected_sensor_event->data[4],
444 injected_sensor_event->data[5]);
445
446 Event ev;
447 convertFromSensorEvent(*injected_sensor_event, &ev);
448
Peng Xu3889e6e2017-03-02 19:10:38 -0800449 return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700450}
451
452status_t SensorDevice::setMode(uint32_t mode) {
Peng Xua8fad9b2017-03-17 12:20:27 -0700453 if (mSensors == nullptr) return NO_INIT;
454 return StatusFromResult(
455 checkReturn(mSensors->setOperationMode(
456 static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
457}
Steven Morelandd15c0302016-12-20 11:14:50 -0800458
Peng Xua8fad9b2017-03-17 12:20:27 -0700459int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
460 if (mSensors == nullptr) return NO_INIT;
461 Mutex::Autolock _l(mLock);
462
463 SharedMemType type;
464 switch (memory->type) {
465 case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
466 type = SharedMemType::ASHMEM;
467 break;
468 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
469 type = SharedMemType::GRALLOC;
470 break;
471 default:
472 return BAD_VALUE;
473 }
474
475 SharedMemFormat format;
476 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
477 return BAD_VALUE;
478 }
479 format = SharedMemFormat::SENSORS_EVENT;
480
481 SharedMemInfo mem = {
482 .type = type,
483 .format = format,
484 .size = static_cast<uint32_t>(memory->size),
485 .memoryHandle = memory->handle,
486 };
487
488 int32_t ret;
489 checkReturn(mSensors->registerDirectChannel(mem,
490 [&ret](auto result, auto channelHandle) {
491 if (result == Result::OK) {
492 ret = channelHandle;
493 } else {
494 ret = StatusFromResult(result);
495 }
496 }));
497 return ret;
498}
499
500void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
501 if (mSensors == nullptr) return;
502 Mutex::Autolock _l(mLock);
503 checkReturn(mSensors->unregisterDirectChannel(channelHandle));
504}
505
506int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
507 int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
508 if (mSensors == nullptr) return NO_INIT;
509 Mutex::Autolock _l(mLock);
510
511 RateLevel rate;
512 switch(config->rate_level) {
513 case SENSOR_DIRECT_RATE_STOP:
514 rate = RateLevel::STOP;
515 break;
516 case SENSOR_DIRECT_RATE_NORMAL:
517 rate = RateLevel::NORMAL;
518 break;
519 case SENSOR_DIRECT_RATE_FAST:
520 rate = RateLevel::FAST;
521 break;
522 case SENSOR_DIRECT_RATE_VERY_FAST:
523 rate = RateLevel::VERY_FAST;
524 break;
525 default:
526 return BAD_VALUE;
527 }
528
529 int32_t ret;
530 checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
531 [&ret, rate] (auto result, auto token) {
532 if (rate == RateLevel::STOP) {
533 ret = StatusFromResult(result);
534 } else {
535 if (result == Result::OK) {
536 ret = token;
537 } else {
538 ret = StatusFromResult(result);
539 }
540 }
541 }));
542
543 return ret;
Aravind Akellaa9e6cc32015-04-16 18:57:31 -0700544}
545
Mathias Agopian667102f2011-09-14 16:43:34 -0700546// ---------------------------------------------------------------------------
547
Aravind Akella4949c502015-02-11 15:54:35 -0800548int SensorDevice::Info::numActiveClients() {
549 SensorDevice& device(SensorDevice::getInstance());
550 int num = 0;
551 for (size_t i = 0; i < batchParams.size(); ++i) {
552 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
553 ++num;
554 }
555 }
556 return num;
557}
558
Peng Xu2bec6232016-07-01 17:13:10 -0700559status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
Aravind Akella724d91d2013-06-27 12:04:23 -0700560 int64_t samplingPeriodNs,
561 int64_t maxBatchReportLatencyNs) {
562 ssize_t index = batchParams.indexOfKey(ident);
Mathias Agopian667102f2011-09-14 16:43:34 -0700563 if (index < 0) {
Peng Xu2bec6232016-07-01 17:13:10 -0700564 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
565 " timeout=%" PRId64 ") failed (%s)",
Aravind Akella724d91d2013-06-27 12:04:23 -0700566 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
Mathias Agopian667102f2011-09-14 16:43:34 -0700567 return BAD_INDEX;
568 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700569 BatchParams& params = batchParams.editValueAt(index);
Peng Xu2bec6232016-07-01 17:13:10 -0700570 params.mTSample = samplingPeriodNs;
571 params.mTBatch = maxBatchReportLatencyNs;
Mathias Agopian667102f2011-09-14 16:43:34 -0700572 return NO_ERROR;
573}
574
Aravind Akella724d91d2013-06-27 12:04:23 -0700575void SensorDevice::Info::selectBatchParams() {
Peng Xu2bec6232016-07-01 17:13:10 -0700576 BatchParams bestParams; // default to max Tsample and max Tbatch
Aravind Akella4949c502015-02-11 15:54:35 -0800577 SensorDevice& device(SensorDevice::getInstance());
Aravind Akella724d91d2013-06-27 12:04:23 -0700578
Aravind Akella4949c502015-02-11 15:54:35 -0800579 for (size_t i = 0; i < batchParams.size(); ++i) {
Peng Xu2bec6232016-07-01 17:13:10 -0700580 if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
581 continue;
Aravind Akella724d91d2013-06-27 12:04:23 -0700582 }
Peng Xu2bec6232016-07-01 17:13:10 -0700583 bestParams.merge(batchParams[i]);
584 }
585 // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
586 if (bestParams.mTBatch <= bestParams.mTSample) {
587 bestParams.mTBatch = 0;
Mathias Agopianf001c922010-11-11 17:58:51 -0800588 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700589 bestBatchParams = bestParams;
590}
591
592ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
593 ssize_t idx = batchParams.removeItem(ident);
594 if (idx >= 0) {
595 selectBatchParams();
596 }
597 return idx;
Mathias Agopianf001c922010-11-11 17:58:51 -0800598}
599
Peng Xu4f707f82016-09-26 11:28:32 -0700600void SensorDevice::notifyConnectionDestroyed(void* ident) {
601 Mutex::Autolock _l(mLock);
602 mDisabledClients.remove(ident);
603}
604
Peng Xu53632542017-01-23 20:06:27 -0800605bool SensorDevice::isDirectReportSupported() const {
Steven Morelandd15c0302016-12-20 11:14:50 -0800606 return mIsDirectReportSupported;
Peng Xu53632542017-01-23 20:06:27 -0800607}
Steven Morelandd15c0302016-12-20 11:14:50 -0800608
609void SensorDevice::convertToSensorEvent(
610 const Event &src, sensors_event_t *dst) {
611 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
612 src, dst);
613
614 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
615 const DynamicSensorInfo &dyn = src.u.dynamic;
616
617 dst->dynamic_sensor_meta.connected = dyn.connected;
618 dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
619 if (dyn.connected) {
620 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
621 CHECK(it != mConnectedDynamicSensors.end());
622
623 dst->dynamic_sensor_meta.sensor = it->second;
624
625 memcpy(dst->dynamic_sensor_meta.uuid,
626 dyn.uuid.data(),
627 sizeof(dst->dynamic_sensor_meta.uuid));
628 }
629 }
630}
631
632void SensorDevice::convertToSensorEvents(
633 const hidl_vec<Event> &src,
634 const hidl_vec<SensorInfo> &dynamicSensorsAdded,
635 sensors_event_t *dst) {
636 // Allocate a sensor_t structure for each dynamic sensor added and insert
637 // it into the dictionary of connected dynamic sensors keyed by handle.
638 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
639 const SensorInfo &info = dynamicSensorsAdded[i];
640
641 auto it = mConnectedDynamicSensors.find(info.sensorHandle);
642 CHECK(it == mConnectedDynamicSensors.end());
643
644 sensor_t *sensor = new sensor_t;
645 convertToSensor(info, sensor);
646
647 mConnectedDynamicSensors.insert(
648 std::make_pair(sensor->handle, sensor));
649 }
650
651 for (size_t i = 0; i < src.size(); ++i) {
652 convertToSensorEvent(src[i], &dst[i]);
653 }
654}
655
Peng Xu3889e6e2017-03-02 19:10:38 -0800656void SensorDevice::handleHidlDeath(const std::string & detail) {
657 // restart is the only option at present.
658 LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
659}
660
Mathias Agopianf001c922010-11-11 17:58:51 -0800661// ---------------------------------------------------------------------------
662}; // namespace android