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 class BatteryService : public Singleton<BatteryService> {
     37     static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
     38     static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
     39     static const String16 DESCRIPTOR;
     40 
     41     friend class Singleton<BatteryService>;
     42     sp<IBinder> mBatteryStatService;
     43 
     44     BatteryService() {
     45         const sp<IServiceManager> sm(defaultServiceManager());
     46         if (sm != NULL) {
     47             const String16 name("batteryinfo");
     48             mBatteryStatService = sm->getService(name);
     49         }
     50     }
     51 
     52     status_t noteStartSensor(int uid, int handle) {
     53         Parcel data, reply;
     54         data.writeInterfaceToken(DESCRIPTOR);
     55         data.writeInt32(uid);
     56         data.writeInt32(handle);
     57         status_t err = mBatteryStatService->transact(
     58                 TRANSACTION_noteStartSensor, data, &reply, 0);
     59         err = reply.readExceptionCode();
     60         return err;
     61     }
     62 
     63     status_t noteStopSensor(int uid, int handle) {
     64         Parcel data, reply;
     65         data.writeInterfaceToken(DESCRIPTOR);
     66         data.writeInt32(uid);
     67         data.writeInt32(handle);
     68         status_t err = mBatteryStatService->transact(
     69                 TRANSACTION_noteStopSensor, data, &reply, 0);
     70         err = reply.readExceptionCode();
     71         return err;
     72     }
     73 
     74 public:
     75     void enableSensor(int handle) {
     76         if (mBatteryStatService != 0) {
     77             int uid = IPCThreadState::self()->getCallingUid();
     78             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
     79             noteStartSensor(uid, handle);
     80             IPCThreadState::self()->restoreCallingIdentity(identity);
     81         }
     82     }
     83     void disableSensor(int handle) {
     84         if (mBatteryStatService != 0) {
     85             int uid = IPCThreadState::self()->getCallingUid();
     86             int64_t identity = IPCThreadState::self()->clearCallingIdentity();
     87             noteStopSensor(uid, handle);
     88             IPCThreadState::self()->restoreCallingIdentity(identity);
     89         }
     90     }
     91 };
     92 
     93 const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
     94 
     95 ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
     96 
     97 // ---------------------------------------------------------------------------
     98 
     99 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
    100 
    101 SensorDevice::SensorDevice()
    102     :  mSensorDevice(0),
    103        mSensorModule(0)
    104 {
    105     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
    106             (hw_module_t const**)&mSensorModule);
    107 
    108     ALOGE_IF(err, "couldn't load %s module (%s)",
    109             SENSORS_HARDWARE_MODULE_ID, strerror(-err));
    110 
    111     if (mSensorModule) {
    112         err = sensors_open(&mSensorModule->common, &mSensorDevice);
    113 
    114         ALOGE_IF(err, "couldn't open device for module %s (%s)",
    115                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
    116 
    117         if (mSensorDevice) {
    118             sensor_t const* list;
    119             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
    120             mActivationCount.setCapacity(count);
    121             Info model;
    122             for (size_t i=0 ; i<size_t(count) ; i++) {
    123                 mActivationCount.add(list[i].handle, model);
    124                 mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
    125             }
    126         }
    127     }
    128 }
    129 
    130 void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
    131 {
    132     if (!mSensorModule) return;
    133     sensor_t const* list;
    134     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
    135 
    136     snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count));
    137     result.append(buffer);
    138 
    139     Mutex::Autolock _l(mLock);
    140     for (size_t i=0 ; i<size_t(count) ; i++) {
    141         const Info& info = mActivationCount.valueFor(list[i].handle);
    142         snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ",
    143                 list[i].handle,
    144                 info.rates.size());
    145         result.append(buffer);
    146         for (size_t j=0 ; j<info.rates.size() ; j++) {
    147             snprintf(buffer, SIZE, "%4.1f%s",
    148                     info.rates.valueAt(j) / 1e6f,
    149                     j<info.rates.size()-1 ? ", " : "");
    150             result.append(buffer);
    151         }
    152         snprintf(buffer, SIZE, " }, selected=%4.1f ms\n",  info.delay / 1e6f);
    153         result.append(buffer);
    154     }
    155 }
    156 
    157 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
    158     if (!mSensorModule) return NO_INIT;
    159     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
    160     return count;
    161 }
    162 
    163 status_t SensorDevice::initCheck() const {
    164     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
    165 }
    166 
    167 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    168     if (!mSensorDevice) return NO_INIT;
    169     ssize_t c;
    170     do {
    171         c = mSensorDevice->poll(mSensorDevice, buffer, count);
    172     } while (c == -EINTR);
    173     return c;
    174 }
    175 
    176 status_t SensorDevice::activate(void* ident, int handle, int enabled)
    177 {
    178     if (!mSensorDevice) return NO_INIT;
    179     status_t err(NO_ERROR);
    180     bool actuateHardware = false;
    181 
    182     Info& info( mActivationCount.editValueFor(handle) );
    183 
    184 
    185     ALOGD_IF(DEBUG_CONNECTIONS,
    186             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
    187             ident, handle, enabled, info.rates.size());
    188 
    189     if (enabled) {
    190         Mutex::Autolock _l(mLock);
    191         ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
    192                 info.rates.indexOfKey(ident));
    193 
    194         if (info.rates.indexOfKey(ident) < 0) {
    195             info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
    196             if (info.rates.size() == 1) {
    197                 actuateHardware = true;
    198             }
    199         } else {
    200             // sensor was already activated for this ident
    201         }
    202     } else {
    203         Mutex::Autolock _l(mLock);
    204         ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
    205                 info.rates.indexOfKey(ident));
    206 
    207         ssize_t idx = info.rates.removeItem(ident);
    208         if (idx >= 0) {
    209             if (info.rates.size() == 0) {
    210                 actuateHardware = true;
    211             }
    212         } else {
    213             // sensor wasn't enabled for this ident
    214         }
    215     }
    216 
    217     if (actuateHardware) {
    218         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
    219 
    220         err = mSensorDevice->activate(mSensorDevice, handle, enabled);
    221         if (enabled) {
    222             ALOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
    223             if (err == 0) {
    224                 BatteryService::getInstance().enableSensor(handle);
    225             }
    226         } else {
    227             if (err == 0) {
    228                 BatteryService::getInstance().disableSensor(handle);
    229             }
    230         }
    231     }
    232 
    233     { // scope for the lock
    234         Mutex::Autolock _l(mLock);
    235         nsecs_t ns = info.selectDelay();
    236         mSensorDevice->setDelay(mSensorDevice, handle, ns);
    237     }
    238 
    239     return err;
    240 }
    241 
    242 status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
    243 {
    244     if (!mSensorDevice) return NO_INIT;
    245     Mutex::Autolock _l(mLock);
    246     Info& info( mActivationCount.editValueFor(handle) );
    247     status_t err = info.setDelayForIdent(ident, ns);
    248     if (err < 0) return err;
    249     ns = info.selectDelay();
    250     return mSensorDevice->setDelay(mSensorDevice, handle, ns);
    251 }
    252 
    253 // ---------------------------------------------------------------------------
    254 
    255 status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
    256 {
    257     ssize_t index = rates.indexOfKey(ident);
    258     if (index < 0) {
    259         ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
    260                 ident, ns, strerror(-index));
    261         return BAD_INDEX;
    262     }
    263     rates.editValueAt(index) = ns;
    264     return NO_ERROR;
    265 }
    266 
    267 nsecs_t SensorDevice::Info::selectDelay()
    268 {
    269     nsecs_t ns = rates.valueAt(0);
    270     for (size_t i=1 ; i<rates.size() ; i++) {
    271         nsecs_t cur = rates.valueAt(i);
    272         if (cur < ns) {
    273             ns = cur;
    274         }
    275     }
    276     delay = ns;
    277     return ns;
    278 }
    279 
    280 // ---------------------------------------------------------------------------
    281 }; // namespace android
    282 
    283