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