blob: 2877589af4cb8e357af254c248cf23266d9d358b [file] [log] [blame]
Andreas Huber99fdbb52016-10-10 13:22:58 -07001/*
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 */
16
17#include <inttypes.h>
18#include <math.h>
19#include <stdint.h>
20#include <sys/types.h>
21
22#include <android-base/logging.h>
Andreas Huber99fdbb52016-10-10 13:22:58 -070023#include <utils/Atomic.h>
24#include <utils/Errors.h>
25#include <utils/Singleton.h>
26
27#include "SensorDevice.h"
28#include "SensorService.h"
29
Steven Morelandbc9cb442016-11-07 19:19:26 -080030#include <sensors/convert.h>
Andreas Huber99fdbb52016-10-10 13:22:58 -070031
Andreas Huber99fdbb52016-10-10 13:22:58 -070032using android::hardware::hidl_vec;
33
Peng Xue36e3472016-11-03 11:57:10 -070034using namespace android::hardware::sensors::V1_0;
Andreas Huber99fdbb52016-10-10 13:22:58 -070035using namespace android::hardware::sensors::V1_0::implementation;
36
37namespace android {
38// ---------------------------------------------------------------------------
39
40ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
41
42static status_t StatusFromResult(Result result) {
43 switch (result) {
44 case Result::OK:
45 return OK;
46 case Result::BAD_VALUE:
47 return BAD_VALUE;
48 case Result::PERMISSION_DENIED:
49 return PERMISSION_DENIED;
50 case Result::INVALID_OPERATION:
51 return INVALID_OPERATION;
Martijn Coenenb41a3852017-01-11 14:57:42 +010052 case Result::NO_MEMORY:
53 return NO_MEMORY;
Andreas Huber99fdbb52016-10-10 13:22:58 -070054 }
55}
56
57SensorDevice::SensorDevice() {
58 mSensors = ISensors::getService("sensors");
59
60 if (mSensors == NULL) {
61 return;
62 }
63
64 mSensors->getSensorsList(
65 [&](const auto &list) {
66 const size_t count = list.size();
67
68 mActivationCount.setCapacity(count);
69 Info model;
70 for (size_t i=0 ; i < count; i++) {
71 sensor_t sensor;
72 convertToSensor(list[i], &sensor);
73 mSensorList.push_back(sensor);
74
75 mActivationCount.add(list[i].sensorHandle, model);
76
Peng Xud08d30c2017-01-12 20:02:47 -080077 mSensors->activate(list[i].sensorHandle, 0 /* enabled */);
Andreas Huber99fdbb52016-10-10 13:22:58 -070078 }
79 });
80}
81
82void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
83 if (connected) {
84 Info model;
85 mActivationCount.add(handle, model);
Peng Xud08d30c2017-01-12 20:02:47 -080086 mSensors->activate(handle, 0 /* enabled */);
Andreas Huber99fdbb52016-10-10 13:22:58 -070087 } else {
88 mActivationCount.removeItem(handle);
89 }
90}
91
92std::string SensorDevice::dump() const {
93 if (mSensors == NULL) return "HAL not initialized\n";
94
Andreas Huber99fdbb52016-10-10 13:22:58 -070095 String8 result;
96 mSensors->getSensorsList([&](const auto &list) {
97 const size_t count = list.size();
98
99 result.appendFormat(
100 "Total %zu h/w sensors, %zu running:\n",
101 count,
102 mActivationCount.size());
103
104 Mutex::Autolock _l(mLock);
105 for (size_t i = 0 ; i < count ; i++) {
106 const Info& info = mActivationCount.valueFor(
107 list[i].sensorHandle);
108
109 if (info.batchParams.isEmpty()) continue;
110 result.appendFormat(
111 "0x%08x) active-count = %zu; ",
112 list[i].sensorHandle,
113 info.batchParams.size());
114
115 result.append("sampling_period(ms) = {");
116 for (size_t j = 0; j < info.batchParams.size(); j++) {
117 const BatchParams& params = info.batchParams.valueAt(j);
118 result.appendFormat(
119 "%.1f%s",
120 params.batchDelay / 1e6f,
121 j < info.batchParams.size() - 1 ? ", " : "");
122 }
123 result.appendFormat(
124 "}, selected = %.1f ms; ",
125 info.bestBatchParams.batchDelay / 1e6f);
126
127 result.append("batching_period(ms) = {");
128 for (size_t j = 0; j < info.batchParams.size(); j++) {
129 BatchParams params = info.batchParams.valueAt(j);
130
131 result.appendFormat(
132 "%.1f%s",
133 params.batchTimeout / 1e6f,
134 j < info.batchParams.size() - 1 ? ", " : "");
135 }
136
137 result.appendFormat(
138 "}, selected = %.1f ms\n",
139 info.bestBatchParams.batchTimeout / 1e6f);
140 }
141 });
142
143 return result.string();
144}
145
146ssize_t SensorDevice::getSensorList(sensor_t const** list) {
147 *list = &mSensorList[0];
148
149 return mSensorList.size();
150}
151
152status_t SensorDevice::initCheck() const {
153 return mSensors != NULL ? NO_ERROR : NO_INIT;
154}
155
156ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
157 if (mSensors == NULL) return NO_INIT;
158
159 ssize_t err;
160
161 mSensors->poll(
162 count,
163 [&](auto result,
164 const auto &events,
165 const auto &dynamicSensorsAdded) {
166 if (result == Result::OK) {
167 convertToSensorEvents(events, dynamicSensorsAdded, buffer);
168 err = (ssize_t)events.size();
169 } else {
170 err = StatusFromResult(result);
171 }
172 });
173
174 return err;
175}
176
177void SensorDevice::autoDisable(void *ident, int handle) {
178 Info& info( mActivationCount.editValueFor(handle) );
179 Mutex::Autolock _l(mLock);
180 info.removeBatchParamsForIdent(ident);
181}
182
183status_t SensorDevice::activate(void* ident, int handle, int enabled) {
184 if (mSensors == NULL) return NO_INIT;
185
186 status_t err(NO_ERROR);
187 bool actuateHardware = false;
188
189 Mutex::Autolock _l(mLock);
190 Info& info( mActivationCount.editValueFor(handle) );
191
192 ALOGD_IF(DEBUG_CONNECTIONS,
193 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
194 ident, handle, enabled, info.batchParams.size());
195
196 if (enabled) {
197 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
198
199 if (isClientDisabledLocked(ident)) {
200 ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
201 ident, handle);
202 return INVALID_OPERATION;
203 }
204
205 if (info.batchParams.indexOfKey(ident) >= 0) {
206 if (info.numActiveClients() == 1) {
207 // This is the first connection, we need to activate the underlying h/w sensor.
208 actuateHardware = true;
209 }
210 } else {
211 // Log error. Every activate call should be preceded by a batch() call.
212 ALOGE("\t >>>ERROR: activate called without batch");
213 }
214 } else {
215 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
216
217 // If a connected dynamic sensor is deactivated, remove it from the
218 // dictionary.
219 auto it = mConnectedDynamicSensors.find(handle);
220 if (it != mConnectedDynamicSensors.end()) {
221 delete it->second;
222 mConnectedDynamicSensors.erase(it);
223 }
224
225 if (info.removeBatchParamsForIdent(ident) >= 0) {
226 if (info.numActiveClients() == 0) {
227 // This is the last connection, we need to de-activate the underlying h/w sensor.
228 actuateHardware = true;
229 } else {
Peng Xud08d30c2017-01-12 20:02:47 -0800230 // Call batch for this sensor with the previously calculated best effort
231 // batch_rate and timeout. One of the apps has unregistered for sensor
232 // events, and the best effort batch parameters might have changed.
233 ALOGD_IF(DEBUG_CONNECTIONS,
234 "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
235 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
236 info.bestBatchParams.batchTimeout);
237 mSensors->batch(
238 handle,
239 info.bestBatchParams.batchDelay,
240 info.bestBatchParams.batchTimeout);
Andreas Huber99fdbb52016-10-10 13:22:58 -0700241 }
242 } else {
243 // sensor wasn't enabled for this ident
244 }
245
246 if (isClientDisabledLocked(ident)) {
247 return NO_ERROR;
248 }
249 }
250
251 if (actuateHardware) {
252 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
253 enabled);
254 err = StatusFromResult(mSensors->activate(handle, enabled));
255 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
256 strerror(-err));
257
258 if (err != NO_ERROR && enabled) {
259 // Failure when enabling the sensor. Clean up on failure.
260 info.removeBatchParamsForIdent(ident);
261 }
262 }
263
Andreas Huber99fdbb52016-10-10 13:22:58 -0700264 return err;
265}
266
267status_t SensorDevice::batch(
268 void* ident,
269 int handle,
270 int flags,
271 int64_t samplingPeriodNs,
272 int64_t maxBatchReportLatencyNs) {
273 if (mSensors == NULL) return NO_INIT;
274
275 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
276 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
277 }
278
Andreas Huber99fdbb52016-10-10 13:22:58 -0700279 ALOGD_IF(DEBUG_CONNECTIONS,
280 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
281 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
282
283 Mutex::Autolock _l(mLock);
284 Info& info(mActivationCount.editValueFor(handle));
285
286 if (info.batchParams.indexOfKey(ident) < 0) {
287 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
288 info.batchParams.add(ident, params);
289 } else {
290 // A batch has already been called with this ident. Update the batch parameters.
291 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
292 }
293
294 BatchParams prevBestBatchParams = info.bestBatchParams;
295 // Find the minimum of all timeouts and batch_rates for this sensor.
296 info.selectBatchParams();
297
298 ALOGD_IF(DEBUG_CONNECTIONS,
299 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
300 " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
301 prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
302 prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
303
304 status_t err(NO_ERROR);
305 // If the min period or min timeout has changed since the last batch call, call batch.
306 if (prevBestBatchParams != info.bestBatchParams) {
Peng Xud08d30c2017-01-12 20:02:47 -0800307 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
308 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
309 info.bestBatchParams.batchTimeout);
310 err = StatusFromResult(
311 mSensors->batch(
312 handle,
313 info.bestBatchParams.batchDelay,
314 info.bestBatchParams.batchTimeout));
Andreas Huber99fdbb52016-10-10 13:22:58 -0700315 if (err != NO_ERROR) {
316 ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
317 mSensors.get(), handle,
318 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
319 info.bestBatchParams.batchTimeout, strerror(-err));
320 info.removeBatchParamsForIdent(ident);
321 }
322 }
323 return err;
324}
325
326status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
327 if (mSensors == NULL) return NO_INIT;
328 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
329 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
330 }
331 Mutex::Autolock _l(mLock);
332 if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
333 Info& info( mActivationCount.editValueFor(handle) );
334 // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
335 // Calling setDelay() in batch mode is an invalid operation.
336 if (info.bestBatchParams.batchTimeout != 0) {
337 return INVALID_OPERATION;
338 }
339 ssize_t index = info.batchParams.indexOfKey(ident);
340 if (index < 0) {
341 return BAD_INDEX;
342 }
343 BatchParams& params = info.batchParams.editValueAt(index);
344 params.batchDelay = samplingPeriodNs;
345 info.selectBatchParams();
346
347 return StatusFromResult(
Peng Xud08d30c2017-01-12 20:02:47 -0800348 mSensors->batch(handle, info.bestBatchParams.batchDelay, 0));
Andreas Huber99fdbb52016-10-10 13:22:58 -0700349}
350
351int SensorDevice::getHalDeviceVersion() const {
352 if (mSensors == NULL) return -1;
353 return SENSORS_DEVICE_API_VERSION_1_4;
354}
355
356status_t SensorDevice::flush(void* ident, int handle) {
Andreas Huber99fdbb52016-10-10 13:22:58 -0700357 if (isClientDisabled(ident)) return INVALID_OPERATION;
358 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
359 return StatusFromResult(mSensors->flush(handle));
360}
361
362bool SensorDevice::isClientDisabled(void* ident) {
363 Mutex::Autolock _l(mLock);
364 return isClientDisabledLocked(ident);
365}
366
367bool SensorDevice::isClientDisabledLocked(void* ident) {
368 return mDisabledClients.indexOf(ident) >= 0;
369}
370
371void SensorDevice::enableAllSensors() {
372 Mutex::Autolock _l(mLock);
373 mDisabledClients.clear();
374 ALOGI("cleared mDisabledClients");
Andreas Huber99fdbb52016-10-10 13:22:58 -0700375 for (size_t i = 0; i< mActivationCount.size(); ++i) {
376 Info& info = mActivationCount.editValueAt(i);
377 if (info.batchParams.isEmpty()) continue;
378 info.selectBatchParams();
379 const int sensor_handle = mActivationCount.keyAt(i);
380 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
381 sensor_handle);
Peng Xud08d30c2017-01-12 20:02:47 -0800382 status_t err = StatusFromResult(
383 mSensors->batch(
384 sensor_handle,
385 info.bestBatchParams.batchDelay,
386 info.bestBatchParams.batchTimeout));
387 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
Andreas Huber99fdbb52016-10-10 13:22:58 -0700388
389 if (err == NO_ERROR) {
390 err = StatusFromResult(
391 mSensors->activate(sensor_handle, 1 /* enabled */));
392 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
393 }
Andreas Huber99fdbb52016-10-10 13:22:58 -0700394 }
395}
396
397void SensorDevice::disableAllSensors() {
398 Mutex::Autolock _l(mLock);
399 for (size_t i = 0; i< mActivationCount.size(); ++i) {
400 const Info& info = mActivationCount.valueAt(i);
401 // Check if this sensor has been activated previously and disable it.
402 if (info.batchParams.size() > 0) {
403 const int sensor_handle = mActivationCount.keyAt(i);
404 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
405 sensor_handle);
Peng Xud08d30c2017-01-12 20:02:47 -0800406 mSensors->activate(sensor_handle, 0 /* enabled */);
Andreas Huber99fdbb52016-10-10 13:22:58 -0700407
408 // Add all the connections that were registered for this sensor to the disabled
409 // clients list.
410 for (size_t j = 0; j < info.batchParams.size(); ++j) {
411 mDisabledClients.add(info.batchParams.keyAt(j));
412 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
413 }
414 }
415 }
416}
417
418status_t SensorDevice::injectSensorData(
419 const sensors_event_t *injected_sensor_event) {
420 ALOGD_IF(DEBUG_CONNECTIONS,
421 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
422 injected_sensor_event->sensor,
423 injected_sensor_event->timestamp, injected_sensor_event->data[0],
424 injected_sensor_event->data[1], injected_sensor_event->data[2],
425 injected_sensor_event->data[3], injected_sensor_event->data[4],
426 injected_sensor_event->data[5]);
427
Andreas Huber99fdbb52016-10-10 13:22:58 -0700428 Event ev;
429 convertFromSensorEvent(*injected_sensor_event, &ev);
430
431 return StatusFromResult(mSensors->injectSensorData(ev));
432}
433
434status_t SensorDevice::setMode(uint32_t mode) {
Andreas Huber99fdbb52016-10-10 13:22:58 -0700435
436 return StatusFromResult(
437 mSensors->setOperationMode(
438 static_cast<hardware::sensors::V1_0::OperationMode>(mode)));
439}
440
441// ---------------------------------------------------------------------------
442
443int SensorDevice::Info::numActiveClients() {
444 SensorDevice& device(SensorDevice::getInstance());
445 int num = 0;
446 for (size_t i = 0; i < batchParams.size(); ++i) {
447 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
448 ++num;
449 }
450 }
451 return num;
452}
453
454status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
455 int64_t samplingPeriodNs,
456 int64_t maxBatchReportLatencyNs) {
457 ssize_t index = batchParams.indexOfKey(ident);
458 if (index < 0) {
459 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
460 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
461 return BAD_INDEX;
462 }
463 BatchParams& params = batchParams.editValueAt(index);
464 params.flags = flags;
465 params.batchDelay = samplingPeriodNs;
466 params.batchTimeout = maxBatchReportLatencyNs;
467 return NO_ERROR;
468}
469
470void SensorDevice::Info::selectBatchParams() {
471 BatchParams bestParams(0, -1, -1);
472 SensorDevice& device(SensorDevice::getInstance());
473
474 for (size_t i = 0; i < batchParams.size(); ++i) {
475 if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
476 BatchParams params = batchParams.valueAt(i);
477 if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
478 bestParams.batchDelay = params.batchDelay;
479 }
480 if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
481 bestParams.batchTimeout = params.batchTimeout;
482 }
483 }
484 bestBatchParams = bestParams;
485}
486
487ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
488 ssize_t idx = batchParams.removeItem(ident);
489 if (idx >= 0) {
490 selectBatchParams();
491 }
492 return idx;
493}
494
495void SensorDevice::notifyConnectionDestroyed(void* ident) {
496 Mutex::Autolock _l(mLock);
497 mDisabledClients.remove(ident);
498}
499
Peng Xue36e3472016-11-03 11:57:10 -0700500int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
501 Mutex::Autolock _l(mLock);
502
503 SharedMemType type;
504 switch (memory->type) {
505 case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
506 type = SharedMemType::ASHMEM;
507 break;
508 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
509 type = SharedMemType::GRALLOC;
510 break;
511 default:
512 return BAD_VALUE;
513 }
514
515 SharedMemFormat format;
516 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
517 return BAD_VALUE;
518 }
519 format = SharedMemFormat::SENSORS_EVENT;
520
521 SharedMemInfo mem = {
522 .type = type,
523 .format = format,
524 .size = static_cast<uint32_t>(memory->size),
525 .memoryHandle = memory->handle,
526 };
527
528 int32_t ret;
529 mSensors->registerDirectChannel(mem,
530 [&ret](auto result, auto channelHandle) {
531 if (result == Result::OK) {
532 ret = channelHandle;
533 } else {
534 ret = StatusFromResult(result);
535 }
536 });
537 return ret;
538}
539
540void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
541 Mutex::Autolock _l(mLock);
542 mSensors->unregisterDirectChannel(channelHandle);
543}
544
545int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
546 int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
547 Mutex::Autolock _l(mLock);
548
549 RateLevel rate;
550 switch(config->rate_level) {
551 case SENSOR_DIRECT_RATE_STOP:
552 rate = RateLevel::STOP;
553 break;
554 case SENSOR_DIRECT_RATE_NORMAL:
555 rate = RateLevel::NORMAL;
556 break;
557 case SENSOR_DIRECT_RATE_FAST:
558 rate = RateLevel::FAST;
559 break;
560 case SENSOR_DIRECT_RATE_VERY_FAST:
561 rate = RateLevel::VERY_FAST;
562 break;
563 default:
564 return BAD_VALUE;
565 }
566
567 int32_t ret;
568 mSensors->configDirectReport(sensorHandle, channelHandle, rate,
569 [&ret, rate] (auto result, auto token) {
570 if (rate == RateLevel::STOP) {
571 ret = StatusFromResult(result);
572 } else {
573 if (result == Result::OK) {
574 ret = token;
575 } else {
576 ret = StatusFromResult(result);
577 }
578 }
579 });
580
581 return ret;
582}
583
Andreas Huber99fdbb52016-10-10 13:22:58 -0700584void SensorDevice::convertToSensorEvent(
585 const Event &src, sensors_event_t *dst) {
586 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
587 src, dst);
588
Peng Xud08d30c2017-01-12 20:02:47 -0800589 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
Andreas Huber99fdbb52016-10-10 13:22:58 -0700590 const DynamicSensorInfo &dyn = src.u.dynamic;
591
592 dst->dynamic_sensor_meta.connected = dyn.connected;
593 dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
594 if (dyn.connected) {
595 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
596 CHECK(it != mConnectedDynamicSensors.end());
597
598 dst->dynamic_sensor_meta.sensor = it->second;
599
600 memcpy(dst->dynamic_sensor_meta.uuid,
601 dyn.uuid.data(),
602 sizeof(dst->dynamic_sensor_meta.uuid));
603 }
604 }
605}
606
607void SensorDevice::convertToSensorEvents(
608 const hidl_vec<Event> &src,
609 const hidl_vec<SensorInfo> &dynamicSensorsAdded,
610 sensors_event_t *dst) {
611 // Allocate a sensor_t structure for each dynamic sensor added and insert
612 // it into the dictionary of connected dynamic sensors keyed by handle.
613 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
614 const SensorInfo &info = dynamicSensorsAdded[i];
615
616 auto it = mConnectedDynamicSensors.find(info.sensorHandle);
617 CHECK(it == mConnectedDynamicSensors.end());
618
619 sensor_t *sensor = new sensor_t;
620 convertToSensor(info, sensor);
621
622 mConnectedDynamicSensors.insert(
623 std::make_pair(sensor->handle, sensor));
624 }
625
626 for (size_t i = 0; i < src.size(); ++i) {
627 convertToSensorEvent(src[i], &dst[i]);
628 }
629}
630
631// ---------------------------------------------------------------------------
632}; // namespace android
633