blob: a4f6549764696501bdde6fec916a951e9ab84f94 [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:
43 * - handle per-connection event rate
44 * - filter events per connection
45 * - make sure to keep the last value of each event type so we can quickly
46 * send something to application when they enable a sensor that is already
47 * active (the issue here is that it can take time before a value is
48 * 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 -070049 * - send sensor info to battery service
Mathias Agopianfc328812010-07-14 23:41:37 -070050 */
51
Mathias Agopian451beee2010-07-19 15:03:55 -070052// ---------------------------------------------------------------------------
53
54class BatteryService : public Singleton<BatteryService> {
55 friend class Singleton<BatteryService>;
56 sp<IBinder> mBatteryStatService;
57 BatteryService() {
58 const String16 name("batteryinfo");
59 //getService(name, &mBatteryStatService);
60 }
61public:
62 void enableSensor(int handle) {
63 if (mBatteryStatService != 0) {
64 int uid = IPCThreadState::self()->getCallingUid();
65 //mBatteryStatService->noteStartSensor(uid, handle);
66 }
67 }
68 void disableSensor(int handle) {
69 if (mBatteryStatService != 0) {
70 int uid = IPCThreadState::self()->getCallingUid();
71 //mBatteryStatService->noteStopSensor(uid, handle);
72 }
73 }
74};
75
76ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
77
78// ---------------------------------------------------------------------------
79
Mathias Agopian1cd70002010-07-21 15:59:50 -070080// 100 events/s max
81static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10);
82
Mathias Agopianfc328812010-07-14 23:41:37 -070083SensorService::SensorService()
84 : Thread(false),
Mathias Agopian50df2952010-07-19 19:09:10 -070085 mSensorDevice(0),
86 mSensorModule(0),
87 mDump("android.permission.DUMP"),
88 mInitCheck(NO_INIT)
Mathias Agopianfc328812010-07-14 23:41:37 -070089{
90}
91
92void SensorService::onFirstRef()
93{
Mathias Agopian50df2952010-07-19 19:09:10 -070094 LOGD("nuSensorService starting...");
95
Mathias Agopianfc328812010-07-14 23:41:37 -070096 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
97 (hw_module_t const**)&mSensorModule);
98
99 LOGE_IF(err, "couldn't load %s module (%s)",
100 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
101
Mathias Agopian50df2952010-07-19 19:09:10 -0700102 if (mSensorModule) {
103 err = sensors_open(&mSensorModule->common, &mSensorDevice);
Mathias Agopianfc328812010-07-14 23:41:37 -0700104
Mathias Agopian50df2952010-07-19 19:09:10 -0700105 LOGE_IF(err, "couldn't open device for module %s (%s)",
106 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
Mathias Agopianfc328812010-07-14 23:41:37 -0700107
Mathias Agopian50df2952010-07-19 19:09:10 -0700108 struct sensor_t const* list;
109 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
110 for (int i=0 ; i<count ; i++) {
111 Sensor sensor(list + i);
112 LOGI("%s", sensor.getName().string());
113 mSensorList.add(sensor);
114 if (mSensorDevice) {
115 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
116 }
117 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700118
Mathias Agopian50df2952010-07-19 19:09:10 -0700119 if (mSensorDevice) {
120 run("SensorService", PRIORITY_URGENT_DISPLAY);
121 mInitCheck = NO_ERROR;
122 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700123 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700124}
125
126SensorService::~SensorService()
127{
128}
129
130status_t SensorService::dump(int fd, const Vector<String16>& args)
131{
132 const size_t SIZE = 1024;
133 char buffer[SIZE];
134 String8 result;
135 if (!mDump.checkCalling()) {
136 snprintf(buffer, SIZE, "Permission Denial: "
137 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
138 IPCThreadState::self()->getCallingPid(),
139 IPCThreadState::self()->getCallingUid());
140 result.append(buffer);
141 } else {
142 Mutex::Autolock _l(mLock);
143 snprintf(buffer, SIZE, "%d connections / %d active\n",
144 mConnections.size(), mActiveConnections.size());
145 result.append(buffer);
146 snprintf(buffer, SIZE, "Active sensors:\n");
147 result.append(buffer);
148 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
Mathias Agopian5d270722010-07-19 15:20:39 -0700149 int handle = mActiveSensors.keyAt(i);
150 snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
151 getSensorName(handle).string(),
152 handle,
Mathias Agopianfc328812010-07-14 23:41:37 -0700153 mActiveSensors.valueAt(i)->getNumConnections());
154 result.append(buffer);
155 }
156 }
157 write(fd, result.string(), result.size());
158 return NO_ERROR;
159}
160
161bool SensorService::threadLoop()
162{
163 LOGD("nuSensorService thread starting...");
164
165 sensors_event_t buffer[16];
166 struct sensors_poll_device_t* device = mSensorDevice;
167 ssize_t count;
168
169 do {
170 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
171 if (count<0) {
172 LOGE("sensor poll failed (%s)", strerror(-count));
173 break;
174 }
175
176 const SortedVector< wp<SensorEventConnection> > activeConnections(
177 getActiveConnections());
178
179 size_t numConnections = activeConnections.size();
180 if (numConnections) {
181 for (size_t i=0 ; i<numConnections ; i++) {
182 sp<SensorEventConnection> connection(activeConnections[i].promote());
183 if (connection != 0) {
184 connection->sendEvents(buffer, count);
185 }
186 }
187 }
188
189 } while (count >= 0 || Thread::exitPending());
190
191 LOGW("Exiting SensorService::threadLoop!");
192 return false;
193}
194
195SortedVector< wp<SensorService::SensorEventConnection> >
196SensorService::getActiveConnections() const
197{
198 Mutex::Autolock _l(mLock);
199 return mActiveConnections;
200}
201
Mathias Agopian5d270722010-07-19 15:20:39 -0700202String8 SensorService::getSensorName(int handle) const {
203 size_t count = mSensorList.size();
204 for (size_t i=0 ; i<count ; i++) {
205 const Sensor& sensor(mSensorList[i]);
206 if (sensor.getHandle() == handle) {
207 return sensor.getName();
208 }
209 }
210 String8 result("unknown");
211 return result;
212}
213
Mathias Agopianfc328812010-07-14 23:41:37 -0700214Vector<Sensor> SensorService::getSensorList()
215{
216 return mSensorList;
217}
218
219sp<ISensorEventConnection> SensorService::createSensorEventConnection()
220{
221 sp<SensorEventConnection> result(new SensorEventConnection(this));
222 Mutex::Autolock _l(mLock);
223 mConnections.add(result);
224 return result;
225}
226
227void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
228{
229 Mutex::Autolock _l(mLock);
230 ssize_t index = mConnections.indexOf(connection);
231 if (index >= 0) {
232
233 size_t size = mActiveSensors.size();
234 for (size_t i=0 ; i<size ; ) {
235 SensorRecord* rec = mActiveSensors.valueAt(i);
236 if (rec && rec->removeConnection(connection)) {
237 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
238 mActiveSensors.removeItemsAt(i, 1);
239 delete rec;
240 size--;
241 } else {
242 i++;
243 }
244 }
245
246 mActiveConnections.remove(connection);
247 mConnections.removeItemsAt(index, 1);
248 }
249}
250
251status_t SensorService::enable(const sp<SensorEventConnection>& connection,
252 int handle)
253{
Mathias Agopian50df2952010-07-19 19:09:10 -0700254 if (mInitCheck != NO_ERROR)
255 return mInitCheck;
256
Mathias Agopianfc328812010-07-14 23:41:37 -0700257 status_t err = NO_ERROR;
258 Mutex::Autolock _l(mLock);
259 SensorRecord* rec = mActiveSensors.valueFor(handle);
260 if (rec == 0) {
261 rec = new SensorRecord(connection);
262 mActiveSensors.add(handle, rec);
263 err = mSensorDevice->activate(mSensorDevice, handle, 1);
264 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
Mathias Agopian451beee2010-07-19 15:03:55 -0700265 if (err == 0) {
266 BatteryService::getInstance().enableSensor(handle);
267 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700268 } else {
269 err = rec->addConnection(connection);
270 }
271 if (err == NO_ERROR) {
272 // connection now active
273 connection->addSensor(handle);
274 if (mActiveConnections.indexOf(connection) < 0) {
275 mActiveConnections.add(connection);
276 }
277 }
278 return err;
279}
280
281status_t SensorService::disable(const sp<SensorEventConnection>& connection,
282 int handle)
283{
Mathias Agopian50df2952010-07-19 19:09:10 -0700284 if (mInitCheck != NO_ERROR)
285 return mInitCheck;
286
Mathias Agopianfc328812010-07-14 23:41:37 -0700287 status_t err = NO_ERROR;
288 Mutex::Autolock _l(mLock);
289 SensorRecord* rec = mActiveSensors.valueFor(handle);
Mathias Agopianfc328812010-07-14 23:41:37 -0700290 if (rec) {
291 // see if this connection becomes inactive
292 connection->removeSensor(handle);
293 if (connection->hasAnySensor() == false) {
294 mActiveConnections.remove(connection);
295 }
296 // see if this sensor becomes inactive
297 if (rec->removeConnection(connection)) {
298 mActiveSensors.removeItem(handle);
299 delete rec;
300 err = mSensorDevice->activate(mSensorDevice, handle, 0);
Mathias Agopian451beee2010-07-19 15:03:55 -0700301 if (err == 0) {
302 BatteryService::getInstance().disableSensor(handle);
303 }
Mathias Agopianfc328812010-07-14 23:41:37 -0700304 }
305 }
306 return err;
307}
308
309status_t SensorService::setRate(const sp<SensorEventConnection>& connection,
310 int handle, nsecs_t ns)
311{
Mathias Agopian50df2952010-07-19 19:09:10 -0700312 if (mInitCheck != NO_ERROR)
313 return mInitCheck;
314
Mathias Agopian1cd70002010-07-21 15:59:50 -0700315 if (ns < 0)
316 return BAD_VALUE;
317
318 if (ns < MINIMUM_EVENT_PERIOD)
319 ns = MINIMUM_EVENT_PERIOD;
320
Mathias Agopianfc328812010-07-14 23:41:37 -0700321 status_t err = NO_ERROR;
322 Mutex::Autolock _l(mLock);
323
324 err = mSensorDevice->setDelay(mSensorDevice, handle, ns);
325
326 // TODO: handle rate per connection
327 return err;
328}
329
330// ---------------------------------------------------------------------------
331
332SensorService::SensorRecord::SensorRecord(
333 const sp<SensorEventConnection>& connection)
334{
335 mConnections.add(connection);
336}
337
338status_t SensorService::SensorRecord::addConnection(
339 const sp<SensorEventConnection>& connection)
340{
341 if (mConnections.indexOf(connection) < 0) {
342 mConnections.add(connection);
343 }
344 return NO_ERROR;
345}
346
347bool SensorService::SensorRecord::removeConnection(
348 const wp<SensorEventConnection>& connection)
349{
350 ssize_t index = mConnections.indexOf(connection);
351 if (index >= 0) {
352 mConnections.removeItemsAt(index, 1);
353 }
354 return mConnections.size() ? false : true;
355}
356
357// ---------------------------------------------------------------------------
358
359SensorService::SensorEventConnection::SensorEventConnection(
360 const sp<SensorService>& service)
361 : mService(service), mChannel(new SensorChannel())
362{
363}
364
365SensorService::SensorEventConnection::~SensorEventConnection()
366{
367 mService->cleanupConnection(this);
368}
369
370void SensorService::SensorEventConnection::onFirstRef()
371{
372}
373
374void SensorService::SensorEventConnection::addSensor(int32_t handle) {
375 if (mSensorList.indexOf(handle) <= 0) {
376 mSensorList.add(handle);
377 }
378}
379
380void SensorService::SensorEventConnection::removeSensor(int32_t handle) {
381 mSensorList.remove(handle);
382}
383
384bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
385 return mSensorList.indexOf(handle) >= 0;
386}
387
388bool SensorService::SensorEventConnection::hasAnySensor() const {
389 return mSensorList.size() ? true : false;
390}
391
392status_t SensorService::SensorEventConnection::sendEvents(
393 sensors_event_t const* buffer, size_t count)
394{
395 // TODO: we should only send the events for the sensors this connection
396 // is registered for.
397
398 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
399 if (size == -EAGAIN) {
400 // the destination doesn't accept events anymore, it's probably
401 // full. For now, we just drop the events on the floor.
402 LOGW("dropping %d events on the floor", count);
403 return size;
404 }
405
406 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
407 count, strerror(-size));
408
409 return size < 0 ? size : NO_ERROR;
410}
411
412sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
413{
414 return mChannel;
415}
416
417status_t SensorService::SensorEventConnection::enableDisable(
418 int handle, bool enabled)
419{
420 status_t err;
421 if (enabled) {
422 err = mService->enable(this, handle);
423 } else {
424 err = mService->disable(this, handle);
425 }
426 return err;
427}
428
429status_t SensorService::SensorEventConnection::setEventRate(
430 int handle, nsecs_t ns)
431{
432 return mService->setRate(this, handle, ns);
433}
434
435// ---------------------------------------------------------------------------
436}; // namespace android
437