SensorService.cpp revision 451beee076cac09f817abae78a990dea108a9482
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#include <utils/Singleton.h>
27
28#include <binder/BinderService.h>
29#include <binder/IServiceManager.h>
30
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).
49 * - send sensor info to battery service
50 */
51
52// ---------------------------------------------------------------------------
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
80SensorService::SensorService()
81    : Thread(false),
82      mDump("android.permission.DUMP")
83{
84}
85
86void SensorService::onFirstRef()
87{
88    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
89            (hw_module_t const**)&mSensorModule);
90
91    LOGE_IF(err, "couldn't load %s module (%s)",
92            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
93
94    err = sensors_open(&mSensorModule->common, &mSensorDevice);
95
96    LOGE_IF(err, "couldn't open device for module %s (%s)",
97            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
98
99    LOGD("nuSensorService starting...");
100
101    struct sensor_t const* list;
102    int count = mSensorModule->get_sensors_list(mSensorModule, &list);
103    for (int i=0 ; i<count ; i++) {
104        Sensor sensor(list + i);
105        LOGI("%s", sensor.getName().string());
106        mSensorList.add(sensor);
107        mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
108    }
109
110    run("SensorService", PRIORITY_URGENT_DISPLAY);
111}
112
113SensorService::~SensorService()
114{
115}
116
117status_t SensorService::dump(int fd, const Vector<String16>& args)
118{
119    const size_t SIZE = 1024;
120    char buffer[SIZE];
121    String8 result;
122    if (!mDump.checkCalling()) {
123        snprintf(buffer, SIZE, "Permission Denial: "
124                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
125                IPCThreadState::self()->getCallingPid(),
126                IPCThreadState::self()->getCallingUid());
127        result.append(buffer);
128    } else {
129        Mutex::Autolock _l(mLock);
130        snprintf(buffer, SIZE, "%d connections / %d active\n",
131                mConnections.size(), mActiveConnections.size());
132        result.append(buffer);
133        snprintf(buffer, SIZE, "Active sensors:\n");
134        result.append(buffer);
135        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
136            snprintf(buffer, SIZE, "handle=%d, connections=%d\n",
137                    mActiveSensors.keyAt(i),
138                    mActiveSensors.valueAt(i)->getNumConnections());
139            result.append(buffer);
140        }
141    }
142    write(fd, result.string(), result.size());
143    return NO_ERROR;
144}
145
146bool SensorService::threadLoop()
147{
148    LOGD("nuSensorService thread starting...");
149
150    sensors_event_t buffer[16];
151    struct sensors_poll_device_t* device = mSensorDevice;
152    ssize_t count;
153
154    do {
155        count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
156        if (count<0) {
157            LOGE("sensor poll failed (%s)", strerror(-count));
158            break;
159        }
160
161        const SortedVector< wp<SensorEventConnection> > activeConnections(
162                getActiveConnections());
163
164        size_t numConnections = activeConnections.size();
165        if (numConnections) {
166            for (size_t i=0 ; i<numConnections ; i++) {
167                sp<SensorEventConnection> connection(activeConnections[i].promote());
168                if (connection != 0) {
169                    connection->sendEvents(buffer, count);
170                }
171            }
172        }
173
174    } while (count >= 0 || Thread::exitPending());
175
176    LOGW("Exiting SensorService::threadLoop!");
177    return false;
178}
179
180SortedVector< wp<SensorService::SensorEventConnection> >
181SensorService::getActiveConnections() const
182{
183    Mutex::Autolock _l(mLock);
184    return mActiveConnections;
185}
186
187Vector<Sensor> SensorService::getSensorList()
188{
189    return mSensorList;
190}
191
192sp<ISensorEventConnection> SensorService::createSensorEventConnection()
193{
194    sp<SensorEventConnection> result(new SensorEventConnection(this));
195    Mutex::Autolock _l(mLock);
196    mConnections.add(result);
197    return result;
198}
199
200void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
201{
202    Mutex::Autolock _l(mLock);
203    ssize_t index = mConnections.indexOf(connection);
204    if (index >= 0) {
205
206        size_t size = mActiveSensors.size();
207        for (size_t i=0 ; i<size ; ) {
208            SensorRecord* rec = mActiveSensors.valueAt(i);
209            if (rec && rec->removeConnection(connection)) {
210                mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
211                mActiveSensors.removeItemsAt(i, 1);
212                delete rec;
213                size--;
214            } else {
215                i++;
216            }
217        }
218
219        mActiveConnections.remove(connection);
220        mConnections.removeItemsAt(index, 1);
221    }
222}
223
224status_t SensorService::enable(const sp<SensorEventConnection>& connection,
225        int handle)
226{
227    status_t err = NO_ERROR;
228    Mutex::Autolock _l(mLock);
229    SensorRecord* rec = mActiveSensors.valueFor(handle);
230    if (rec == 0) {
231        rec = new SensorRecord(connection);
232        mActiveSensors.add(handle, rec);
233        err = mSensorDevice->activate(mSensorDevice, handle, 1);
234        LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
235        if (err == 0) {
236            BatteryService::getInstance().enableSensor(handle);
237        }
238    } else {
239        err = rec->addConnection(connection);
240    }
241    if (err == NO_ERROR) {
242        // connection now active
243        connection->addSensor(handle);
244        if (mActiveConnections.indexOf(connection) < 0) {
245            mActiveConnections.add(connection);
246        }
247    }
248    return err;
249}
250
251status_t SensorService::disable(const sp<SensorEventConnection>& connection,
252        int handle)
253{
254    status_t err = NO_ERROR;
255    Mutex::Autolock _l(mLock);
256    SensorRecord* rec = mActiveSensors.valueFor(handle);
257    LOGW("sensor (handle=%d) is not enabled", handle);
258    if (rec) {
259        // see if this connection becomes inactive
260        connection->removeSensor(handle);
261        if (connection->hasAnySensor() == false) {
262            mActiveConnections.remove(connection);
263        }
264        // see if this sensor becomes inactive
265        if (rec->removeConnection(connection)) {
266            mActiveSensors.removeItem(handle);
267            delete rec;
268            err = mSensorDevice->activate(mSensorDevice, handle, 0);
269            if (err == 0) {
270                BatteryService::getInstance().disableSensor(handle);
271            }
272        }
273    }
274    return err;
275}
276
277status_t SensorService::setRate(const sp<SensorEventConnection>& connection,
278        int handle, nsecs_t ns)
279{
280    status_t err = NO_ERROR;
281    Mutex::Autolock _l(mLock);
282
283    err = mSensorDevice->setDelay(mSensorDevice, handle, ns);
284
285    // TODO: handle rate per connection
286    return err;
287}
288
289// ---------------------------------------------------------------------------
290
291SensorService::SensorRecord::SensorRecord(
292        const sp<SensorEventConnection>& connection)
293{
294    mConnections.add(connection);
295}
296
297status_t SensorService::SensorRecord::addConnection(
298        const sp<SensorEventConnection>& connection)
299{
300    if (mConnections.indexOf(connection) < 0) {
301        mConnections.add(connection);
302    }
303    return NO_ERROR;
304}
305
306bool SensorService::SensorRecord::removeConnection(
307        const wp<SensorEventConnection>& connection)
308{
309    ssize_t index = mConnections.indexOf(connection);
310    if (index >= 0) {
311        mConnections.removeItemsAt(index, 1);
312    }
313    return mConnections.size() ? false : true;
314}
315
316// ---------------------------------------------------------------------------
317
318SensorService::SensorEventConnection::SensorEventConnection(
319        const sp<SensorService>& service)
320    : mService(service), mChannel(new SensorChannel())
321{
322}
323
324SensorService::SensorEventConnection::~SensorEventConnection()
325{
326    mService->cleanupConnection(this);
327}
328
329void SensorService::SensorEventConnection::onFirstRef()
330{
331}
332
333void SensorService::SensorEventConnection::addSensor(int32_t handle) {
334    if (mSensorList.indexOf(handle) <= 0) {
335        mSensorList.add(handle);
336    }
337}
338
339void SensorService::SensorEventConnection::removeSensor(int32_t handle) {
340    mSensorList.remove(handle);
341}
342
343bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
344    return mSensorList.indexOf(handle) >= 0;
345}
346
347bool SensorService::SensorEventConnection::hasAnySensor() const {
348    return mSensorList.size() ? true : false;
349}
350
351status_t SensorService::SensorEventConnection::sendEvents(
352        sensors_event_t const* buffer, size_t count)
353{
354    // TODO: we should only send the events for the sensors this connection
355    // is registered for.
356
357    ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
358    if (size == -EAGAIN) {
359        // the destination doesn't accept events anymore, it's probably
360        // full. For now, we just drop the events on the floor.
361        LOGW("dropping %d events on the floor", count);
362        return size;
363    }
364
365    LOGE_IF(size<0, "dropping %d events on the floor (%s)",
366            count, strerror(-size));
367
368    return size < 0 ? size : NO_ERROR;
369}
370
371sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
372{
373    return mChannel;
374}
375
376status_t SensorService::SensorEventConnection::enableDisable(
377        int handle, bool enabled)
378{
379    status_t err;
380    if (enabled) {
381        err = mService->enable(this, handle);
382    } else {
383        err = mService->disable(this, handle);
384    }
385    return err;
386}
387
388status_t SensorService::SensorEventConnection::setEventRate(
389        int handle, nsecs_t ns)
390{
391    return mService->setRate(this, handle, ns);
392}
393
394// ---------------------------------------------------------------------------
395}; // namespace android
396
397