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