blob: 5410cbc525abb7febe1e36c490cd90f5801b0a8b [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>
26
27#include <binder/BinderService.h>
28
29#include <gui/ISensorServer.h>
30#include <gui/ISensorEventConnection.h>
31
32#include <hardware/sensors.h>
33
34#include "SensorService.h"
35
36namespace android {
37// ---------------------------------------------------------------------------
38
39/*
40 * TODO:
41 * - handle per-connection event rate
42 * - filter events per connection
43 * - make sure to keep the last value of each event type so we can quickly
44 * send something to application when they enable a sensor that is already
45 * active (the issue here is that it can take time before a value is
46 * produced by the h/w if the rate is low or if it's a one-shot sensor).
47 */
48
49SensorService::SensorService()
50 : Thread(false),
51 mDump("android.permission.DUMP")
52{
53}
54
55void SensorService::onFirstRef()
56{
57 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
58 (hw_module_t const**)&mSensorModule);
59
60 LOGE_IF(err, "couldn't load %s module (%s)",
61 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
62
63 err = sensors_open(&mSensorModule->common, &mSensorDevice);
64
65 LOGE_IF(err, "couldn't open device for module %s (%s)",
66 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
67
68 LOGD("nuSensorService starting...");
69
70 struct sensor_t const* list;
71 int count = mSensorModule->get_sensors_list(mSensorModule, &list);
72 for (int i=0 ; i<count ; i++) {
73 Sensor sensor(list + i);
74 LOGI("%s", sensor.getName().string());
75 mSensorList.add(sensor);
76 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
77 }
78
79 run("SensorService", PRIORITY_URGENT_DISPLAY);
80}
81
82SensorService::~SensorService()
83{
84}
85
86status_t SensorService::dump(int fd, const Vector<String16>& args)
87{
88 const size_t SIZE = 1024;
89 char buffer[SIZE];
90 String8 result;
91 if (!mDump.checkCalling()) {
92 snprintf(buffer, SIZE, "Permission Denial: "
93 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
94 IPCThreadState::self()->getCallingPid(),
95 IPCThreadState::self()->getCallingUid());
96 result.append(buffer);
97 } else {
98 Mutex::Autolock _l(mLock);
99 snprintf(buffer, SIZE, "%d connections / %d active\n",
100 mConnections.size(), mActiveConnections.size());
101 result.append(buffer);
102 snprintf(buffer, SIZE, "Active sensors:\n");
103 result.append(buffer);
104 for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
105 snprintf(buffer, SIZE, "handle=%d, connections=%d\n",
106 mActiveSensors.keyAt(i),
107 mActiveSensors.valueAt(i)->getNumConnections());
108 result.append(buffer);
109 }
110 }
111 write(fd, result.string(), result.size());
112 return NO_ERROR;
113}
114
115bool SensorService::threadLoop()
116{
117 LOGD("nuSensorService thread starting...");
118
119 sensors_event_t buffer[16];
120 struct sensors_poll_device_t* device = mSensorDevice;
121 ssize_t count;
122
123 do {
124 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
125 if (count<0) {
126 LOGE("sensor poll failed (%s)", strerror(-count));
127 break;
128 }
129
130 const SortedVector< wp<SensorEventConnection> > activeConnections(
131 getActiveConnections());
132
133 size_t numConnections = activeConnections.size();
134 if (numConnections) {
135 for (size_t i=0 ; i<numConnections ; i++) {
136 sp<SensorEventConnection> connection(activeConnections[i].promote());
137 if (connection != 0) {
138 connection->sendEvents(buffer, count);
139 }
140 }
141 }
142
143 } while (count >= 0 || Thread::exitPending());
144
145 LOGW("Exiting SensorService::threadLoop!");
146 return false;
147}
148
149SortedVector< wp<SensorService::SensorEventConnection> >
150SensorService::getActiveConnections() const
151{
152 Mutex::Autolock _l(mLock);
153 return mActiveConnections;
154}
155
156Vector<Sensor> SensorService::getSensorList()
157{
158 return mSensorList;
159}
160
161sp<ISensorEventConnection> SensorService::createSensorEventConnection()
162{
163 sp<SensorEventConnection> result(new SensorEventConnection(this));
164 Mutex::Autolock _l(mLock);
165 mConnections.add(result);
166 return result;
167}
168
169void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
170{
171 Mutex::Autolock _l(mLock);
172 ssize_t index = mConnections.indexOf(connection);
173 if (index >= 0) {
174
175 size_t size = mActiveSensors.size();
176 for (size_t i=0 ; i<size ; ) {
177 SensorRecord* rec = mActiveSensors.valueAt(i);
178 if (rec && rec->removeConnection(connection)) {
179 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
180 mActiveSensors.removeItemsAt(i, 1);
181 delete rec;
182 size--;
183 } else {
184 i++;
185 }
186 }
187
188 mActiveConnections.remove(connection);
189 mConnections.removeItemsAt(index, 1);
190 }
191}
192
193status_t SensorService::enable(const sp<SensorEventConnection>& connection,
194 int handle)
195{
196 status_t err = NO_ERROR;
197 Mutex::Autolock _l(mLock);
198 SensorRecord* rec = mActiveSensors.valueFor(handle);
199 if (rec == 0) {
200 rec = new SensorRecord(connection);
201 mActiveSensors.add(handle, rec);
202 err = mSensorDevice->activate(mSensorDevice, handle, 1);
203 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
204 } else {
205 err = rec->addConnection(connection);
206 }
207 if (err == NO_ERROR) {
208 // connection now active
209 connection->addSensor(handle);
210 if (mActiveConnections.indexOf(connection) < 0) {
211 mActiveConnections.add(connection);
212 }
213 }
214 return err;
215}
216
217status_t SensorService::disable(const sp<SensorEventConnection>& connection,
218 int handle)
219{
220 status_t err = NO_ERROR;
221 Mutex::Autolock _l(mLock);
222 SensorRecord* rec = mActiveSensors.valueFor(handle);
223 LOGW("sensor (handle=%d) is not enabled", handle);
224 if (rec) {
225 // see if this connection becomes inactive
226 connection->removeSensor(handle);
227 if (connection->hasAnySensor() == false) {
228 mActiveConnections.remove(connection);
229 }
230 // see if this sensor becomes inactive
231 if (rec->removeConnection(connection)) {
232 mActiveSensors.removeItem(handle);
233 delete rec;
234 err = mSensorDevice->activate(mSensorDevice, handle, 0);
235 }
236 }
237 return err;
238}
239
240status_t SensorService::setRate(const sp<SensorEventConnection>& connection,
241 int handle, nsecs_t ns)
242{
243 status_t err = NO_ERROR;
244 Mutex::Autolock _l(mLock);
245
246 err = mSensorDevice->setDelay(mSensorDevice, handle, ns);
247
248 // TODO: handle rate per connection
249 return err;
250}
251
252// ---------------------------------------------------------------------------
253
254SensorService::SensorRecord::SensorRecord(
255 const sp<SensorEventConnection>& connection)
256{
257 mConnections.add(connection);
258}
259
260status_t SensorService::SensorRecord::addConnection(
261 const sp<SensorEventConnection>& connection)
262{
263 if (mConnections.indexOf(connection) < 0) {
264 mConnections.add(connection);
265 }
266 return NO_ERROR;
267}
268
269bool SensorService::SensorRecord::removeConnection(
270 const wp<SensorEventConnection>& connection)
271{
272 ssize_t index = mConnections.indexOf(connection);
273 if (index >= 0) {
274 mConnections.removeItemsAt(index, 1);
275 }
276 return mConnections.size() ? false : true;
277}
278
279// ---------------------------------------------------------------------------
280
281SensorService::SensorEventConnection::SensorEventConnection(
282 const sp<SensorService>& service)
283 : mService(service), mChannel(new SensorChannel())
284{
285}
286
287SensorService::SensorEventConnection::~SensorEventConnection()
288{
289 mService->cleanupConnection(this);
290}
291
292void SensorService::SensorEventConnection::onFirstRef()
293{
294}
295
296void SensorService::SensorEventConnection::addSensor(int32_t handle) {
297 if (mSensorList.indexOf(handle) <= 0) {
298 mSensorList.add(handle);
299 }
300}
301
302void SensorService::SensorEventConnection::removeSensor(int32_t handle) {
303 mSensorList.remove(handle);
304}
305
306bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
307 return mSensorList.indexOf(handle) >= 0;
308}
309
310bool SensorService::SensorEventConnection::hasAnySensor() const {
311 return mSensorList.size() ? true : false;
312}
313
314status_t SensorService::SensorEventConnection::sendEvents(
315 sensors_event_t const* buffer, size_t count)
316{
317 // TODO: we should only send the events for the sensors this connection
318 // is registered for.
319
320 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
321 if (size == -EAGAIN) {
322 // the destination doesn't accept events anymore, it's probably
323 // full. For now, we just drop the events on the floor.
324 LOGW("dropping %d events on the floor", count);
325 return size;
326 }
327
328 LOGE_IF(size<0, "dropping %d events on the floor (%s)",
329 count, strerror(-size));
330
331 return size < 0 ? size : NO_ERROR;
332}
333
334sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
335{
336 return mChannel;
337}
338
339status_t SensorService::SensorEventConnection::enableDisable(
340 int handle, bool enabled)
341{
342 status_t err;
343 if (enabled) {
344 err = mService->enable(this, handle);
345 } else {
346 err = mService->disable(this, handle);
347 }
348 return err;
349}
350
351status_t SensorService::SensorEventConnection::setEventRate(
352 int handle, nsecs_t ns)
353{
354 return mService->setRate(this, handle, ns);
355}
356
357// ---------------------------------------------------------------------------
358}; // namespace android
359