blob: d82a7e23831859184e1d61643d1e0b34ecc3bbf1 [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 Agopian667102f2011-09-14 16:43:34 -0700141 const Info& info = mActivationCount.valueFor(list[i].handle);
142 snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ",
Mathias Agopianf001c922010-11-11 17:58:51 -0800143 list[i].handle,
Mathias Agopian667102f2011-09-14 16:43:34 -0700144 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);
Mathias Agopianf001c922010-11-11 17:58:51 -0800153 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 return mSensorDevice->poll(mSensorDevice, buffer, count);
170}
171
172status_t SensorDevice::activate(void* ident, int handle, int enabled)
173{
174 if (!mSensorDevice) return NO_INIT;
175 status_t err(NO_ERROR);
176 bool actuateHardware = false;
177
178 Info& info( mActivationCount.editValueFor(handle) );
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700179
180
181 LOGD_IF(DEBUG_CONNECTIONS,
182 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
183 ident, handle, enabled, info.rates.size());
184
Mathias Agopianf001c922010-11-11 17:58:51 -0800185 if (enabled) {
Mathias Agopianf001c922010-11-11 17:58:51 -0800186 Mutex::Autolock _l(mLock);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700187 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
188 info.rates.indexOfKey(ident));
189
Mathias Agopianf001c922010-11-11 17:58:51 -0800190 if (info.rates.indexOfKey(ident) < 0) {
191 info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700192 if (info.rates.size() == 1) {
193 actuateHardware = true;
194 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800195 } else {
196 // sensor was already activated for this ident
Mathias Agopianf001c922010-11-11 17:58:51 -0800197 }
198 } else {
Mathias Agopianf001c922010-11-11 17:58:51 -0800199 Mutex::Autolock _l(mLock);
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700200 LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
201 info.rates.indexOfKey(ident));
202
203 ssize_t idx = info.rates.removeItem(ident);
204 if (idx >= 0) {
Mathias Agopian50b66762010-11-29 17:26:51 -0800205 if (info.rates.size() == 0) {
206 actuateHardware = true;
207 }
208 } else {
209 // sensor wasn't enabled for this ident
210 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800211 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800212
Mathias Agopianf001c922010-11-11 17:58:51 -0800213 if (actuateHardware) {
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700214 LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
215
Mathias Agopianf001c922010-11-11 17:58:51 -0800216 err = mSensorDevice->activate(mSensorDevice, handle, enabled);
217 if (enabled) {
218 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
219 if (err == 0) {
220 BatteryService::getInstance().enableSensor(handle);
221 }
222 } else {
223 if (err == 0) {
224 BatteryService::getInstance().disableSensor(handle);
225 }
226 }
227 }
228
Mathias Agopian667102f2011-09-14 16:43:34 -0700229 { // scope for the lock
Mathias Agopianf001c922010-11-11 17:58:51 -0800230 Mutex::Autolock _l(mLock);
Mathias Agopian667102f2011-09-14 16:43:34 -0700231 nsecs_t ns = info.selectDelay();
Mathias Agopianf001c922010-11-11 17:58:51 -0800232 mSensorDevice->setDelay(mSensorDevice, handle, ns);
233 }
234
235 return err;
236}
237
238status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
239{
240 if (!mSensorDevice) return NO_INIT;
Mathias Agopian667102f2011-09-14 16:43:34 -0700241 Mutex::Autolock _l(mLock);
Mathias Agopianf001c922010-11-11 17:58:51 -0800242 Info& info( mActivationCount.editValueFor(handle) );
Mathias Agopian667102f2011-09-14 16:43:34 -0700243 status_t err = info.setDelayForIdent(ident, ns);
244 if (err < 0) return err;
245 ns = info.selectDelay();
246 return mSensorDevice->setDelay(mSensorDevice, handle, ns);
247}
248
249// ---------------------------------------------------------------------------
250
251status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
252{
253 ssize_t index = rates.indexOfKey(ident);
254 if (index < 0) {
255 LOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
256 ident, ns, strerror(-index));
257 return BAD_INDEX;
258 }
259 rates.editValueAt(index) = ns;
260 return NO_ERROR;
261}
262
263nsecs_t SensorDevice::Info::selectDelay()
264{
265 nsecs_t ns = rates.valueAt(0);
266 for (size_t i=1 ; i<rates.size() ; i++) {
267 nsecs_t cur = rates.valueAt(i);
268 if (cur < ns) {
269 ns = cur;
Mathias Agopianf001c922010-11-11 17:58:51 -0800270 }
271 }
Mathias Agopian667102f2011-09-14 16:43:34 -0700272 delay = ns;
273 return ns;
Mathias Agopianf001c922010-11-11 17:58:51 -0800274}
275
276// ---------------------------------------------------------------------------
277}; // namespace android
278