SensorService.cpp revision cf51001dbf28e9885fcacd4048902f1c75768fe9
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 * - 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 * - send sensor info to battery service
48 */
49
50// ---------------------------------------------------------------------------
51
52class BatteryService : public Singleton<BatteryService> {
53    friend class Singleton<BatteryService>;
54    sp<IBinder> mBatteryStatService;
55    BatteryService() {
56        const String16 name("batteryinfo");
57        //getService(name, &mBatteryStatService);
58    }
59public:
60    void enableSensor(int handle) {
61        if (mBatteryStatService != 0) {
62            int uid = IPCThreadState::self()->getCallingUid();
63            //mBatteryStatService->noteStartSensor(uid, handle);
64        }
65    }
66    void disableSensor(int handle) {
67        if (mBatteryStatService != 0) {
68            int uid = IPCThreadState::self()->getCallingUid();
69            //mBatteryStatService->noteStopSensor(uid, handle);
70        }
71    }
72};
73
74ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
75
76// ---------------------------------------------------------------------------
77
78// 100 events/s max
79static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10);
80
81SensorService::SensorService()
82    : Thread(false),
83      mSensorDevice(0),
84      mSensorModule(0),
85      mDump("android.permission.DUMP"),
86      mInitCheck(NO_INIT)
87{
88}
89
90void SensorService::onFirstRef()
91{
92    LOGD("nuSensorService starting...");
93
94    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
95            (hw_module_t const**)&mSensorModule);
96
97    LOGE_IF(err, "couldn't load %s module (%s)",
98            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
99
100    if (mSensorModule) {
101        err = sensors_open(&mSensorModule->common, &mSensorDevice);
102
103        LOGE_IF(err, "couldn't open device for module %s (%s)",
104                SENSORS_HARDWARE_MODULE_ID, strerror(-err));
105
106        struct sensor_t const* list;
107        int count = mSensorModule->get_sensors_list(mSensorModule, &list);
108        for (int i=0 ; i<count ; i++) {
109            Sensor sensor(list + i);
110            LOGI("%s", sensor.getName().string());
111            mSensorList.add(sensor);
112            if (mSensorDevice) {
113                mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
114            }
115        }
116
117        if (mSensorDevice) {
118            run("SensorService", PRIORITY_URGENT_DISPLAY);
119            mInitCheck = NO_ERROR;
120        }
121    }
122}
123
124SensorService::~SensorService()
125{
126}
127
128status_t SensorService::dump(int fd, const Vector<String16>& args)
129{
130    const size_t SIZE = 1024;
131    char buffer[SIZE];
132    String8 result;
133    if (!mDump.checkCalling()) {
134        snprintf(buffer, SIZE, "Permission Denial: "
135                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
136                IPCThreadState::self()->getCallingPid(),
137                IPCThreadState::self()->getCallingUid());
138        result.append(buffer);
139    } else {
140        Mutex::Autolock _l(mLock);
141        snprintf(buffer, SIZE, "%d active connections\n",
142                mActiveConnections.size());
143        result.append(buffer);
144        snprintf(buffer, SIZE, "Active sensors:\n");
145        result.append(buffer);
146        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
147            int handle = mActiveSensors.keyAt(i);
148            snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
149                    getSensorName(handle).string(),
150                    handle,
151                    mActiveSensors.valueAt(i)->getNumConnections());
152            result.append(buffer);
153        }
154    }
155    write(fd, result.string(), result.size());
156    return NO_ERROR;
157}
158
159bool SensorService::threadLoop()
160{
161    LOGD("nuSensorService thread starting...");
162
163    sensors_event_t buffer[16];
164    sensors_event_t scratch[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            Mutex::Autolock _l(mLock);
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, scratch);
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
202String8 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
214Vector<Sensor> SensorService::getSensorList()
215{
216    return mSensorList;
217}
218
219sp<ISensorEventConnection> SensorService::createSensorEventConnection()
220{
221    sp<SensorEventConnection> result(new SensorEventConnection(this));
222    return result;
223}
224
225void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
226{
227    Mutex::Autolock _l(mLock);
228    size_t size = mActiveSensors.size();
229    for (size_t i=0 ; i<size ; ) {
230        SensorRecord* rec = mActiveSensors.valueAt(i);
231        if (rec && rec->removeConnection(connection)) {
232            mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
233            mActiveSensors.removeItemsAt(i, 1);
234            delete rec;
235            size--;
236        } else {
237            i++;
238        }
239    }
240    mActiveConnections.remove(connection);
241}
242
243status_t SensorService::enable(const sp<SensorEventConnection>& connection,
244        int handle)
245{
246    if (mInitCheck != NO_ERROR)
247        return mInitCheck;
248
249    status_t err = NO_ERROR;
250    Mutex::Autolock _l(mLock);
251    SensorRecord* rec = mActiveSensors.valueFor(handle);
252    if (rec == 0) {
253        rec = new SensorRecord(connection);
254        mActiveSensors.add(handle, rec);
255        err = mSensorDevice->activate(mSensorDevice, handle, 1);
256        LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
257        if (err == 0) {
258            BatteryService::getInstance().enableSensor(handle);
259        }
260    } else {
261        rec->addConnection(connection);
262    }
263    if (err == NO_ERROR) {
264        // connection now active
265        if (connection->addSensor(handle)) {
266            // the sensor was added (which means it wasn't already there)
267            // so, see if this connection becomes active
268            if (mActiveConnections.indexOf(connection) < 0) {
269                mActiveConnections.add(connection);
270            }
271            // this could change the sensor event delivery speed
272            recomputeEventsPeriodLocked(handle);
273        }
274    }
275    return err;
276}
277
278status_t SensorService::disable(const sp<SensorEventConnection>& connection,
279        int handle)
280{
281    if (mInitCheck != NO_ERROR)
282        return mInitCheck;
283
284    status_t err = NO_ERROR;
285    Mutex::Autolock _l(mLock);
286    SensorRecord* rec = mActiveSensors.valueFor(handle);
287    if (rec) {
288        // see if this connection becomes inactive
289        connection->removeSensor(handle);
290        if (connection->hasAnySensor() == false) {
291            mActiveConnections.remove(connection);
292        }
293        // see if this sensor becomes inactive
294        if (rec->removeConnection(connection)) {
295            mActiveSensors.removeItem(handle);
296            delete rec;
297            err = mSensorDevice->activate(mSensorDevice, handle, 0);
298            if (err == 0) {
299                BatteryService::getInstance().disableSensor(handle);
300            }
301        }
302    }
303    if (err == NO_ERROR) {
304        recomputeEventsPeriodLocked(handle);
305    }
306    return err;
307}
308
309status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
310        int handle, nsecs_t ns)
311{
312    if (mInitCheck != NO_ERROR)
313        return mInitCheck;
314
315    if (ns < 0)
316        return BAD_VALUE;
317
318    if (ns < MINIMUM_EVENTS_PERIOD)
319        ns = MINIMUM_EVENTS_PERIOD;
320
321    Mutex::Autolock _l(mLock);
322    status_t err = connection->setEventRateLocked(handle, ns);
323    if (err == NO_ERROR) {
324        recomputeEventsPeriodLocked(handle);
325    }
326    return err;
327}
328
329status_t SensorService::recomputeEventsPeriodLocked(int32_t handle)
330{
331    status_t err = NO_ERROR;
332    nsecs_t wanted = ms2ns(1000);
333    size_t count = mActiveConnections.size();
334    for (size_t i=0 ; i<count ; i++) {
335        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
336        if (connection != NULL) {
337            nsecs_t ns = connection->getEventRateForSensor(handle);
338            if (ns) {
339                wanted = wanted < ns ? wanted : ns;
340            }
341        }
342    }
343    err = mSensorDevice->setDelay(mSensorDevice, handle, wanted);
344    return err;
345}
346
347// ---------------------------------------------------------------------------
348
349SensorService::SensorRecord::SensorRecord(
350        const sp<SensorEventConnection>& connection)
351{
352    mConnections.add(connection);
353}
354
355bool SensorService::SensorRecord::addConnection(
356        const sp<SensorEventConnection>& connection)
357{
358    if (mConnections.indexOf(connection) < 0) {
359        mConnections.add(connection);
360        return true;
361    }
362    return false;
363}
364
365bool SensorService::SensorRecord::removeConnection(
366        const wp<SensorEventConnection>& connection)
367{
368    ssize_t index = mConnections.indexOf(connection);
369    if (index >= 0) {
370        mConnections.removeItemsAt(index, 1);
371    }
372    return mConnections.size() ? false : true;
373}
374
375// ---------------------------------------------------------------------------
376
377SensorService::SensorEventConnection::SensorEventConnection(
378        const sp<SensorService>& service)
379    : mService(service), mChannel(new SensorChannel())
380{
381}
382
383SensorService::SensorEventConnection::~SensorEventConnection()
384{
385    mService->cleanupConnection(this);
386}
387
388void SensorService::SensorEventConnection::onFirstRef()
389{
390}
391
392bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
393    if (mSensorInfo.indexOfKey(handle) <= 0) {
394        SensorInfo info;
395        mSensorInfo.add(handle, info);
396        return true;
397    }
398    return false;
399}
400
401bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
402    if (mSensorInfo.removeItem(handle) >= 0) {
403        return true;
404    }
405    return false;
406}
407
408bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
409    return mSensorInfo.indexOfKey(handle) >= 0;
410}
411
412bool SensorService::SensorEventConnection::hasAnySensor() const {
413    return mSensorInfo.size() ? true : false;
414}
415
416status_t SensorService::SensorEventConnection::setEventRateLocked(
417        int handle, nsecs_t ns)
418{
419    ssize_t index = mSensorInfo.indexOfKey(handle);
420    if (index >= 0) {
421        SensorInfo& info = mSensorInfo.editValueFor(handle);
422        info.ns = ns;
423        return NO_ERROR;
424    }
425    return status_t(index);
426}
427
428status_t SensorService::SensorEventConnection::sendEvents(
429        sensors_event_t const* buffer, size_t numEvents,
430        sensors_event_t* scratch)
431{
432    // filter out events not for this connection
433    size_t count=0, i=0;
434    while (i<numEvents) {
435        const int32_t curr = buffer[i].sensor;
436        if (mSensorInfo.indexOfKey(curr) >= 0) {
437            do {
438                scratch[count++] = buffer[i++];
439            } while ((i<numEvents) && (buffer[i].sensor == curr));
440        } else {
441            i++;
442        }
443    }
444
445    ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
446    if (size == -EAGAIN) {
447        // the destination doesn't accept events anymore, it's probably
448        // full. For now, we just drop the events on the floor.
449        LOGW("dropping %d events on the floor", count);
450        return size;
451    }
452
453    LOGE_IF(size<0, "dropping %d events on the floor (%s)",
454            count, strerror(-size));
455
456    return size < 0 ? size : NO_ERROR;
457}
458
459sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
460{
461    return mChannel;
462}
463
464status_t SensorService::SensorEventConnection::enableDisable(
465        int handle, bool enabled)
466{
467    status_t err;
468    if (enabled) {
469        err = mService->enable(this, handle);
470    } else {
471        err = mService->disable(this, handle);
472    }
473    return err;
474}
475
476status_t SensorService::SensorEventConnection::setEventRate(
477        int handle, nsecs_t ns)
478{
479    return mService->setEventRate(this, handle, ns);
480}
481
482// ---------------------------------------------------------------------------
483}; // namespace android
484
485