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