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 
     17 #include <stdint.h>
     18 #include <math.h>
     19 #include <sys/types.h>
     20 
     21 #include <utils/Atomic.h>
     22 #include <utils/Errors.h>
     23 #include <utils/Singleton.h>
     24 
     25 #include <binder/BinderService.h>
     26 #include <binder/Parcel.h>
     27 #include <binder/IServiceManager.h>
     28 
     29 #include <hardware/sensors.h>
     30 
     31 #include "SensorDevice.h"
     32 #include "SensorService.h"
     33 
     34 namespace android {
     35 // ---------------------------------------------------------------------------
     36 
     37 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
     38 
     39 SensorDevice::SensorDevice()
     40     :  mSensorDevice(0),
     41        mSensorModule(0)
     42 {
     43     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
     44             (hw_module_t const**)&mSensorModule);
     45 
     46     ALOGE_IF(err, "couldn't load %s module (%s)",
     47             SENSORS_HARDWARE_MODULE_ID, strerror(-err));
     48 
     49     if (mSensorModule) {
     50         err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
     51 
     52         ALOGE_IF(err, "couldn't open device for module %s (%s)",
     53                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
     54 
     55         if (mSensorDevice) {
     56             sensor_t const* list;
     57             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
     58             mActivationCount.setCapacity(count);
     59             Info model;
     60             for (size_t i=0 ; i<size_t(count) ; i++) {
     61                 mActivationCount.add(list[i].handle, model);
     62                 mSensorDevice->activate(
     63                         reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
     64                         list[i].handle, 0);
     65             }
     66         }
     67     }
     68 }
     69 
     70 void SensorDevice::dump(String8& result)
     71 {
     72     if (!mSensorModule) return;
     73     sensor_t const* list;
     74     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
     75 
     76     result.appendFormat("%d h/w sensors:\n", int(count));
     77 
     78     Mutex::Autolock _l(mLock);
     79     for (size_t i=0 ; i<size_t(count) ; i++) {
     80         const Info& info = mActivationCount.valueFor(list[i].handle);
     81         result.appendFormat("handle=0x%08x, active-count=%d, batch_period(ms)={ ", list[i].handle,
     82                             info.batchParams.size());
     83         for (size_t j = 0; j < info.batchParams.size(); j++) {
     84             BatchParams params = info.batchParams.valueAt(j);
     85             result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
     86                                 j < info.batchParams.size() - 1 ? ", " : "");
     87         }
     88         result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
     89 
     90         result.appendFormat("handle=0x%08x, active-count=%d, batch_timeout(ms)={ ", list[i].handle,
     91                             info.batchParams.size());
     92         for (size_t j = 0; j < info.batchParams.size(); j++) {
     93             BatchParams params = info.batchParams.valueAt(j);
     94             result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
     95                                 j < info.batchParams.size() - 1 ? ", " : "");
     96         }
     97         result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
     98     }
     99 }
    100 
    101 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
    102     if (!mSensorModule) return NO_INIT;
    103     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
    104     return count;
    105 }
    106 
    107 status_t SensorDevice::initCheck() const {
    108     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
    109 }
    110 
    111 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    112     if (!mSensorDevice) return NO_INIT;
    113     ssize_t c;
    114     do {
    115         c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
    116                                 buffer, count);
    117     } while (c == -EINTR);
    118     return c;
    119 }
    120 
    121 void SensorDevice::autoDisable(void *ident, int handle) {
    122     Info& info( mActivationCount.editValueFor(handle) );
    123     Mutex::Autolock _l(mLock);
    124     info.removeBatchParamsForIdent(ident);
    125 }
    126 
    127 status_t SensorDevice::activate(void* ident, int handle, int enabled)
    128 {
    129     if (!mSensorDevice) return NO_INIT;
    130     status_t err(NO_ERROR);
    131     bool actuateHardware = false;
    132 
    133     Mutex::Autolock _l(mLock);
    134     Info& info( mActivationCount.editValueFor(handle) );
    135 
    136     ALOGD_IF(DEBUG_CONNECTIONS,
    137              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
    138              ident, handle, enabled, info.batchParams.size());
    139 
    140     if (enabled) {
    141         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
    142 
    143         if (info.batchParams.indexOfKey(ident) >= 0) {
    144           if (info.batchParams.size() == 1) {
    145               // This is the first connection, we need to activate the underlying h/w sensor.
    146               actuateHardware = true;
    147           }
    148         } else {
    149             // Log error. Every activate call should be preceded by a batch() call.
    150             ALOGE("\t >>>ERROR: activate called without batch");
    151         }
    152     } else {
    153         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
    154 
    155         if (info.removeBatchParamsForIdent(ident) >= 0) {
    156             if (info.batchParams.size() == 0) {
    157                 // This is the last connection, we need to de-activate the underlying h/w sensor.
    158                 actuateHardware = true;
    159             } else {
    160                 const int halVersion = getHalDeviceVersion();
    161                 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
    162                     // Call batch for this sensor with the previously calculated best effort
    163                     // batch_rate and timeout. One of the apps has unregistered for sensor
    164                     // events, and the best effort batch parameters might have changed.
    165                     ALOGD_IF(DEBUG_CONNECTIONS,
    166                              "\t>>> actuating h/w batch %d %d %lld %lld ", handle,
    167                              info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    168                              info.bestBatchParams.batchTimeout);
    169                     mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
    170                                          info.bestBatchParams.batchDelay,
    171                                          info.bestBatchParams.batchTimeout);
    172                 }
    173             }
    174         } else {
    175             // sensor wasn't enabled for this ident
    176         }
    177     }
    178 
    179     if (actuateHardware) {
    180         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
    181         err = mSensorDevice->activate(
    182                 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
    183         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
    184                  strerror(-err));
    185 
    186         if (err != NO_ERROR && enabled) {
    187             // Failure when enabling the sensor. Clean up on failure.
    188             info.removeBatchParamsForIdent(ident);
    189         }
    190     }
    191 
    192     // On older devices which do not support batch, call setDelay().
    193     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
    194         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle,
    195                  info.bestBatchParams.batchDelay);
    196         mSensorDevice->setDelay(
    197                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    198                 handle, info.bestBatchParams.batchDelay);
    199     }
    200     return err;
    201 }
    202 
    203 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
    204                              int64_t maxBatchReportLatencyNs) {
    205     if (!mSensorDevice) return NO_INIT;
    206 
    207     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
    208         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
    209     }
    210 
    211     const int halVersion = getHalDeviceVersion();
    212     if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
    213         if (flags & SENSORS_BATCH_DRY_RUN) {
    214             return mSensorDevice->batch(mSensorDevice, handle, flags, samplingPeriodNs,
    215                                         maxBatchReportLatencyNs);
    216         } else {
    217             // Call h/w with dry run to see if the given parameters are feasible or not. Return if
    218             // there is an error.
    219             status_t errDryRun(NO_ERROR);
    220             errDryRun = mSensorDevice->batch(mSensorDevice, handle, flags | SENSORS_BATCH_DRY_RUN,
    221                                              samplingPeriodNs, maxBatchReportLatencyNs);
    222             if (errDryRun != NO_ERROR) {
    223                 ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch dry run error %s",
    224                          strerror(-errDryRun));
    225                 return errDryRun;
    226             }
    227         }
    228     } else if (maxBatchReportLatencyNs != 0) {
    229         // Batch is not supported on older devices.
    230         return INVALID_OPERATION;
    231     }
    232 
    233     ALOGD_IF(DEBUG_CONNECTIONS,
    234              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld",
    235              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
    236 
    237     Mutex::Autolock _l(mLock);
    238     Info& info(mActivationCount.editValueFor(handle));
    239 
    240     if (info.batchParams.indexOfKey(ident) < 0) {
    241         BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
    242         info.batchParams.add(ident, params);
    243     } else {
    244         // A batch has already been called with this ident. Update the batch parameters.
    245         info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
    246     }
    247 
    248     BatchParams prevBestBatchParams = info.bestBatchParams;
    249     // Find the minimum of all timeouts and batch_rates for this sensor.
    250     info.selectBatchParams();
    251 
    252     ALOGD_IF(DEBUG_CONNECTIONS,
    253              "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld",
    254              prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
    255              prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
    256 
    257     status_t err(NO_ERROR);
    258     // If the min period or min timeout has changed since the last batch call, call batch.
    259     if (prevBestBatchParams != info.bestBatchParams) {
    260         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
    261             ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle,
    262                      info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    263                      info.bestBatchParams.batchTimeout);
    264             err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
    265                                        info.bestBatchParams.batchDelay,
    266                                        info.bestBatchParams.batchTimeout);
    267         } else {
    268             // For older devices which do not support batch, call setDelay() after activate() is
    269             // called. Some older devices may not support calling setDelay before activate(), so
    270             // call setDelay in SensorDevice::activate() method.
    271         }
    272         if (err != NO_ERROR) {
    273             ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle,
    274                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    275                   info.bestBatchParams.batchTimeout, strerror(-err));
    276             info.removeBatchParamsForIdent(ident);
    277         }
    278     }
    279     return err;
    280 }
    281 
    282 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
    283 {
    284     if (!mSensorDevice) return NO_INIT;
    285     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
    286         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
    287     }
    288     Mutex::Autolock _l(mLock);
    289     Info& info( mActivationCount.editValueFor(handle) );
    290     // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
    291     // Calling setDelay() in batch mode is an invalid operation.
    292     if (info.bestBatchParams.batchTimeout != 0) {
    293       return INVALID_OPERATION;
    294     }
    295     ssize_t index = info.batchParams.indexOfKey(ident);
    296     if (index < 0) {
    297         return BAD_INDEX;
    298     }
    299     BatchParams& params = info.batchParams.editValueAt(index);
    300     params.batchDelay = samplingPeriodNs;
    301     info.selectBatchParams();
    302     return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    303                                    handle, info.bestBatchParams.batchDelay);
    304 }
    305 
    306 int SensorDevice::getHalDeviceVersion() const {
    307     if (!mSensorDevice) return -1;
    308 
    309     return mSensorDevice->common.version;
    310 }
    311 
    312 status_t SensorDevice::flush(void* ident, int handle) {
    313     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
    314         return INVALID_OPERATION;
    315     }
    316     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
    317     return mSensorDevice->flush(mSensorDevice, handle);
    318 }
    319 
    320 // ---------------------------------------------------------------------------
    321 
    322 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
    323                                                     int64_t samplingPeriodNs,
    324                                                     int64_t maxBatchReportLatencyNs) {
    325     ssize_t index = batchParams.indexOfKey(ident);
    326     if (index < 0) {
    327         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
    328               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
    329         return BAD_INDEX;
    330     }
    331     BatchParams& params = batchParams.editValueAt(index);
    332     params.flags = flags;
    333     params.batchDelay = samplingPeriodNs;
    334     params.batchTimeout = maxBatchReportLatencyNs;
    335     return NO_ERROR;
    336 }
    337 
    338 void SensorDevice::Info::selectBatchParams() {
    339     BatchParams bestParams(-1, -1, -1);
    340 
    341     if (batchParams.size() > 0) {
    342         BatchParams params = batchParams.valueAt(0);
    343         bestParams = params;
    344     }
    345 
    346     for (size_t i = 1; i < batchParams.size(); ++i) {
    347         BatchParams params = batchParams.valueAt(i);
    348         if (params.batchDelay < bestParams.batchDelay) {
    349             bestParams.batchDelay = params.batchDelay;
    350         }
    351         if (params.batchTimeout < bestParams.batchTimeout) {
    352             bestParams.batchTimeout = params.batchTimeout;
    353         }
    354     }
    355     bestBatchParams = bestParams;
    356 }
    357 
    358 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
    359     ssize_t idx = batchParams.removeItem(ident);
    360     if (idx >= 0) {
    361         selectBatchParams();
    362     }
    363     return idx;
    364 }
    365 
    366 // ---------------------------------------------------------------------------
    367 }; // namespace android
    368 
    369