Home | History | Annotate | Download | only in sensorservice
      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 
     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 
     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 
     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 
    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 
    128 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 
    163 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
    164     *list = &mSensorList[0];
    165 
    166     return mSensorList.size();
    167 }
    168 
    169 status_t SensorDevice::initCheck() const {
    170     return mSensors != nullptr ? NO_ERROR : NO_INIT;
    171 }
    172 
    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 
    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 
    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 
    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 
    379 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
    380     return batch(ident, handle, 0, samplingPeriodNs, 0);
    381 }
    382 
    383 int SensorDevice::getHalDeviceVersion() const {
    384     if (mSensors == nullptr) return -1;
    385     return SENSORS_DEVICE_API_VERSION_1_4;
    386 }
    387 
    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 
    395 bool SensorDevice::isClientDisabled(void* ident) {
    396     Mutex::Autolock _l(mLock);
    397     return isClientDisabledLocked(ident);
    398 }
    399 
    400 bool SensorDevice::isClientDisabledLocked(void* ident) {
    401     return mDisabledClients.indexOf(ident) >= 0;
    402 }
    403 
    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 
    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 
    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 
    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 
    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 
    518 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
    519     if (mSensors == nullptr) return;
    520     Mutex::Autolock _l(mLock);
    521     checkReturn(mSensors->unregisterDirectChannel(channelHandle));
    522 }
    523 
    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 
    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 
    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 
    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 
    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 
    618 void SensorDevice::notifyConnectionDestroyed(void* ident) {
    619     Mutex::Autolock _l(mLock);
    620     mDisabledClients.remove(ident);
    621 }
    622 
    623 bool SensorDevice::isDirectReportSupported() const {
    624     return mIsDirectReportSupported;
    625 }
    626 
    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 
    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 
    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