• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #include "SensorDevice.h"
17 #include "SensorService.h"
18 
19 #include <android-base/logging.h>
20 #include <sensors/convert.h>
21 #include <utils/Atomic.h>
22 #include <utils/Errors.h>
23 #include <utils/Singleton.h>
24 
25 #include <chrono>
26 #include <cinttypes>
27 #include <thread>
28 
29 using android::hardware::hidl_vec;
30 
31 using namespace android::hardware::sensors::V1_0;
32 using namespace android::hardware::sensors::V1_0::implementation;
33 
34 
35 namespace android {
36 // ---------------------------------------------------------------------------
37 
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39 
40 static 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;
52     }
53 }
54 
SensorDevice()55 SensorDevice::SensorDevice() : mHidlTransportErrors(20) {
56     if (!connectHidlService()) {
57         return;
58     }
59 
60     float minPowerMa = 0.001; // 1 microAmp
61 
62     checkReturn(mSensors->getSensorsList(
63             [&](const auto &list) {
64                 const size_t count = list.size();
65 
66                 mActivationCount.setCapacity(count);
67                 Info model;
68                 for (size_t i=0 ; i < count; i++) {
69                     sensor_t sensor;
70                     convertToSensor(list[i], &sensor);
71                     // Sanity check and clamp power if it is 0 (or close)
72                     if (sensor.power < minPowerMa) {
73                         ALOGE("Reported power %f not deemed sane, clamping to %f",
74                               sensor.power, minPowerMa);
75                         sensor.power = minPowerMa;
76                     }
77                     mSensorList.push_back(sensor);
78 
79                     mActivationCount.add(list[i].sensorHandle, model);
80 
81                     checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
82                 }
83             }));
84 
85     mIsDirectReportSupported =
86            (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
87 }
88 
connectHidlService()89 bool SensorDevice::connectHidlService() {
90     // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
91     constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
92     size_t retry = 10;
93 
94     while (true) {
95         int initStep = 0;
96         mSensors = ISensors::getService();
97         if (mSensors != nullptr) {
98             ++initStep;
99             // Poke ISensor service. If it has lingering connection from previous generation of
100             // system server, it will kill itself. There is no intention to handle the poll result,
101             // which will be done since the size is 0.
102             if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
103                 // ok to continue
104                 break;
105             }
106             // hidl service is restarting, pointer is invalid.
107             mSensors = nullptr;
108         }
109 
110         if (--retry <= 0) {
111             ALOGE("Cannot connect to ISensors hidl service!");
112             break;
113         }
114         // Delay 100ms before retry, hidl service is expected to come up in short time after
115         // crash.
116         ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
117                 (initStep == 0) ? "getService()" : "poll() check", retry);
118         std::this_thread::sleep_for(RETRY_DELAY);
119     }
120     return (mSensors != nullptr);
121 }
122 
handleDynamicSensorConnection(int handle,bool connected)123 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
124     // not need to check mSensors because this is is only called after successful poll()
125     if (connected) {
126         Info model;
127         mActivationCount.add(handle, model);
128         checkReturn(mSensors->activate(handle, 0 /* enabled */));
129     } else {
130         mActivationCount.removeItem(handle);
131     }
132 }
133 
dump() const134 std::string SensorDevice::dump() const {
135     if (mSensors == nullptr) return "HAL not initialized\n";
136 
137     String8 result;
138     result.appendFormat("Total %zu h/w sensors, %zu running:\n",
139                         mSensorList.size(), mActivationCount.size());
140 
141     Mutex::Autolock _l(mLock);
142     for (const auto & s : mSensorList) {
143         int32_t handle = s.handle;
144         const Info& info = mActivationCount.valueFor(handle);
145         if (info.batchParams.isEmpty()) continue;
146 
147         result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
148 
149         result.append("sampling_period(ms) = {");
150         for (size_t j = 0; j < info.batchParams.size(); j++) {
151             const BatchParams& params = info.batchParams[j];
152             result.appendFormat("%.1f%s", params.mTSample / 1e6f,
153                 j < info.batchParams.size() - 1 ? ", " : "");
154         }
155         result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
156 
157         result.append("batching_period(ms) = {");
158         for (size_t j = 0; j < info.batchParams.size(); j++) {
159             const BatchParams& params = info.batchParams[j];
160             result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
161                     j < info.batchParams.size() - 1 ? ", " : "");
162         }
163         result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
164     }
165 
166     return result.string();
167 }
168 
getSensorList(sensor_t const ** list)169 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
170     *list = &mSensorList[0];
171 
172     return mSensorList.size();
173 }
174 
initCheck() const175 status_t SensorDevice::initCheck() const {
176     return mSensors != NULL ? NO_ERROR : NO_INIT;
177 }
178 
poll(sensors_event_t * buffer,size_t count)179 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
180     if (mSensors == nullptr) return NO_INIT;
181 
182     ssize_t err;
183     int numHidlTransportErrors = 0;
184     bool hidlTransportError = false;
185 
186     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     }
221 
222     return err;
223 }
224 
autoDisable(void * ident,int handle)225 void SensorDevice::autoDisable(void *ident, int handle) {
226     Info& info( mActivationCount.editValueFor(handle) );
227     Mutex::Autolock _l(mLock);
228     info.removeBatchParamsForIdent(ident);
229 }
230 
activate(void * ident,int handle,int enabled)231 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
232     if (mSensors == nullptr) return NO_INIT;
233 
234     status_t err(NO_ERROR);
235     bool actuateHardware = false;
236 
237     Mutex::Autolock _l(mLock);
238     Info& info( mActivationCount.editValueFor(handle) );
239 
240     ALOGD_IF(DEBUG_CONNECTIONS,
241              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
242              ident, handle, enabled, info.batchParams.size());
243 
244     if (enabled) {
245         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
246 
247         if (isClientDisabledLocked(ident)) {
248             ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
249                     ident, handle);
250             return INVALID_OPERATION;
251         }
252 
253         if (info.batchParams.indexOfKey(ident) >= 0) {
254           if (info.numActiveClients() == 1) {
255               // This is the first connection, we need to activate the underlying h/w sensor.
256               actuateHardware = true;
257           }
258         } else {
259             // Log error. Every activate call should be preceded by a batch() call.
260             ALOGE("\t >>>ERROR: activate called without batch");
261         }
262     } else {
263         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
264 
265         // 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 
273         if (info.removeBatchParamsForIdent(ident) >= 0) {
274             if (info.numActiveClients() == 0) {
275                 // This is the last connection, we need to de-activate the underlying h/w sensor.
276                 actuateHardware = true;
277             } else {
278                 // 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 0x%08x %" PRId64 " %" PRId64, handle,
283                          info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
284                 checkReturn(mSensors->batch(
285                         handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
286             }
287         } else {
288             // sensor wasn't enabled for this ident
289         }
290 
291         if (isClientDisabledLocked(ident)) {
292             return NO_ERROR;
293         }
294     }
295 
296     if (actuateHardware) {
297         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
298                  enabled);
299         err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
300         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
301                  strerror(-err));
302 
303         if (err != NO_ERROR && enabled) {
304             // Failure when enabling the sensor. Clean up on failure.
305             info.removeBatchParamsForIdent(ident);
306         }
307     }
308 
309     return err;
310 }
311 
batch(void * ident,int handle,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)312 status_t SensorDevice::batch(
313         void* ident,
314         int handle,
315         int flags,
316         int64_t samplingPeriodNs,
317         int64_t maxBatchReportLatencyNs) {
318     if (mSensors == nullptr) return NO_INIT;
319 
320     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
321         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
322     }
323     if (maxBatchReportLatencyNs < 0) {
324         maxBatchReportLatencyNs = 0;
325     }
326 
327     ALOGD_IF(DEBUG_CONNECTIONS,
328              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
329              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(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,
347              "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
348              " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
349              prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
350              prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
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) {
355         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
356                  info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
357         err = StatusFromResult(
358                 checkReturn(mSensors->batch(
359                     handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
360         if (err != NO_ERROR) {
361             ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
362                   mSensors.get(), handle, info.bestBatchParams.mTSample,
363                   info.bestBatchParams.mTBatch, strerror(-err));
364             info.removeBatchParamsForIdent(ident);
365         }
366     }
367     return err;
368 }
369 
setDelay(void * ident,int handle,int64_t samplingPeriodNs)370 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
371     return batch(ident, handle, 0, samplingPeriodNs, 0);
372 }
373 
getHalDeviceVersion() const374 int SensorDevice::getHalDeviceVersion() const {
375     if (mSensors == nullptr) return -1;
376     return SENSORS_DEVICE_API_VERSION_1_4;
377 }
378 
flush(void * ident,int handle)379 status_t SensorDevice::flush(void* ident, int handle) {
380     if (mSensors == nullptr) return NO_INIT;
381     if (isClientDisabled(ident)) return INVALID_OPERATION;
382     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
383     return StatusFromResult(checkReturn(mSensors->flush(handle)));
384 }
385 
isClientDisabled(void * ident)386 bool SensorDevice::isClientDisabled(void* ident) {
387     Mutex::Autolock _l(mLock);
388     return isClientDisabledLocked(ident);
389 }
390 
isClientDisabledLocked(void * ident)391 bool SensorDevice::isClientDisabledLocked(void* ident) {
392     return mDisabledClients.indexOf(ident) >= 0;
393 }
394 
enableAllSensors()395 void SensorDevice::enableAllSensors() {
396     if (mSensors == nullptr) return;
397     Mutex::Autolock _l(mLock);
398     mDisabledClients.clear();
399     ALOGI("cleared mDisabledClients");
400     for (size_t i = 0; i< mActivationCount.size(); ++i) {
401         Info& info = mActivationCount.editValueAt(i);
402         if (info.batchParams.isEmpty()) continue;
403         info.selectBatchParams();
404         const int sensor_handle = mActivationCount.keyAt(i);
405         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
406                    sensor_handle);
407         status_t err = StatusFromResult(
408                 checkReturn(mSensors->batch(
409                     sensor_handle,
410                     info.bestBatchParams.mTSample,
411                     info.bestBatchParams.mTBatch)));
412         ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
413 
414         if (err == NO_ERROR) {
415             err = StatusFromResult(
416                     checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
417             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
418         }
419     }
420 }
421 
disableAllSensors()422 void SensorDevice::disableAllSensors() {
423     if (mSensors == nullptr) return;
424     Mutex::Autolock _l(mLock);
425     for (size_t i = 0; i< mActivationCount.size(); ++i) {
426         const Info& info = mActivationCount.valueAt(i);
427         // Check if this sensor has been activated previously and disable it.
428         if (info.batchParams.size() > 0) {
429            const int sensor_handle = mActivationCount.keyAt(i);
430            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
431                    sensor_handle);
432            checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
433 
434            // Add all the connections that were registered for this sensor to the disabled
435            // clients list.
436            for (size_t j = 0; j < info.batchParams.size(); ++j) {
437                mDisabledClients.add(info.batchParams.keyAt(j));
438                ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
439            }
440         }
441     }
442 }
443 
injectSensorData(const sensors_event_t * injected_sensor_event)444 status_t SensorDevice::injectSensorData(
445         const sensors_event_t *injected_sensor_event) {
446     if (mSensors == nullptr) return NO_INIT;
447     ALOGD_IF(DEBUG_CONNECTIONS,
448             "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
449             injected_sensor_event->sensor,
450             injected_sensor_event->timestamp, injected_sensor_event->data[0],
451             injected_sensor_event->data[1], injected_sensor_event->data[2],
452             injected_sensor_event->data[3], injected_sensor_event->data[4],
453             injected_sensor_event->data[5]);
454 
455     Event ev;
456     convertFromSensorEvent(*injected_sensor_event, &ev);
457 
458     return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
459 }
460 
setMode(uint32_t mode)461 status_t SensorDevice::setMode(uint32_t mode) {
462     if (mSensors == nullptr) return NO_INIT;
463     return StatusFromResult(
464             checkReturn(mSensors->setOperationMode(
465                     static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
466 }
467 
registerDirectChannel(const sensors_direct_mem_t * memory)468 int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
469     if (mSensors == nullptr) return NO_INIT;
470     Mutex::Autolock _l(mLock);
471 
472     SharedMemType type;
473     switch (memory->type) {
474         case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
475             type = SharedMemType::ASHMEM;
476             break;
477         case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
478             type = SharedMemType::GRALLOC;
479             break;
480         default:
481             return BAD_VALUE;
482     }
483 
484     SharedMemFormat format;
485     if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
486         return BAD_VALUE;
487     }
488     format = SharedMemFormat::SENSORS_EVENT;
489 
490     SharedMemInfo mem = {
491         .type = type,
492         .format = format,
493         .size = static_cast<uint32_t>(memory->size),
494         .memoryHandle = memory->handle,
495     };
496 
497     int32_t ret;
498     checkReturn(mSensors->registerDirectChannel(mem,
499             [&ret](auto result, auto channelHandle) {
500                 if (result == Result::OK) {
501                     ret = channelHandle;
502                 } else {
503                     ret = StatusFromResult(result);
504                 }
505             }));
506     return ret;
507 }
508 
unregisterDirectChannel(int32_t channelHandle)509 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
510     if (mSensors == nullptr) return;
511     Mutex::Autolock _l(mLock);
512     checkReturn(mSensors->unregisterDirectChannel(channelHandle));
513 }
514 
configureDirectChannel(int32_t sensorHandle,int32_t channelHandle,const struct sensors_direct_cfg_t * config)515 int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
516         int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
517     if (mSensors == nullptr) return NO_INIT;
518     Mutex::Autolock _l(mLock);
519 
520     RateLevel rate;
521     switch(config->rate_level) {
522         case SENSOR_DIRECT_RATE_STOP:
523             rate = RateLevel::STOP;
524             break;
525         case SENSOR_DIRECT_RATE_NORMAL:
526             rate = RateLevel::NORMAL;
527             break;
528         case SENSOR_DIRECT_RATE_FAST:
529             rate = RateLevel::FAST;
530             break;
531         case SENSOR_DIRECT_RATE_VERY_FAST:
532             rate = RateLevel::VERY_FAST;
533             break;
534         default:
535             return BAD_VALUE;
536     }
537 
538     int32_t ret;
539     checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
540             [&ret, rate] (auto result, auto token) {
541                 if (rate == RateLevel::STOP) {
542                     ret = StatusFromResult(result);
543                 } else {
544                     if (result == Result::OK) {
545                         ret = token;
546                     } else {
547                         ret = StatusFromResult(result);
548                     }
549                 }
550             }));
551 
552     return ret;
553 }
554 
555 // ---------------------------------------------------------------------------
556 
numActiveClients()557 int SensorDevice::Info::numActiveClients() {
558     SensorDevice& device(SensorDevice::getInstance());
559     int num = 0;
560     for (size_t i = 0; i < batchParams.size(); ++i) {
561         if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
562             ++num;
563         }
564     }
565     return num;
566 }
567 
setBatchParamsForIdent(void * ident,int,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)568 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
569                                                     int64_t samplingPeriodNs,
570                                                     int64_t maxBatchReportLatencyNs) {
571     ssize_t index = batchParams.indexOfKey(ident);
572     if (index < 0) {
573         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
574               " timeout=%" PRId64 ") failed (%s)",
575               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
576         return BAD_INDEX;
577     }
578     BatchParams& params = batchParams.editValueAt(index);
579     params.mTSample = samplingPeriodNs;
580     params.mTBatch = maxBatchReportLatencyNs;
581     return NO_ERROR;
582 }
583 
selectBatchParams()584 void SensorDevice::Info::selectBatchParams() {
585     BatchParams bestParams; // default to max Tsample and max Tbatch
586     SensorDevice& device(SensorDevice::getInstance());
587 
588     for (size_t i = 0; i < batchParams.size(); ++i) {
589         if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
590             continue;
591         }
592         bestParams.merge(batchParams[i]);
593     }
594     // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
595     if (bestParams.mTBatch <= bestParams.mTSample) {
596         bestParams.mTBatch = 0;
597     }
598     bestBatchParams = bestParams;
599 }
600 
removeBatchParamsForIdent(void * ident)601 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
602     ssize_t idx = batchParams.removeItem(ident);
603     if (idx >= 0) {
604         selectBatchParams();
605     }
606     return idx;
607 }
608 
notifyConnectionDestroyed(void * ident)609 void SensorDevice::notifyConnectionDestroyed(void* ident) {
610     Mutex::Autolock _l(mLock);
611     mDisabledClients.remove(ident);
612 }
613 
isDirectReportSupported() const614 bool SensorDevice::isDirectReportSupported() const {
615     return mIsDirectReportSupported;
616 }
617 
convertToSensorEvent(const Event & src,sensors_event_t * dst)618 void SensorDevice::convertToSensorEvent(
619         const Event &src, sensors_event_t *dst) {
620     ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
621             src, dst);
622 
623     if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
624         const DynamicSensorInfo &dyn = src.u.dynamic;
625 
626         dst->dynamic_sensor_meta.connected = dyn.connected;
627         dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
628         if (dyn.connected) {
629             auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
630             CHECK(it != mConnectedDynamicSensors.end());
631 
632             dst->dynamic_sensor_meta.sensor = it->second;
633 
634             memcpy(dst->dynamic_sensor_meta.uuid,
635                    dyn.uuid.data(),
636                    sizeof(dst->dynamic_sensor_meta.uuid));
637         }
638     }
639 }
640 
convertToSensorEvents(const hidl_vec<Event> & src,const hidl_vec<SensorInfo> & dynamicSensorsAdded,sensors_event_t * dst)641 void SensorDevice::convertToSensorEvents(
642         const hidl_vec<Event> &src,
643         const hidl_vec<SensorInfo> &dynamicSensorsAdded,
644         sensors_event_t *dst) {
645     // Allocate a sensor_t structure for each dynamic sensor added and insert
646     // it into the dictionary of connected dynamic sensors keyed by handle.
647     for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
648         const SensorInfo &info = dynamicSensorsAdded[i];
649 
650         auto it = mConnectedDynamicSensors.find(info.sensorHandle);
651         CHECK(it == mConnectedDynamicSensors.end());
652 
653         sensor_t *sensor = new sensor_t;
654         convertToSensor(info, sensor);
655 
656         mConnectedDynamicSensors.insert(
657                 std::make_pair(sensor->handle, sensor));
658     }
659 
660     for (size_t i = 0; i < src.size(); ++i) {
661         convertToSensorEvent(src[i], &dst[i]);
662     }
663 }
664 
handleHidlDeath(const std::string & detail)665 void SensorDevice::handleHidlDeath(const std::string & detail) {
666     // restart is the only option at present.
667     LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
668 }
669 
670 // ---------------------------------------------------------------------------
671 }; // namespace android
672