blob: 38d498c068b729989ba7400911ee6e4198aab6e7 [file] [log] [blame]
Mathias Agopianf001c922010-11-11 17:58:51 -08001/*
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"
Mathias Agopiana1b7db92011-05-27 16:23:58 -070032#include "SensorService.h"
Mathias Agopianf001c922010-11-11 17:58:51 -080033
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++) {
Mathias Agopian50b66762010-11-29 17:26:51 -0800141 snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d\n",
Mathias Agopianf001c922010-11-11 17:58:51 -0800142 list[i].handle,
Mathias Agopianf001c922010-11-11 17:58:51 -0800143 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) );
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700170
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
Mathias Agopianf001c922010-11-11 17:58:51 -0800176 if (enabled) {
Mathias Agopianf001c922010-11-11 17:58:51 -0800177 Mutex::Autolock _l(mLock);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700178 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
179 info.rates.indexOfKey(ident));
180
Mathias Agopianf001c922010-11-11 17:58:51 -0800181 if (info.rates.indexOfKey(ident) < 0) {
182 info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700183 if (info.rates.size() == 1) {
184 actuateHardware = true;
185 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800186 } else {
187 // sensor was already activated for this ident
Mathias Agopianf001c922010-11-11 17:58:51 -0800188 }
189 } else {
Mathias Agopianf001c922010-11-11 17:58:51 -0800190 Mutex::Autolock _l(mLock);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700191 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
192 info.rates.indexOfKey(ident));
193
194 ssize_t idx = info.rates.removeItem(ident);
195 if (idx >= 0) {
Mathias Agopian50b66762010-11-29 17:26:51 -0800196 if (info.rates.size() == 0) {
197 actuateHardware = true;
198 }
199 } else {
200 // sensor wasn't enabled for this ident
201 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800202 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800203
Mathias Agopianf001c922010-11-11 17:58:51 -0800204 if (actuateHardware) {
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700205 LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
206
Mathias Agopianf001c922010-11-11 17:58:51 -0800207 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 }
Mathias Agopian984826c2011-05-17 22:54:42 -0700254
255 //LOGD("setDelay: ident=%p, handle=%d, ns=%lld", ident, handle, ns);
256
Mathias Agopianf001c922010-11-11 17:58:51 -0800257 return mSensorDevice->setDelay(mSensorDevice, handle, ns);
258}
259
260// ---------------------------------------------------------------------------
261}; // namespace android
262