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(&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(mSensorDevice, list[i].handle, 0);
     63             }
     64         }
     65     }
     66 }
     67 
     68 void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
     69 {
     70     if (!mSensorModule) return;
     71     sensor_t const* list;
     72     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
     73 
     74     snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count));
     75     result.append(buffer);
     76 
     77     Mutex::Autolock _l(mLock);
     78     for (size_t i=0 ; i<size_t(count) ; i++) {
     79         const Info& info = mActivationCount.valueFor(list[i].handle);
     80         snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ",
     81                 list[i].handle,
     82                 info.rates.size());
     83         result.append(buffer);
     84         for (size_t j=0 ; j<info.rates.size() ; j++) {
     85             snprintf(buffer, SIZE, "%4.1f%s",
     86                     info.rates.valueAt(j) / 1e6f,
     87                     j<info.rates.size()-1 ? ", " : "");
     88             result.append(buffer);
     89         }
     90         snprintf(buffer, SIZE, " }, selected=%4.1f ms\n",  info.delay / 1e6f);
     91         result.append(buffer);
     92     }
     93 }
     94 
     95 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
     96     if (!mSensorModule) return NO_INIT;
     97     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
     98     return count;
     99 }
    100 
    101 status_t SensorDevice::initCheck() const {
    102     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
    103 }
    104 
    105 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    106     if (!mSensorDevice) return NO_INIT;
    107     ssize_t c;
    108     do {
    109         c = mSensorDevice->poll(mSensorDevice, buffer, count);
    110     } while (c == -EINTR);
    111     return c;
    112 }
    113 
    114 void SensorDevice::autoDisable(void *ident, int handle) {
    115     Info& info( mActivationCount.editValueFor(handle) );
    116     Mutex::Autolock _l(mLock);
    117     info.rates.removeItem(ident);
    118 }
    119 
    120 status_t SensorDevice::activate(void* ident, int handle, int enabled)
    121 {
    122     if (!mSensorDevice) return NO_INIT;
    123     status_t err(NO_ERROR);
    124     bool actuateHardware = false;
    125 
    126     Info& info( mActivationCount.editValueFor(handle) );
    127 
    128 
    129     ALOGD_IF(DEBUG_CONNECTIONS,
    130             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
    131             ident, handle, enabled, info.rates.size());
    132 
    133     if (enabled) {
    134         Mutex::Autolock _l(mLock);
    135         ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
    136                 info.rates.indexOfKey(ident));
    137 
    138         if (info.rates.indexOfKey(ident) < 0) {
    139             info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
    140             if (info.rates.size() == 1) {
    141                 actuateHardware = true;
    142             }
    143         } else {
    144             // sensor was already activated for this ident
    145         }
    146     } else {
    147         Mutex::Autolock _l(mLock);
    148         ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
    149                 info.rates.indexOfKey(ident));
    150 
    151         ssize_t idx = info.rates.removeItem(ident);
    152         if (idx >= 0) {
    153             if (info.rates.size() == 0) {
    154                 actuateHardware = true;
    155             }
    156         } else {
    157             // sensor wasn't enabled for this ident
    158         }
    159     }
    160 
    161     if (actuateHardware) {
    162         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
    163 
    164         err = mSensorDevice->activate(mSensorDevice, handle, enabled);
    165         ALOGE_IF(err, "Error %s sensor %d (%s)",
    166                 enabled ? "activating" : "disabling",
    167                 handle, strerror(-err));
    168 
    169         if (err != NO_ERROR) {
    170             // clean-up on failure
    171             if (enabled) {
    172                 // failure when enabling the sensor
    173                 Mutex::Autolock _l(mLock);
    174                 info.rates.removeItem(ident);
    175             }
    176         }
    177     }
    178 
    179     { // scope for the lock
    180         Mutex::Autolock _l(mLock);
    181         nsecs_t ns = info.selectDelay();
    182         mSensorDevice->setDelay(mSensorDevice, handle, ns);
    183     }
    184 
    185     return err;
    186 }
    187 
    188 status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
    189 {
    190     if (!mSensorDevice) return NO_INIT;
    191     Mutex::Autolock _l(mLock);
    192     Info& info( mActivationCount.editValueFor(handle) );
    193     status_t err = info.setDelayForIdent(ident, ns);
    194     if (err < 0) return err;
    195     ns = info.selectDelay();
    196     return mSensorDevice->setDelay(mSensorDevice, handle, ns);
    197 }
    198 
    199 int SensorDevice::getHalDeviceVersion() const {
    200     if (!mSensorDevice) return -1;
    201 
    202     return mSensorDevice->common.version;
    203 }
    204 
    205 // ---------------------------------------------------------------------------
    206 
    207 status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
    208 {
    209     ssize_t index = rates.indexOfKey(ident);
    210     if (index < 0) {
    211         ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
    212                 ident, ns, strerror(-index));
    213         return BAD_INDEX;
    214     }
    215     rates.editValueAt(index) = ns;
    216     return NO_ERROR;
    217 }
    218 
    219 nsecs_t SensorDevice::Info::selectDelay()
    220 {
    221     nsecs_t ns = rates.valueAt(0);
    222     for (size_t i=1 ; i<rates.size() ; i++) {
    223         nsecs_t cur = rates.valueAt(i);
    224         if (cur < ns) {
    225             ns = cur;
    226         }
    227     }
    228     delay = ns;
    229     return ns;
    230 }
    231 
    232 // ---------------------------------------------------------------------------
    233 }; // namespace android
    234 
    235