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 <inttypes.h>
     18 #include <math.h>
     19 #include <stdint.h>
     20 #include <sys/types.h>
     21 
     22 #include <utils/Atomic.h>
     23 #include <utils/Errors.h>
     24 #include <utils/Singleton.h>
     25 
     26 #include <binder/BinderService.h>
     27 #include <binder/Parcel.h>
     28 #include <binder/IServiceManager.h>
     29 
     30 #include <hardware/sensors.h>
     31 
     32 #include "SensorDevice.h"
     33 #include "SensorService.h"
     34 
     35 namespace android {
     36 // ---------------------------------------------------------------------------
     37 
     38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
     39 
     40 SensorDevice::SensorDevice()
     41     :  mSensorDevice(0),
     42        mSensorModule(0) {
     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             if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
     57                 mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
     58                 ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");
     59             }
     60 
     61             sensor_t const* list;
     62             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
     63             mActivationCount.setCapacity(count);
     64             Info model;
     65             for (size_t i=0 ; i<size_t(count) ; i++) {
     66                 mActivationCount.add(list[i].handle, model);
     67                 mSensorDevice->activate(
     68                         reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
     69                         list[i].handle, 0);
     70             }
     71         }
     72     }
     73 }
     74 
     75 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
     76     if (connected) {
     77         Info model;
     78         mActivationCount.add(handle, model);
     79         mSensorDevice->activate(
     80                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0);
     81     } else {
     82         mActivationCount.removeItem(handle);
     83     }
     84 }
     85 
     86 std::string SensorDevice::dump() const {
     87     if (!mSensorModule) return "HAL not initialized\n";
     88 
     89     String8 result;
     90     sensor_t const* list;
     91     int count = mSensorModule->get_sensors_list(mSensorModule, &list);
     92 
     93     result.appendFormat("HAL: %s (%s), version %#010x\n",
     94                         mSensorModule->common.name,
     95                         mSensorModule->common.author,
     96                         getHalDeviceVersion());
     97     result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size());
     98 
     99     Mutex::Autolock _l(mLock);
    100     for (int i = 0 ; i < count ; i++) {
    101         const Info& info = mActivationCount.valueFor(list[i].handle);
    102         if (info.batchParams.isEmpty()) continue;
    103         result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle,
    104                             info.batchParams.size());
    105 
    106         result.append("sampling_period(ms) = {");
    107         for (size_t j = 0; j < info.batchParams.size(); j++) {
    108             const BatchParams& params = info.batchParams.valueAt(j);
    109             result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
    110                                 j < info.batchParams.size() - 1 ? ", " : "");
    111         }
    112         result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
    113 
    114         result.append("batching_period(ms) = {");
    115         for (size_t j = 0; j < info.batchParams.size(); j++) {
    116             BatchParams params = info.batchParams.valueAt(j);
    117             result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
    118                                 j < info.batchParams.size() - 1 ? ", " : "");
    119         }
    120         result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
    121     }
    122     return result.string();
    123 }
    124 
    125 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
    126     if (!mSensorModule) return NO_INIT;
    127     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
    128     return count;
    129 }
    130 
    131 status_t SensorDevice::initCheck() const {
    132     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
    133 }
    134 
    135 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    136     if (!mSensorDevice) return NO_INIT;
    137     ssize_t c;
    138     do {
    139         c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
    140                                 buffer, count);
    141     } while (c == -EINTR);
    142     return c;
    143 }
    144 
    145 void SensorDevice::autoDisable(void *ident, int handle) {
    146     Info& info( mActivationCount.editValueFor(handle) );
    147     Mutex::Autolock _l(mLock);
    148     info.removeBatchParamsForIdent(ident);
    149 }
    150 
    151 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
    152     if (!mSensorDevice) return NO_INIT;
    153     status_t err(NO_ERROR);
    154     bool actuateHardware = false;
    155 
    156     Mutex::Autolock _l(mLock);
    157     Info& info( mActivationCount.editValueFor(handle) );
    158 
    159     ALOGD_IF(DEBUG_CONNECTIONS,
    160              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
    161              ident, handle, enabled, info.batchParams.size());
    162 
    163     if (enabled) {
    164         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
    165 
    166         if (isClientDisabledLocked(ident)) {
    167             return INVALID_OPERATION;
    168         }
    169 
    170         if (info.batchParams.indexOfKey(ident) >= 0) {
    171           if (info.numActiveClients() == 1) {
    172               // This is the first connection, we need to activate the underlying h/w sensor.
    173               actuateHardware = true;
    174           }
    175         } else {
    176             // Log error. Every activate call should be preceded by a batch() call.
    177             ALOGE("\t >>>ERROR: activate called without batch");
    178         }
    179     } else {
    180         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
    181 
    182         if (info.removeBatchParamsForIdent(ident) >= 0) {
    183             if (info.numActiveClients() == 0) {
    184                 // This is the last connection, we need to de-activate the underlying h/w sensor.
    185                 actuateHardware = true;
    186             } else {
    187                 const int halVersion = getHalDeviceVersion();
    188                 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
    189                     // Call batch for this sensor with the previously calculated best effort
    190                     // batch_rate and timeout. One of the apps has unregistered for sensor
    191                     // events, and the best effort batch parameters might have changed.
    192                     ALOGD_IF(DEBUG_CONNECTIONS,
    193                              "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
    194                              info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    195                              info.bestBatchParams.batchTimeout);
    196                     mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
    197                                          info.bestBatchParams.batchDelay,
    198                                          info.bestBatchParams.batchTimeout);
    199                 }
    200             }
    201         } else {
    202             // sensor wasn't enabled for this ident
    203         }
    204 
    205         if (isClientDisabledLocked(ident)) {
    206             return NO_ERROR;
    207         }
    208     }
    209 
    210     if (actuateHardware) {
    211         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
    212                  enabled);
    213         err = mSensorDevice->activate(
    214                 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
    215         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
    216                  strerror(-err));
    217 
    218         if (err != NO_ERROR && enabled) {
    219             // Failure when enabling the sensor. Clean up on failure.
    220             info.removeBatchParamsForIdent(ident);
    221         }
    222     }
    223 
    224     // On older devices which do not support batch, call setDelay().
    225     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
    226         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
    227                  info.bestBatchParams.batchDelay);
    228         mSensorDevice->setDelay(
    229                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    230                 handle, info.bestBatchParams.batchDelay);
    231     }
    232     return err;
    233 }
    234 
    235 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
    236                              int64_t maxBatchReportLatencyNs) {
    237     if (!mSensorDevice) return NO_INIT;
    238 
    239     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
    240         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
    241     }
    242 
    243     const int halVersion = getHalDeviceVersion();
    244     if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) {
    245         // Batch is not supported on older devices return invalid operation.
    246         return INVALID_OPERATION;
    247     }
    248 
    249     ALOGD_IF(DEBUG_CONNECTIONS,
    250              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
    251              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
    252 
    253     Mutex::Autolock _l(mLock);
    254     Info& info(mActivationCount.editValueFor(handle));
    255 
    256     if (info.batchParams.indexOfKey(ident) < 0) {
    257         BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
    258         info.batchParams.add(ident, params);
    259     } else {
    260         // A batch has already been called with this ident. Update the batch parameters.
    261         info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
    262     }
    263 
    264     BatchParams prevBestBatchParams = info.bestBatchParams;
    265     // Find the minimum of all timeouts and batch_rates for this sensor.
    266     info.selectBatchParams();
    267 
    268     ALOGD_IF(DEBUG_CONNECTIONS,
    269              "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
    270              " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
    271              prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
    272              prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
    273 
    274     status_t err(NO_ERROR);
    275     // If the min period or min timeout has changed since the last batch call, call batch.
    276     if (prevBestBatchParams != info.bestBatchParams) {
    277         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
    278             ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
    279                      info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    280                      info.bestBatchParams.batchTimeout);
    281             err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
    282                                        info.bestBatchParams.batchDelay,
    283                                        info.bestBatchParams.batchTimeout);
    284         } else {
    285             // For older devices which do not support batch, call setDelay() after activate() is
    286             // called. Some older devices may not support calling setDelay before activate(), so
    287             // call setDelay in SensorDevice::activate() method.
    288         }
    289         if (err != NO_ERROR) {
    290             ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
    291                   mSensorDevice, handle,
    292                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    293                   info.bestBatchParams.batchTimeout, strerror(-err));
    294             info.removeBatchParamsForIdent(ident);
    295         }
    296     }
    297     return err;
    298 }
    299 
    300 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
    301     if (!mSensorDevice) return NO_INIT;
    302     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
    303         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
    304     }
    305     Mutex::Autolock _l(mLock);
    306     if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
    307     Info& info( mActivationCount.editValueFor(handle) );
    308     // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
    309     // Calling setDelay() in batch mode is an invalid operation.
    310     if (info.bestBatchParams.batchTimeout != 0) {
    311       return INVALID_OPERATION;
    312     }
    313     ssize_t index = info.batchParams.indexOfKey(ident);
    314     if (index < 0) {
    315         return BAD_INDEX;
    316     }
    317     BatchParams& params = info.batchParams.editValueAt(index);
    318     params.batchDelay = samplingPeriodNs;
    319     info.selectBatchParams();
    320     return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    321                                    handle, info.bestBatchParams.batchDelay);
    322 }
    323 
    324 int SensorDevice::getHalDeviceVersion() const {
    325     if (!mSensorDevice) return -1;
    326     return mSensorDevice->common.version;
    327 }
    328 
    329 status_t SensorDevice::flush(void* ident, int handle) {
    330     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
    331         return INVALID_OPERATION;
    332     }
    333     if (isClientDisabled(ident)) return INVALID_OPERATION;
    334     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
    335     return mSensorDevice->flush(mSensorDevice, handle);
    336 }
    337 
    338 bool SensorDevice::isClientDisabled(void* ident) {
    339     Mutex::Autolock _l(mLock);
    340     return isClientDisabledLocked(ident);
    341 }
    342 
    343 bool SensorDevice::isClientDisabledLocked(void* ident) {
    344     return mDisabledClients.indexOf(ident) >= 0;
    345 }
    346 
    347 void SensorDevice::enableAllSensors() {
    348     Mutex::Autolock _l(mLock);
    349     mDisabledClients.clear();
    350     const int halVersion = getHalDeviceVersion();
    351     for (size_t i = 0; i< mActivationCount.size(); ++i) {
    352         Info& info = mActivationCount.editValueAt(i);
    353         if (info.batchParams.isEmpty()) continue;
    354         info.selectBatchParams();
    355         const int sensor_handle = mActivationCount.keyAt(i);
    356         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
    357                    sensor_handle);
    358         status_t err(NO_ERROR);
    359         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
    360             err = mSensorDevice->batch(mSensorDevice, sensor_handle,
    361                  info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
    362                  info.bestBatchParams.batchTimeout);
    363             ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
    364         }
    365 
    366         if (err == NO_ERROR) {
    367             err = mSensorDevice->activate(
    368                     reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    369                     sensor_handle, 1);
    370             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
    371         }
    372 
    373         if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
    374              err = mSensorDevice->setDelay(
    375                     reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
    376                     sensor_handle, info.bestBatchParams.batchDelay);
    377              ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
    378         }
    379     }
    380 }
    381 
    382 void SensorDevice::disableAllSensors() {
    383     Mutex::Autolock _l(mLock);
    384    for (size_t i = 0; i< mActivationCount.size(); ++i) {
    385         const Info& info = mActivationCount.valueAt(i);
    386         // Check if this sensor has been activated previously and disable it.
    387         if (info.batchParams.size() > 0) {
    388            const int sensor_handle = mActivationCount.keyAt(i);
    389            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
    390                    sensor_handle);
    391            mSensorDevice->activate(
    392                    reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
    393                    sensor_handle, 0);
    394            // Add all the connections that were registered for this sensor to the disabled
    395            // clients list.
    396            for (size_t j = 0; j < info.batchParams.size(); ++j) {
    397                mDisabledClients.add(info.batchParams.keyAt(j));
    398            }
    399         }
    400     }
    401 }
    402 
    403 status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) {
    404       ALOGD_IF(DEBUG_CONNECTIONS,
    405               "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
    406                injected_sensor_event->sensor,
    407                injected_sensor_event->timestamp, injected_sensor_event->data[0],
    408                injected_sensor_event->data[1], injected_sensor_event->data[2],
    409                injected_sensor_event->data[3], injected_sensor_event->data[4],
    410                injected_sensor_event->data[5]);
    411       if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
    412           return INVALID_OPERATION;
    413       }
    414       return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
    415 }
    416 
    417 status_t SensorDevice::setMode(uint32_t mode) {
    418      if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
    419           return INVALID_OPERATION;
    420      }
    421      return mSensorModule->set_operation_mode(mode);
    422 }
    423 
    424 // ---------------------------------------------------------------------------
    425 
    426 int SensorDevice::Info::numActiveClients() {
    427     SensorDevice& device(SensorDevice::getInstance());
    428     int num = 0;
    429     for (size_t i = 0; i < batchParams.size(); ++i) {
    430         if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
    431             ++num;
    432         }
    433     }
    434     return num;
    435 }
    436 
    437 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
    438                                                     int64_t samplingPeriodNs,
    439                                                     int64_t maxBatchReportLatencyNs) {
    440     ssize_t index = batchParams.indexOfKey(ident);
    441     if (index < 0) {
    442         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
    443               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
    444         return BAD_INDEX;
    445     }
    446     BatchParams& params = batchParams.editValueAt(index);
    447     params.flags = flags;
    448     params.batchDelay = samplingPeriodNs;
    449     params.batchTimeout = maxBatchReportLatencyNs;
    450     return NO_ERROR;
    451 }
    452 
    453 void SensorDevice::Info::selectBatchParams() {
    454     BatchParams bestParams(0, -1, -1);
    455     SensorDevice& device(SensorDevice::getInstance());
    456 
    457     for (size_t i = 0; i < batchParams.size(); ++i) {
    458         if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
    459         BatchParams params = batchParams.valueAt(i);
    460         if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
    461             bestParams.batchDelay = params.batchDelay;
    462         }
    463         if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
    464             bestParams.batchTimeout = params.batchTimeout;
    465         }
    466     }
    467     bestBatchParams = bestParams;
    468 }
    469 
    470 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
    471     ssize_t idx = batchParams.removeItem(ident);
    472     if (idx >= 0) {
    473         selectBatchParams();
    474     }
    475     return idx;
    476 }
    477 
    478 // ---------------------------------------------------------------------------
    479 }; // namespace android
    480 
    481