blob: 82cdf3d40137015ffddc6f7f74c757f6ce7d8c2e [file] [log] [blame]
Mathias Agopianfc328812010-07-14 23:41:37 -07001/*
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 <sys/types.h>
19
20#include <utils/SortedVector.h>
21#include <utils/KeyedVector.h>
22#include <utils/threads.h>
23#include <utils/Atomic.h>
24#include <utils/Errors.h>
25#include <utils/RefBase.h>
Mathias Agopian451beee2010-07-19 15:03:55 -070026#include <utils/Singleton.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070027
28#include <binder/BinderService.h>
Mathias Agopian451beee2010-07-19 15:03:55 -070029#include <binder/IServiceManager.h>
Mathias Agopianfc328812010-07-14 23:41:37 -070030
31#include <gui/ISensorServer.h>
32#include <gui/ISensorEventConnection.h>
33
34#include <hardware/sensors.h>
35
36#include "SensorService.h"
37
38namespace android {
39// ---------------------------------------------------------------------------
40
41/*
42 * TODO:
Mathias Agopianfc328812010-07-14 23:41:37 -070043 * - filter events per connection
44 * - make sure to keep the last value of each event type so we can quickly
45 * send something to application when they enable a sensor that is already
46 * active (the issue here is that it can take time before a value is
47 * produced by the h/w if the rate is low or if it's a one-shot sensor).
Mathias Agopian451beee2010-07-19 15:03:55 -070048 * - send sensor info to battery service
Mathias Agopianfc328812010-07-14 23:41:37 -070049 */
50
Mathias Agopian451beee2010-07-19 15:03:55 -070051// ---------------------------------------------------------------------------
52
53class BatteryService : public Singleton<BatteryService> {
54 friend class Singleton<BatteryService>;
55 sp<IBinder> mBatteryStatService;
56 BatteryService() {
57 const String16 name("batteryinfo");
58 //getService(name, &mBatteryStatService);
59 }
60public:
61 void enableSensor(int handle) {
62 if (mBatteryStatService != 0) {
63 int uid = IPCThreadState::self()->getCallingUid();
64 //mBatteryStatService->noteStartSensor(uid, handle);
65 }
66 }
67 void disableSensor(int handle) {
68 if (mBatteryStatService != 0) {
69 int uid = IPCThreadState::self()->getCallingUid();
70 //mBatteryStatService->noteStopSensor(uid, handle);
71 }
72 }
73};
74
75ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
76
77// ---------------------------------------------------------------------------
78
Mathias Agopian1cd70002010-07-21 15:59:50 -070079// 100 events/s max
80static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10);
81
Mathias Agopianfc328812010-07-14 23:41:37 -070082SensorService::SensorService()
83 : Thread(false),
Mathias Agopian50df2952010-07-19 19:09:10 -070084 mSensorDevice(0),
85 mSensorModule(0),
86 mDump("android.permission.DUMP"),
87 mInitCheck(NO_INIT)
Mathias Agopianfc328812010-07-14 23:41:37 -070088{
89}
90
91void SensorService::onFirstRef()
92{
Mathias Agopian50df2952010-07-19 19:09:10 -070093 LOGD("nuSensorService starting...");
94
Mathias Agopianfc328812010-07-14 23:41:37 -070095 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
96 (hw_module_t const**)&mSensorModule);
97
98 LOGE_IF(err, "couldn't load %s module (%s)",
99 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
100
Mathias Agopian50df2952010-07-19 19:09:10 -0700101 if (mSensorModule) {
102 err = sensors_open(&mSensorModule->common, &mSensorDevice);
Mathias Agopianfc328812010-07-14 23:41:37 -0700103
Mathias Agopian50df2952010-07-19 19:09:10 -0700104 LOGE_IF(err, "couldn't open device for module %s (%s)",
105 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
Mathias Agopianfc328812010-07-14 23:41:37 -0700106
Mathias Agopian50df2952010-07-19 19:09:10 -0700107 struct sensor_t const* list;
108 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
109 for (int i=0 ; i<count ; i++) {
110 Sensor sensor(list + i);
111 LOGI("%s", sensor.getName().string());
112 mSensorList.add(sensor);
113 if (mSensorDevice) {
114 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
115 }
116 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700117
Mathias Agopian50df2952010-07-19 19:09:10 -0700118 if (mSensorDevice) {
119 run("SensorService", PRIORITY_URGENT_DISPLAY);
120 mInitCheck = NO_ERROR;
121 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700122 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700123}
124
125SensorService::~SensorService()
126{
127}
128
129status_t SensorService::dump(int fd, const Vector<String16>& args)
130{
131 const size_t SIZE = 1024;
132 char buffer[SIZE];
133 String8 result;
134 if (!mDump.checkCalling()) {
135 snprintf(buffer, SIZE, "Permission Denial: "
136 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
137 IPCThreadState::self()->getCallingPid(),
138 IPCThreadState::self()->getCallingUid());
139 result.append(buffer);
140 } else {
141 Mutex::Autolock _l(mLock);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700142 snprintf(buffer, SIZE, "%d active connections\n",
143 mActiveConnections.size());
Mathias Agopianfc328812010-07-14 23:41:37 -0700144 result.append(buffer);
145 snprintf(buffer, SIZE, "Active sensors:\n");
146 result.append(buffer);
147 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
Mathias Agopian5d270722010-07-19 15:20:39 -0700148 int handle = mActiveSensors.keyAt(i);
149 snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
150 getSensorName(handle).string(),
151 handle,
Mathias Agopianfc328812010-07-14 23:41:37 -0700152 mActiveSensors.valueAt(i)->getNumConnections());
153 result.append(buffer);
154 }
155 }
156 write(fd, result.string(), result.size());
157 return NO_ERROR;
158}
159
160bool SensorService::threadLoop()
161{
162 LOGD("nuSensorService thread starting...");
163
164 sensors_event_t buffer[16];
165 struct sensors_poll_device_t* device = mSensorDevice;
166 ssize_t count;
167
168 do {
169 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
170 if (count<0) {
171 LOGE("sensor poll failed (%s)", strerror(-count));
172 break;
173 }
174
175 const SortedVector< wp<SensorEventConnection> > activeConnections(
176 getActiveConnections());
177
178 size_t numConnections = activeConnections.size();
179 if (numConnections) {
180 for (size_t i=0 ; i<numConnections ; i++) {
181 sp<SensorEventConnection> connection(activeConnections[i].promote());
182 if (connection != 0) {
183 connection->sendEvents(buffer, count);
184 }
185 }
186 }
187
188 } while (count >= 0 || Thread::exitPending());
189
190 LOGW("Exiting SensorService::threadLoop!");
191 return false;
192}
193
194SortedVector< wp<SensorService::SensorEventConnection> >
195SensorService::getActiveConnections() const
196{
197 Mutex::Autolock _l(mLock);
198 return mActiveConnections;
199}
200
Mathias Agopian5d270722010-07-19 15:20:39 -0700201String8 SensorService::getSensorName(int handle) const {
202 size_t count = mSensorList.size();
203 for (size_t i=0 ; i<count ; i++) {
204 const Sensor& sensor(mSensorList[i]);
205 if (sensor.getHandle() == handle) {
206 return sensor.getName();
207 }
208 }
209 String8 result("unknown");
210 return result;
211}
212
Mathias Agopianfc328812010-07-14 23:41:37 -0700213Vector<Sensor> SensorService::getSensorList()
214{
215 return mSensorList;
216}
217
218sp<ISensorEventConnection> SensorService::createSensorEventConnection()
219{
220 sp<SensorEventConnection> result(new SensorEventConnection(this));
Mathias Agopianfc328812010-07-14 23:41:37 -0700221 return result;
222}
223
224void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
225{
226 Mutex::Autolock _l(mLock);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700227 size_t size = mActiveSensors.size();
228 for (size_t i=0 ; i<size ; ) {
229 SensorRecord* rec = mActiveSensors.valueAt(i);
230 if (rec && rec->removeConnection(connection)) {
231 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
232 mActiveSensors.removeItemsAt(i, 1);
233 delete rec;
234 size--;
235 } else {
236 i++;
Mathias Agopianfc328812010-07-14 23:41:37 -0700237 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700238 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700239 mActiveConnections.remove(connection);
Mathias Agopianfc328812010-07-14 23:41:37 -0700240}
241
242status_t SensorService::enable(const sp<SensorEventConnection>& connection,
243 int handle)
244{
Mathias Agopian50df2952010-07-19 19:09:10 -0700245 if (mInitCheck != NO_ERROR)
246 return mInitCheck;
247
Mathias Agopianfc328812010-07-14 23:41:37 -0700248 status_t err = NO_ERROR;
249 Mutex::Autolock _l(mLock);
250 SensorRecord* rec = mActiveSensors.valueFor(handle);
251 if (rec == 0) {
252 rec = new SensorRecord(connection);
253 mActiveSensors.add(handle, rec);
254 err = mSensorDevice->activate(mSensorDevice, handle, 1);
255 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
Mathias Agopian451beee2010-07-19 15:03:55 -0700256 if (err == 0) {
257 BatteryService::getInstance().enableSensor(handle);
258 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700259 } else {
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700260 rec->addConnection(connection);
Mathias Agopianfc328812010-07-14 23:41:37 -0700261 }
262 if (err == NO_ERROR) {
263 // connection now active
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700264 if (connection->addSensor(handle)) {
265 // the sensor was added (which means it wasn't already there)
266 // so, see if this connection becomes active
267 if (mActiveConnections.indexOf(connection) < 0) {
268 mActiveConnections.add(connection);
269 }
270 // this could change the sensor event delivery speed
271 recomputeEventsPeriodLocked(handle);
Mathias Agopianfc328812010-07-14 23:41:37 -0700272 }
273 }
274 return err;
275}
276
277status_t SensorService::disable(const sp<SensorEventConnection>& connection,
278 int handle)
279{
Mathias Agopian50df2952010-07-19 19:09:10 -0700280 if (mInitCheck != NO_ERROR)
281 return mInitCheck;
282
Mathias Agopianfc328812010-07-14 23:41:37 -0700283 status_t err = NO_ERROR;
284 Mutex::Autolock _l(mLock);
285 SensorRecord* rec = mActiveSensors.valueFor(handle);
Mathias Agopianfc328812010-07-14 23:41:37 -0700286 if (rec) {
287 // see if this connection becomes inactive
288 connection->removeSensor(handle);
289 if (connection->hasAnySensor() == false) {
290 mActiveConnections.remove(connection);
291 }
292 // see if this sensor becomes inactive
293 if (rec->removeConnection(connection)) {
294 mActiveSensors.removeItem(handle);
295 delete rec;
296 err = mSensorDevice->activate(mSensorDevice, handle, 0);
Mathias Agopian451beee2010-07-19 15:03:55 -0700297 if (err == 0) {
298 BatteryService::getInstance().disableSensor(handle);
299 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700300 }
301 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700302 if (err == NO_ERROR) {
303 recomputeEventsPeriodLocked(handle);
304 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700305 return err;
306}
307
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700308status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
Mathias Agopianfc328812010-07-14 23:41:37 -0700309 int handle, nsecs_t ns)
310{
Mathias Agopian50df2952010-07-19 19:09:10 -0700311 if (mInitCheck != NO_ERROR)
312 return mInitCheck;
313
Mathias Agopian1cd70002010-07-21 15:59:50 -0700314 if (ns < 0)
315 return BAD_VALUE;
316
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700317 if (ns < MINIMUM_EVENTS_PERIOD)
318 ns = MINIMUM_EVENTS_PERIOD;
Mathias Agopian1cd70002010-07-21 15:59:50 -0700319
Mathias Agopianfc328812010-07-14 23:41:37 -0700320 Mutex::Autolock _l(mLock);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700321 status_t err = connection->setEventRateLocked(handle, ns);
322 if (err == NO_ERROR) {
323 recomputeEventsPeriodLocked(handle);
324 }
325 return err;
326}
Mathias Agopianfc328812010-07-14 23:41:37 -0700327
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700328status_t SensorService::recomputeEventsPeriodLocked(int32_t handle)
329{
330 status_t err = NO_ERROR;
331 nsecs_t wanted = ms2ns(1000);
332 size_t count = mActiveConnections.size();
333 for (size_t i=0 ; i<count ; i++) {
334 sp<SensorEventConnection> connection(mActiveConnections[i].promote());
335 if (connection != NULL) {
336 nsecs_t ns = connection->getEventRateForSensor(handle);
337 if (ns) {
338 wanted = wanted < ns ? wanted : ns;
339 }
340 }
341 }
342 err = mSensorDevice->setDelay(mSensorDevice, handle, wanted);
Mathias Agopianfc328812010-07-14 23:41:37 -0700343 return err;
344}
345
346// ---------------------------------------------------------------------------
347
348SensorService::SensorRecord::SensorRecord(
349 const sp<SensorEventConnection>& connection)
350{
351 mConnections.add(connection);
352}
353
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700354bool SensorService::SensorRecord::addConnection(
Mathias Agopianfc328812010-07-14 23:41:37 -0700355 const sp<SensorEventConnection>& connection)
356{
357 if (mConnections.indexOf(connection) < 0) {
358 mConnections.add(connection);
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700359 return true;
Mathias Agopianfc328812010-07-14 23:41:37 -0700360 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700361 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700362}
363
364bool SensorService::SensorRecord::removeConnection(
365 const wp<SensorEventConnection>& connection)
366{
367 ssize_t index = mConnections.indexOf(connection);
368 if (index >= 0) {
369 mConnections.removeItemsAt(index, 1);
370 }
371 return mConnections.size() ? false : true;
372}
373
374// ---------------------------------------------------------------------------
375
376SensorService::SensorEventConnection::SensorEventConnection(
377 const sp<SensorService>& service)
378 : mService(service), mChannel(new SensorChannel())
379{
380}
381
382SensorService::SensorEventConnection::~SensorEventConnection()
383{
384 mService->cleanupConnection(this);
385}
386
387void SensorService::SensorEventConnection::onFirstRef()
388{
389}
390
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700391bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
392 if (mSensorInfo.indexOfKey(handle) <= 0) {
393 SensorInfo info;
394 mSensorInfo.add(handle, info);
395 return true;
Mathias Agopianfc328812010-07-14 23:41:37 -0700396 }
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700397 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700398}
399
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700400bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
401 if (mSensorInfo.removeItem(handle) >= 0) {
402 return true;
403 }
404 return false;
Mathias Agopianfc328812010-07-14 23:41:37 -0700405}
406
407bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700408 return mSensorInfo.indexOfKey(handle) >= 0;
Mathias Agopianfc328812010-07-14 23:41:37 -0700409}
410
411bool SensorService::SensorEventConnection::hasAnySensor() const {
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700412 return mSensorInfo.size() ? true : false;
413}
414
415status_t SensorService::SensorEventConnection::setEventRateLocked(
416 int handle, nsecs_t ns)
417{
418 ssize_t index = mSensorInfo.indexOfKey(handle);
419 if (index >= 0) {
420 SensorInfo& info = mSensorInfo.editValueFor(handle);
421 info.ns = ns;
422 return NO_ERROR;
423 }
424 return status_t(index);
Mathias Agopianfc328812010-07-14 23:41:37 -0700425}
426
427status_t SensorService::SensorEventConnection::sendEvents(
428 sensors_event_t const* buffer, size_t count)
429{
430 // TODO: we should only send the events for the sensors this connection
431 // is registered for.
432
433 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
434 if (size == -EAGAIN) {
435 // the destination doesn't accept events anymore, it's probably
436 // full. For now, we just drop the events on the floor.
437 LOGW("dropping %d events on the floor", count);
438 return size;
439 }
440
441 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
442 count, strerror(-size));
443
444 return size < 0 ? size : NO_ERROR;
445}
446
447sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
448{
449 return mChannel;
450}
451
452status_t SensorService::SensorEventConnection::enableDisable(
453 int handle, bool enabled)
454{
455 status_t err;
456 if (enabled) {
457 err = mService->enable(this, handle);
458 } else {
459 err = mService->disable(this, handle);
460 }
461 return err;
462}
463
464status_t SensorService::SensorEventConnection::setEventRate(
465 int handle, nsecs_t ns)
466{
Mathias Agopian7c1c5312010-07-21 15:59:50 -0700467 return mService->setEventRate(this, handle, ns);
Mathias Agopianfc328812010-07-14 23:41:37 -0700468}
469
470// ---------------------------------------------------------------------------
471}; // namespace android
472