SensorDevice.cpp revision a551237de142549fb8a6608ee9d2fbf4b7ca2ebf
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 34namespace android { 35// --------------------------------------------------------------------------- 36class 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 74public: 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 93const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats"); 94 95ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService) 96 97// --------------------------------------------------------------------------- 98 99ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) 100 101SensorDevice::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 LOGE_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 LOGE_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 130void 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 157ssize_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 163status_t SensorDevice::initCheck() const { 164 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; 165} 166 167ssize_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 176status_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 LOGE_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 242status_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 255status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns) 256{ 257 ssize_t index = rates.indexOfKey(ident); 258 if (index < 0) { 259 LOGE("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 267nsecs_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