SensorDevice.cpp revision a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0
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 snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d\n", 142 list[i].handle, 143 mActivationCount.valueFor(list[i].handle).rates.size()); 144 result.append(buffer); 145 } 146} 147 148ssize_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 154status_t SensorDevice::initCheck() const { 155 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; 156} 157 158ssize_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 163status_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 171 172 LOGD_IF(DEBUG_CONNECTIONS, 173 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d", 174 ident, handle, enabled, info.rates.size()); 175 176 if (enabled) { 177 Mutex::Autolock _l(mLock); 178 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", 179 info.rates.indexOfKey(ident)); 180 181 if (info.rates.indexOfKey(ident) < 0) { 182 info.rates.add(ident, DEFAULT_EVENTS_PERIOD); 183 if (info.rates.size() == 1) { 184 actuateHardware = true; 185 } 186 } else { 187 // sensor was already activated for this ident 188 } 189 } else { 190 Mutex::Autolock _l(mLock); 191 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld", 192 info.rates.indexOfKey(ident)); 193 194 ssize_t idx = info.rates.removeItem(ident); 195 if (idx >= 0) { 196 if (info.rates.size() == 0) { 197 actuateHardware = true; 198 } 199 } else { 200 // sensor wasn't enabled for this ident 201 } 202 } 203 204 if (actuateHardware) { 205 LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w"); 206 207 err = mSensorDevice->activate(mSensorDevice, handle, enabled); 208 if (enabled) { 209 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err)); 210 if (err == 0) { 211 BatteryService::getInstance().enableSensor(handle); 212 } 213 } else { 214 if (err == 0) { 215 BatteryService::getInstance().disableSensor(handle); 216 } 217 } 218 } 219 220 if (!actuateHardware || enabled) { 221 Mutex::Autolock _l(mLock); 222 nsecs_t ns = info.rates.valueAt(0); 223 for (size_t i=1 ; i<info.rates.size() ; i++) { 224 if (info.rates.valueAt(i) < ns) { 225 nsecs_t cur = info.rates.valueAt(i); 226 if (cur < ns) { 227 ns = cur; 228 } 229 } 230 } 231 mSensorDevice->setDelay(mSensorDevice, handle, ns); 232 } 233 234 return err; 235} 236 237status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns) 238{ 239 if (!mSensorDevice) return NO_INIT; 240 Info& info( mActivationCount.editValueFor(handle) ); 241 { // scope for lock 242 Mutex::Autolock _l(mLock); 243 ssize_t index = info.rates.indexOfKey(ident); 244 if (index < 0) return BAD_INDEX; 245 info.rates.editValueAt(index) = ns; 246 ns = info.rates.valueAt(0); 247 for (size_t i=1 ; i<info.rates.size() ; i++) { 248 nsecs_t cur = info.rates.valueAt(i); 249 if (cur < ns) { 250 ns = cur; 251 } 252 } 253 } 254 return mSensorDevice->setDelay(mSensorDevice, handle, ns); 255} 256 257// --------------------------------------------------------------------------- 258}; // namespace android 259 260