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 <cutils/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 namespace android::hardware::sensors::V1_0;
30 using namespace android::hardware::sensors::V1_0::implementation;
31 using android::hardware::hidl_vec;
32 using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;
33 
34 namespace android {
35 // ---------------------------------------------------------------------------
36 
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)37 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
38 
39 static 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;
51     }
52 }
53 
SensorDevice()54 SensorDevice::SensorDevice()
55         : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
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 will wait for HAL service to start if HAL is declared in device manifest.
91     size_t retry = 10;
92 
93     while (retry-- > 0) {
94         mSensors = ISensors::getService();
95         if (mSensors == nullptr) {
96             // no sensor hidl service found
97             break;
98         }
99 
100         mRestartWaiter->reset();
101         // Poke ISensor service. If it has lingering connection from previous generation of
102         // system server, it will kill itself. There is no intention to handle the poll result,
103         // which will be done since the size is 0.
104         if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
105             // ok to continue
106             break;
107         }
108 
109         // hidl service is restarting, pointer is invalid.
110         mSensors = nullptr;
111         ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry);
112         mRestartWaiter->wait();
113     }
114     return (mSensors != nullptr);
115 }
116 
handleDynamicSensorConnection(int handle,bool connected)117 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
118     // not need to check mSensors because this is is only called after successful poll()
119     if (connected) {
120         Info model;
121         mActivationCount.add(handle, model);
122         checkReturn(mSensors->activate(handle, 0 /* enabled */));
123     } else {
124         mActivationCount.removeItem(handle);
125     }
126 }
127 
dump() const128 std::string SensorDevice::dump() const {
129     if (mSensors == nullptr) return "HAL not initialized\n";
130 
131     String8 result;
132     result.appendFormat("Total %zu h/w sensors, %zu running:\n",
133                         mSensorList.size(), mActivationCount.size());
134 
135     Mutex::Autolock _l(mLock);
136     for (const auto & s : mSensorList) {
137         int32_t handle = s.handle;
138         const Info& info = mActivationCount.valueFor(handle);
139         if (info.batchParams.isEmpty()) continue;
140 
141         result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
142 
143         result.append("sampling_period(ms) = {");
144         for (size_t j = 0; j < info.batchParams.size(); j++) {
145             const BatchParams& params = info.batchParams[j];
146             result.appendFormat("%.1f%s", params.mTSample / 1e6f,
147                 j < info.batchParams.size() - 1 ? ", " : "");
148         }
149         result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
150 
151         result.append("batching_period(ms) = {");
152         for (size_t j = 0; j < info.batchParams.size(); j++) {
153             const BatchParams& params = info.batchParams[j];
154             result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
155                     j < info.batchParams.size() - 1 ? ", " : "");
156         }
157         result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
158     }
159 
160     return result.string();
161 }
162 
getSensorList(sensor_t const ** list)163 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
164     *list = &mSensorList[0];
165 
166     return mSensorList.size();
167 }
168 
initCheck() const169 status_t SensorDevice::initCheck() const {
170     return mSensors != nullptr ? NO_ERROR : NO_INIT;
171 }
172 
poll(sensors_event_t * buffer,size_t count)173 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
174     if (mSensors == nullptr) return NO_INIT;
175 
176     ssize_t err;
177     int numHidlTransportErrors = 0;
178     bool hidlTransportError = false;
179 
180     do {
181         auto ret = mSensors->poll(
182                 count,
183                 [&](auto result,
184                     const auto &events,
185                     const auto &dynamicSensorsAdded) {
186                     if (result == Result::OK) {
187                         convertToSensorEvents(events, dynamicSensorsAdded, buffer);
188                         err = (ssize_t)events.size();
189                     } else {
190                         err = StatusFromResult(result);
191                     }
192                 });
193 
194         if (ret.isOk())  {
195             hidlTransportError = false;
196         } else {
197             hidlTransportError = true;
198             numHidlTransportErrors++;
199             if (numHidlTransportErrors > 50) {
200                 // Log error and bail
201                 ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
202                 handleHidlDeath(ret.description());
203             } else {
204                 std::this_thread::sleep_for(std::chrono::milliseconds(10));
205             }
206         }
207     } while (hidlTransportError);
208 
209     if(numHidlTransportErrors > 0) {
210         ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
211         HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors);
212         mHidlTransportErrors.add(errLog);
213         mTotalHidlTransportErrors++;
214     }
215 
216     return err;
217 }
218 
autoDisable(void * ident,int handle)219 void SensorDevice::autoDisable(void *ident, int handle) {
220     Mutex::Autolock _l(mLock);
221     ssize_t activationIndex = mActivationCount.indexOfKey(handle);
222     if (activationIndex < 0) {
223         ALOGW("Handle %d cannot be found in activation record", handle);
224         return;
225     }
226     Info& info(mActivationCount.editValueAt(activationIndex));
227     info.removeBatchParamsForIdent(ident);
228 }
229 
activate(void * ident,int handle,int enabled)230 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
231     if (mSensors == nullptr) return NO_INIT;
232 
233     status_t err(NO_ERROR);
234     bool actuateHardware = false;
235 
236     Mutex::Autolock _l(mLock);
237     ssize_t activationIndex = mActivationCount.indexOfKey(handle);
238     if (activationIndex < 0) {
239         ALOGW("Handle %d cannot be found in activation record", handle);
240         return BAD_VALUE;
241     }
242     Info& info(mActivationCount.editValueAt(activationIndex));
243 
244     ALOGD_IF(DEBUG_CONNECTIONS,
245              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
246              ident, handle, enabled, info.batchParams.size());
247 
248     if (enabled) {
249         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
250 
251         if (isClientDisabledLocked(ident)) {
252             ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
253                     ident, handle);
254             return INVALID_OPERATION;
255         }
256 
257         if (info.batchParams.indexOfKey(ident) >= 0) {
258           if (info.numActiveClients() == 1) {
259               // This is the first connection, we need to activate the underlying h/w sensor.
260               actuateHardware = true;
261           }
262         } else {
263             // Log error. Every activate call should be preceded by a batch() call.
264             ALOGE("\t >>>ERROR: activate called without batch");
265         }
266     } else {
267         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
268 
269         // If a connected dynamic sensor is deactivated, remove it from the
270         // dictionary.
271         auto it = mConnectedDynamicSensors.find(handle);
272         if (it != mConnectedDynamicSensors.end()) {
273             delete it->second;
274             mConnectedDynamicSensors.erase(it);
275         }
276 
277         if (info.removeBatchParamsForIdent(ident) >= 0) {
278             if (info.numActiveClients() == 0) {
279                 // This is the last connection, we need to de-activate the underlying h/w sensor.
280                 actuateHardware = true;
281             } else {
282                 // Call batch for this sensor with the previously calculated best effort
283                 // batch_rate and timeout. One of the apps has unregistered for sensor
284                 // events, and the best effort batch parameters might have changed.
285                 ALOGD_IF(DEBUG_CONNECTIONS,
286                          "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
287                          info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
288                 checkReturn(mSensors->batch(
289                         handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
290             }
291         } else {
292             // sensor wasn't enabled for this ident
293         }
294 
295         if (isClientDisabledLocked(ident)) {
296             return NO_ERROR;
297         }
298     }
299 
300     if (actuateHardware) {
301         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
302                  enabled);
303         err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
304         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
305                  strerror(-err));
306 
307         if (err != NO_ERROR && enabled) {
308             // Failure when enabling the sensor. Clean up on failure.
309             info.removeBatchParamsForIdent(ident);
310         }
311     }
312 
313     return err;
314 }
315 
batch(void * ident,int handle,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)316 status_t SensorDevice::batch(
317         void* ident,
318         int handle,
319         int flags,
320         int64_t samplingPeriodNs,
321         int64_t maxBatchReportLatencyNs) {
322     if (mSensors == nullptr) return NO_INIT;
323 
324     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
325         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
326     }
327     if (maxBatchReportLatencyNs < 0) {
328         maxBatchReportLatencyNs = 0;
329     }
330 
331     ALOGD_IF(DEBUG_CONNECTIONS,
332              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
333              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
334 
335     Mutex::Autolock _l(mLock);
336     ssize_t activationIndex = mActivationCount.indexOfKey(handle);
337     if (activationIndex < 0) {
338         ALOGW("Handle %d cannot be found in activation record", handle);
339         return BAD_VALUE;
340     }
341     Info& info(mActivationCount.editValueAt(activationIndex));
342 
343     if (info.batchParams.indexOfKey(ident) < 0) {
344         BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
345         info.batchParams.add(ident, params);
346     } else {
347         // A batch has already been called with this ident. Update the batch parameters.
348         info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
349     }
350 
351     BatchParams prevBestBatchParams = info.bestBatchParams;
352     // Find the minimum of all timeouts and batch_rates for this sensor.
353     info.selectBatchParams();
354 
355     ALOGD_IF(DEBUG_CONNECTIONS,
356              "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
357              " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
358              prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
359              prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
360 
361     status_t err(NO_ERROR);
362     // If the min period or min timeout has changed since the last batch call, call batch.
363     if (prevBestBatchParams != info.bestBatchParams) {
364         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
365                  info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
366         err = StatusFromResult(
367                 checkReturn(mSensors->batch(
368                     handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
369         if (err != NO_ERROR) {
370             ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
371                   mSensors.get(), handle, info.bestBatchParams.mTSample,
372                   info.bestBatchParams.mTBatch, strerror(-err));
373             info.removeBatchParamsForIdent(ident);
374         }
375     }
376     return err;
377 }
378 
setDelay(void * ident,int handle,int64_t samplingPeriodNs)379 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
380     return batch(ident, handle, 0, samplingPeriodNs, 0);
381 }
382 
getHalDeviceVersion() const383 int SensorDevice::getHalDeviceVersion() const {
384     if (mSensors == nullptr) return -1;
385     return SENSORS_DEVICE_API_VERSION_1_4;
386 }
387 
flush(void * ident,int handle)388 status_t SensorDevice::flush(void* ident, int handle) {
389     if (mSensors == nullptr) return NO_INIT;
390     if (isClientDisabled(ident)) return INVALID_OPERATION;
391     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
392     return StatusFromResult(checkReturn(mSensors->flush(handle)));
393 }
394 
isClientDisabled(void * ident)395 bool SensorDevice::isClientDisabled(void* ident) {
396     Mutex::Autolock _l(mLock);
397     return isClientDisabledLocked(ident);
398 }
399 
isClientDisabledLocked(void * ident)400 bool SensorDevice::isClientDisabledLocked(void* ident) {
401     return mDisabledClients.indexOf(ident) >= 0;
402 }
403 
enableAllSensors()404 void SensorDevice::enableAllSensors() {
405     if (mSensors == nullptr) return;
406     Mutex::Autolock _l(mLock);
407     mDisabledClients.clear();
408     ALOGI("cleared mDisabledClients");
409     for (size_t i = 0; i< mActivationCount.size(); ++i) {
410         Info& info = mActivationCount.editValueAt(i);
411         if (info.batchParams.isEmpty()) continue;
412         info.selectBatchParams();
413         const int sensor_handle = mActivationCount.keyAt(i);
414         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
415                    sensor_handle);
416         status_t err = StatusFromResult(
417                 checkReturn(mSensors->batch(
418                     sensor_handle,
419                     info.bestBatchParams.mTSample,
420                     info.bestBatchParams.mTBatch)));
421         ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
422 
423         if (err == NO_ERROR) {
424             err = StatusFromResult(
425                     checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
426             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
427         }
428     }
429 }
430 
disableAllSensors()431 void SensorDevice::disableAllSensors() {
432     if (mSensors == nullptr) return;
433     Mutex::Autolock _l(mLock);
434     for (size_t i = 0; i< mActivationCount.size(); ++i) {
435         const Info& info = mActivationCount.valueAt(i);
436         // Check if this sensor has been activated previously and disable it.
437         if (info.batchParams.size() > 0) {
438            const int sensor_handle = mActivationCount.keyAt(i);
439            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
440                    sensor_handle);
441            checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
442 
443            // Add all the connections that were registered for this sensor to the disabled
444            // clients list.
445            for (size_t j = 0; j < info.batchParams.size(); ++j) {
446                mDisabledClients.add(info.batchParams.keyAt(j));
447                ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
448            }
449         }
450     }
451 }
452 
injectSensorData(const sensors_event_t * injected_sensor_event)453 status_t SensorDevice::injectSensorData(
454         const sensors_event_t *injected_sensor_event) {
455     if (mSensors == nullptr) return NO_INIT;
456     ALOGD_IF(DEBUG_CONNECTIONS,
457             "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
458             injected_sensor_event->sensor,
459             injected_sensor_event->timestamp, injected_sensor_event->data[0],
460             injected_sensor_event->data[1], injected_sensor_event->data[2],
461             injected_sensor_event->data[3], injected_sensor_event->data[4],
462             injected_sensor_event->data[5]);
463 
464     Event ev;
465     convertFromSensorEvent(*injected_sensor_event, &ev);
466 
467     return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
468 }
469 
setMode(uint32_t mode)470 status_t SensorDevice::setMode(uint32_t mode) {
471     if (mSensors == nullptr) return NO_INIT;
472     return StatusFromResult(
473             checkReturn(mSensors->setOperationMode(
474                     static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
475 }
476 
registerDirectChannel(const sensors_direct_mem_t * memory)477 int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
478     if (mSensors == nullptr) return NO_INIT;
479     Mutex::Autolock _l(mLock);
480 
481     SharedMemType type;
482     switch (memory->type) {
483         case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
484             type = SharedMemType::ASHMEM;
485             break;
486         case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
487             type = SharedMemType::GRALLOC;
488             break;
489         default:
490             return BAD_VALUE;
491     }
492 
493     SharedMemFormat format;
494     if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
495         return BAD_VALUE;
496     }
497     format = SharedMemFormat::SENSORS_EVENT;
498 
499     SharedMemInfo mem = {
500         .type = type,
501         .format = format,
502         .size = static_cast<uint32_t>(memory->size),
503         .memoryHandle = memory->handle,
504     };
505 
506     int32_t ret;
507     checkReturn(mSensors->registerDirectChannel(mem,
508             [&ret](auto result, auto channelHandle) {
509                 if (result == Result::OK) {
510                     ret = channelHandle;
511                 } else {
512                     ret = StatusFromResult(result);
513                 }
514             }));
515     return ret;
516 }
517 
unregisterDirectChannel(int32_t channelHandle)518 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
519     if (mSensors == nullptr) return;
520     Mutex::Autolock _l(mLock);
521     checkReturn(mSensors->unregisterDirectChannel(channelHandle));
522 }
523 
configureDirectChannel(int32_t sensorHandle,int32_t channelHandle,const struct sensors_direct_cfg_t * config)524 int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
525         int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
526     if (mSensors == nullptr) return NO_INIT;
527     Mutex::Autolock _l(mLock);
528 
529     RateLevel rate;
530     switch(config->rate_level) {
531         case SENSOR_DIRECT_RATE_STOP:
532             rate = RateLevel::STOP;
533             break;
534         case SENSOR_DIRECT_RATE_NORMAL:
535             rate = RateLevel::NORMAL;
536             break;
537         case SENSOR_DIRECT_RATE_FAST:
538             rate = RateLevel::FAST;
539             break;
540         case SENSOR_DIRECT_RATE_VERY_FAST:
541             rate = RateLevel::VERY_FAST;
542             break;
543         default:
544             return BAD_VALUE;
545     }
546 
547     int32_t ret;
548     checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
549             [&ret, rate] (auto result, auto token) {
550                 if (rate == RateLevel::STOP) {
551                     ret = StatusFromResult(result);
552                 } else {
553                     if (result == Result::OK) {
554                         ret = token;
555                     } else {
556                         ret = StatusFromResult(result);
557                     }
558                 }
559             }));
560 
561     return ret;
562 }
563 
564 // ---------------------------------------------------------------------------
565 
numActiveClients()566 int SensorDevice::Info::numActiveClients() {
567     SensorDevice& device(SensorDevice::getInstance());
568     int num = 0;
569     for (size_t i = 0; i < batchParams.size(); ++i) {
570         if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
571             ++num;
572         }
573     }
574     return num;
575 }
576 
setBatchParamsForIdent(void * ident,int,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)577 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
578                                                     int64_t samplingPeriodNs,
579                                                     int64_t maxBatchReportLatencyNs) {
580     ssize_t index = batchParams.indexOfKey(ident);
581     if (index < 0) {
582         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
583               " timeout=%" PRId64 ") failed (%s)",
584               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
585         return BAD_INDEX;
586     }
587     BatchParams& params = batchParams.editValueAt(index);
588     params.mTSample = samplingPeriodNs;
589     params.mTBatch = maxBatchReportLatencyNs;
590     return NO_ERROR;
591 }
592 
selectBatchParams()593 void SensorDevice::Info::selectBatchParams() {
594     BatchParams bestParams; // default to max Tsample and max Tbatch
595     SensorDevice& device(SensorDevice::getInstance());
596 
597     for (size_t i = 0; i < batchParams.size(); ++i) {
598         if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
599             continue;
600         }
601         bestParams.merge(batchParams[i]);
602     }
603     // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
604     if (bestParams.mTBatch <= bestParams.mTSample) {
605         bestParams.mTBatch = 0;
606     }
607     bestBatchParams = bestParams;
608 }
609 
removeBatchParamsForIdent(void * ident)610 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
611     ssize_t idx = batchParams.removeItem(ident);
612     if (idx >= 0) {
613         selectBatchParams();
614     }
615     return idx;
616 }
617 
notifyConnectionDestroyed(void * ident)618 void SensorDevice::notifyConnectionDestroyed(void* ident) {
619     Mutex::Autolock _l(mLock);
620     mDisabledClients.remove(ident);
621 }
622 
isDirectReportSupported() const623 bool SensorDevice::isDirectReportSupported() const {
624     return mIsDirectReportSupported;
625 }
626 
convertToSensorEvent(const Event & src,sensors_event_t * dst)627 void SensorDevice::convertToSensorEvent(
628         const Event &src, sensors_event_t *dst) {
629     ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
630             src, dst);
631 
632     if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
633         const DynamicSensorInfo &dyn = src.u.dynamic;
634 
635         dst->dynamic_sensor_meta.connected = dyn.connected;
636         dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
637         if (dyn.connected) {
638             auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
639             CHECK(it != mConnectedDynamicSensors.end());
640 
641             dst->dynamic_sensor_meta.sensor = it->second;
642 
643             memcpy(dst->dynamic_sensor_meta.uuid,
644                    dyn.uuid.data(),
645                    sizeof(dst->dynamic_sensor_meta.uuid));
646         }
647     }
648 }
649 
convertToSensorEvents(const hidl_vec<Event> & src,const hidl_vec<SensorInfo> & dynamicSensorsAdded,sensors_event_t * dst)650 void SensorDevice::convertToSensorEvents(
651         const hidl_vec<Event> &src,
652         const hidl_vec<SensorInfo> &dynamicSensorsAdded,
653         sensors_event_t *dst) {
654     // Allocate a sensor_t structure for each dynamic sensor added and insert
655     // it into the dictionary of connected dynamic sensors keyed by handle.
656     for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
657         const SensorInfo &info = dynamicSensorsAdded[i];
658 
659         auto it = mConnectedDynamicSensors.find(info.sensorHandle);
660         CHECK(it == mConnectedDynamicSensors.end());
661 
662         sensor_t *sensor = new sensor_t;
663         convertToSensor(info, sensor);
664 
665         mConnectedDynamicSensors.insert(
666                 std::make_pair(sensor->handle, sensor));
667     }
668 
669     for (size_t i = 0; i < src.size(); ++i) {
670         convertToSensorEvent(src[i], &dst[i]);
671     }
672 }
673 
handleHidlDeath(const std::string & detail)674 void SensorDevice::handleHidlDeath(const std::string & detail) {
675     // restart is the only option at present.
676     LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
677 }
678 
679 // ---------------------------------------------------------------------------
680 }; // namespace android
681