SensorService.cpp revision fc32881fcc68640d008c7515cdd1bcd866f72cd5
1/*
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
360