SensorService.cpp revision 3301542828febc768e1df42892cfac4992c35474
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 <math.h>
19#include <sys/types.h>
20
21#include <cutils/properties.h>
22
23#include <utils/SortedVector.h>
24#include <utils/KeyedVector.h>
25#include <utils/threads.h>
26#include <utils/Atomic.h>
27#include <utils/Errors.h>
28#include <utils/RefBase.h>
29#include <utils/Singleton.h>
30#include <utils/String16.h>
31
32#include <binder/BinderService.h>
33#include <binder/IServiceManager.h>
34
35#include <gui/ISensorServer.h>
36#include <gui/ISensorEventConnection.h>
37
38#include <hardware/sensors.h>
39
40#include "CorrectedGyroSensor.h"
41#include "GravitySensor.h"
42#include "LinearAccelerationSensor.h"
43#include "OrientationSensor.h"
44#include "RotationVectorSensor.h"
45#include "SensorFusion.h"
46#include "SensorService.h"
47
48namespace android {
49// ---------------------------------------------------------------------------
50
51/*
52 * Notes:
53 *
54 * - what about a gyro-corrected magnetic-field sensor?
55 * - option to "hide" the HAL sensors
56 * - run mag sensor from time to time to force calibration
57 * - gravity sensor length is wrong (=> drift in linear-acc sensor)
58 *
59 */
60
61SensorService::SensorService()
62    : mDump("android.permission.DUMP"),
63      mInitCheck(NO_INIT)
64{
65}
66
67void SensorService::onFirstRef()
68{
69    LOGD("nuSensorService starting...");
70
71    SensorDevice& dev(SensorDevice::getInstance());
72
73    if (dev.initCheck() == NO_ERROR) {
74        bool hasGyro = false;
75        uint32_t virtualSensorsNeeds =
76                (1<<SENSOR_TYPE_GRAVITY) |
77                (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
78                (1<<SENSOR_TYPE_ROTATION_VECTOR);
79        sensor_t const* list;
80        int count = dev.getSensorList(&list);
81        mLastEventSeen.setCapacity(count);
82        for (int i=0 ; i<count ; i++) {
83            registerSensor( new HardwareSensor(list[i]) );
84            switch (list[i].type) {
85                case SENSOR_TYPE_GYROSCOPE:
86                    hasGyro = true;
87                    break;
88                case SENSOR_TYPE_GRAVITY:
89                case SENSOR_TYPE_LINEAR_ACCELERATION:
90                case SENSOR_TYPE_ROTATION_VECTOR:
91                    virtualSensorsNeeds &= ~(1<<list[i].type);
92                    break;
93            }
94        }
95
96        // it's safe to instantiate the SensorFusion object here
97        // (it wants to be instantiated after h/w sensors have been
98        // registered)
99        const SensorFusion& fusion(SensorFusion::getInstance());
100
101        if (hasGyro) {
102            // Always instantiate Android's virtual sensors. Since they are
103            // instantiated behind sensors from the HAL, they won't
104            // interfere with applications, unless they looks specifically
105            // for them (by name).
106
107            registerVirtualSensor( new RotationVectorSensor() );
108            registerVirtualSensor( new GravitySensor(list, count) );
109            registerVirtualSensor( new LinearAccelerationSensor(list, count) );
110
111            // these are optional
112            registerVirtualSensor( new OrientationSensor() );
113            registerVirtualSensor( new CorrectedGyroSensor(list, count) );
114
115            // virtual debugging sensors...
116            char value[PROPERTY_VALUE_MAX];
117            property_get("debug.sensors", value, "0");
118            if (atoi(value)) {
119                registerVirtualSensor( new GyroDriftSensor() );
120            }
121        }
122
123        run("SensorService", PRIORITY_URGENT_DISPLAY);
124        mInitCheck = NO_ERROR;
125    }
126}
127
128void SensorService::registerSensor(SensorInterface* s)
129{
130    sensors_event_t event;
131    memset(&event, 0, sizeof(event));
132
133    const Sensor sensor(s->getSensor());
134    // add to the sensor list (returned to clients)
135    mSensorList.add(sensor);
136    // add to our handle->SensorInterface mapping
137    mSensorMap.add(sensor.getHandle(), s);
138    // create an entry in the mLastEventSeen array
139    mLastEventSeen.add(sensor.getHandle(), event);
140}
141
142void SensorService::registerVirtualSensor(SensorInterface* s)
143{
144    registerSensor(s);
145    mVirtualSensorList.add( s );
146}
147
148SensorService::~SensorService()
149{
150    for (size_t i=0 ; i<mSensorMap.size() ; i++)
151        delete mSensorMap.valueAt(i);
152}
153
154status_t SensorService::dump(int fd, const Vector<String16>& args)
155{
156    const size_t SIZE = 1024;
157    char buffer[SIZE];
158    String8 result;
159    if (!mDump.checkCalling()) {
160        snprintf(buffer, SIZE, "Permission Denial: "
161                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
162                IPCThreadState::self()->getCallingPid(),
163                IPCThreadState::self()->getCallingUid());
164        result.append(buffer);
165    } else {
166        Mutex::Autolock _l(mLock);
167        snprintf(buffer, SIZE, "Sensor List:\n");
168        result.append(buffer);
169        for (size_t i=0 ; i<mSensorList.size() ; i++) {
170            const Sensor& s(mSensorList[i]);
171            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
172            snprintf(buffer, SIZE,
173                    "%-48s| %-32s | 0x%08x | maxRate=%7.2fHz | "
174                    "last=<%5.1f,%5.1f,%5.1f>\n",
175                    s.getName().string(),
176                    s.getVendor().string(),
177                    s.getHandle(),
178                    s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f,
179                    e.data[0], e.data[1], e.data[2]);
180            result.append(buffer);
181        }
182        SensorFusion::getInstance().dump(result, buffer, SIZE);
183        SensorDevice::getInstance().dump(result, buffer, SIZE);
184
185        snprintf(buffer, SIZE, "%d active connections\n",
186                mActiveConnections.size());
187        result.append(buffer);
188        snprintf(buffer, SIZE, "Active sensors:\n");
189        result.append(buffer);
190        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
191            int handle = mActiveSensors.keyAt(i);
192            snprintf(buffer, SIZE, "%s (handle=0x%08x, connections=%d)\n",
193                    getSensorName(handle).string(),
194                    handle,
195                    mActiveSensors.valueAt(i)->getNumConnections());
196            result.append(buffer);
197        }
198    }
199    write(fd, result.string(), result.size());
200    return NO_ERROR;
201}
202
203bool SensorService::threadLoop()
204{
205    LOGD("nuSensorService thread starting...");
206
207    const size_t numEventMax = 16 * (1 + mVirtualSensorList.size());
208    sensors_event_t buffer[numEventMax];
209    sensors_event_t scratch[numEventMax];
210    SensorDevice& device(SensorDevice::getInstance());
211    const size_t vcount = mVirtualSensorList.size();
212
213    ssize_t count;
214    do {
215        count = device.poll(buffer, numEventMax);
216        if (count<0) {
217            LOGE("sensor poll failed (%s)", strerror(-count));
218            break;
219        }
220
221        recordLastValue(buffer, count);
222
223        // handle virtual sensors
224        if (count && vcount) {
225            sensors_event_t const * const event = buffer;
226            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
227                    getActiveVirtualSensors());
228            const size_t activeVirtualSensorCount = virtualSensors.size();
229            if (activeVirtualSensorCount) {
230                size_t k = 0;
231                SensorFusion& fusion(SensorFusion::getInstance());
232                if (fusion.isEnabled()) {
233                    for (size_t i=0 ; i<size_t(count) ; i++) {
234                        fusion.process(event[i]);
235                    }
236                }
237                for (size_t i=0 ; i<size_t(count) ; i++) {
238                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
239                        sensors_event_t out;
240                        if (virtualSensors.valueAt(j)->process(&out, event[i])) {
241                            buffer[count + k] = out;
242                            k++;
243                        }
244                    }
245                }
246                if (k) {
247                    // record the last synthesized values
248                    recordLastValue(&buffer[count], k);
249                    count += k;
250                    // sort the buffer by time-stamps
251                    sortEventBuffer(buffer, count);
252                }
253            }
254        }
255
256        // send our events to clients...
257        const SortedVector< wp<SensorEventConnection> > activeConnections(
258                getActiveConnections());
259        size_t numConnections = activeConnections.size();
260        for (size_t i=0 ; i<numConnections ; i++) {
261            sp<SensorEventConnection> connection(
262                    activeConnections[i].promote());
263            if (connection != 0) {
264                connection->sendEvents(buffer, count, scratch);
265            }
266        }
267    } while (count >= 0 || Thread::exitPending());
268
269    LOGW("Exiting SensorService::threadLoop!");
270    return false;
271}
272
273void SensorService::recordLastValue(
274        sensors_event_t const * buffer, size_t count)
275{
276    Mutex::Autolock _l(mLock);
277
278    // record the last event for each sensor
279    int32_t prev = buffer[0].sensor;
280    for (size_t i=1 ; i<count ; i++) {
281        // record the last event of each sensor type in this buffer
282        int32_t curr = buffer[i].sensor;
283        if (curr != prev) {
284            mLastEventSeen.editValueFor(prev) = buffer[i-1];
285            prev = curr;
286        }
287    }
288    mLastEventSeen.editValueFor(prev) = buffer[count-1];
289}
290
291void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
292{
293    struct compar {
294        static int cmp(void const* lhs, void const* rhs) {
295            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
296            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
297            return r->timestamp - l->timestamp;
298        }
299    };
300    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
301}
302
303SortedVector< wp<SensorService::SensorEventConnection> >
304SensorService::getActiveConnections() const
305{
306    Mutex::Autolock _l(mLock);
307    return mActiveConnections;
308}
309
310DefaultKeyedVector<int, SensorInterface*>
311SensorService::getActiveVirtualSensors() const
312{
313    Mutex::Autolock _l(mLock);
314    return mActiveVirtualSensors;
315}
316
317String8 SensorService::getSensorName(int handle) const {
318    size_t count = mSensorList.size();
319    for (size_t i=0 ; i<count ; i++) {
320        const Sensor& sensor(mSensorList[i]);
321        if (sensor.getHandle() == handle) {
322            return sensor.getName();
323        }
324    }
325    String8 result("unknown");
326    return result;
327}
328
329Vector<Sensor> SensorService::getSensorList()
330{
331    return mSensorList;
332}
333
334sp<ISensorEventConnection> SensorService::createSensorEventConnection()
335{
336    sp<SensorEventConnection> result(new SensorEventConnection(this));
337    return result;
338}
339
340void SensorService::cleanupConnection(SensorEventConnection* c)
341{
342    Mutex::Autolock _l(mLock);
343    const wp<SensorEventConnection> connection(c);
344    size_t size = mActiveSensors.size();
345    LOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
346    for (size_t i=0 ; i<size ; ) {
347        int handle = mActiveSensors.keyAt(i);
348        if (c->hasSensor(handle)) {
349            LOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
350            SensorInterface* sensor = mSensorMap.valueFor( handle );
351            LOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
352            if (sensor) {
353                sensor->activate(c, false);
354            }
355        }
356        SensorRecord* rec = mActiveSensors.valueAt(i);
357        LOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
358        LOGD_IF(DEBUG_CONNECTIONS,
359                "removing connection %p for sensor[%d].handle=0x%08x",
360                c, i, handle);
361
362        if (rec && rec->removeConnection(connection)) {
363            LOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
364            mActiveSensors.removeItemsAt(i, 1);
365            mActiveVirtualSensors.removeItem(handle);
366            delete rec;
367            size--;
368        } else {
369            i++;
370        }
371    }
372    mActiveConnections.remove(connection);
373}
374
375status_t SensorService::enable(const sp<SensorEventConnection>& connection,
376        int handle)
377{
378    if (mInitCheck != NO_ERROR)
379        return mInitCheck;
380
381    Mutex::Autolock _l(mLock);
382    SensorInterface* sensor = mSensorMap.valueFor(handle);
383    status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE);
384    if (err == NO_ERROR) {
385        SensorRecord* rec = mActiveSensors.valueFor(handle);
386        if (rec == 0) {
387            rec = new SensorRecord(connection);
388            mActiveSensors.add(handle, rec);
389            if (sensor->isVirtual()) {
390                mActiveVirtualSensors.add(handle, sensor);
391            }
392        } else {
393            if (rec->addConnection(connection)) {
394                // this sensor is already activated, but we are adding a
395                // connection that uses it. Immediately send down the last
396                // known value of the requested sensor if it's not a
397                // "continuous" sensor.
398                if (sensor->getSensor().getMinDelay() == 0) {
399                    sensors_event_t scratch;
400                    sensors_event_t& event(mLastEventSeen.editValueFor(handle));
401                    if (event.version == sizeof(sensors_event_t)) {
402                        connection->sendEvents(&event, 1);
403                    }
404                }
405            }
406        }
407        if (err == NO_ERROR) {
408            // connection now active
409            if (connection->addSensor(handle)) {
410                // the sensor was added (which means it wasn't already there)
411                // so, see if this connection becomes active
412                if (mActiveConnections.indexOf(connection) < 0) {
413                    mActiveConnections.add(connection);
414                }
415            }
416        }
417    }
418    return err;
419}
420
421status_t SensorService::disable(const sp<SensorEventConnection>& connection,
422        int handle)
423{
424    if (mInitCheck != NO_ERROR)
425        return mInitCheck;
426
427    status_t err = NO_ERROR;
428    Mutex::Autolock _l(mLock);
429    SensorRecord* rec = mActiveSensors.valueFor(handle);
430    if (rec) {
431        // see if this connection becomes inactive
432        connection->removeSensor(handle);
433        if (connection->hasAnySensor() == false) {
434            mActiveConnections.remove(connection);
435        }
436        // see if this sensor becomes inactive
437        if (rec->removeConnection(connection)) {
438            mActiveSensors.removeItem(handle);
439            mActiveVirtualSensors.removeItem(handle);
440            delete rec;
441        }
442        SensorInterface* sensor = mSensorMap.valueFor(handle);
443        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
444    }
445    return err;
446}
447
448status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
449        int handle, nsecs_t ns)
450{
451    if (mInitCheck != NO_ERROR)
452        return mInitCheck;
453
454    if (ns < 0)
455        return BAD_VALUE;
456
457    if (ns < MINIMUM_EVENTS_PERIOD)
458        ns = MINIMUM_EVENTS_PERIOD;
459
460    SensorInterface* sensor = mSensorMap.valueFor(handle);
461    if (!sensor) return BAD_VALUE;
462    return sensor->setDelay(connection.get(), handle, ns);
463}
464
465// ---------------------------------------------------------------------------
466
467SensorService::SensorRecord::SensorRecord(
468        const sp<SensorEventConnection>& connection)
469{
470    mConnections.add(connection);
471}
472
473bool SensorService::SensorRecord::addConnection(
474        const sp<SensorEventConnection>& connection)
475{
476    if (mConnections.indexOf(connection) < 0) {
477        mConnections.add(connection);
478        return true;
479    }
480    return false;
481}
482
483bool SensorService::SensorRecord::removeConnection(
484        const wp<SensorEventConnection>& connection)
485{
486    ssize_t index = mConnections.indexOf(connection);
487    if (index >= 0) {
488        mConnections.removeItemsAt(index, 1);
489    }
490    return mConnections.size() ? false : true;
491}
492
493// ---------------------------------------------------------------------------
494
495SensorService::SensorEventConnection::SensorEventConnection(
496        const sp<SensorService>& service)
497    : mService(service), mChannel(new SensorChannel())
498{
499}
500
501SensorService::SensorEventConnection::~SensorEventConnection()
502{
503    LOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
504    mService->cleanupConnection(this);
505}
506
507void SensorService::SensorEventConnection::onFirstRef()
508{
509}
510
511bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
512    Mutex::Autolock _l(mConnectionLock);
513    if (mSensorInfo.indexOf(handle) <= 0) {
514        mSensorInfo.add(handle);
515        return true;
516    }
517    return false;
518}
519
520bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
521    Mutex::Autolock _l(mConnectionLock);
522    if (mSensorInfo.remove(handle) >= 0) {
523        return true;
524    }
525    return false;
526}
527
528bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
529    Mutex::Autolock _l(mConnectionLock);
530    return mSensorInfo.indexOf(handle) >= 0;
531}
532
533bool SensorService::SensorEventConnection::hasAnySensor() const {
534    Mutex::Autolock _l(mConnectionLock);
535    return mSensorInfo.size() ? true : false;
536}
537
538status_t SensorService::SensorEventConnection::sendEvents(
539        sensors_event_t const* buffer, size_t numEvents,
540        sensors_event_t* scratch)
541{
542    // filter out events not for this connection
543    size_t count = 0;
544    if (scratch) {
545        Mutex::Autolock _l(mConnectionLock);
546        size_t i=0;
547        while (i<numEvents) {
548            const int32_t curr = buffer[i].sensor;
549            if (mSensorInfo.indexOf(curr) >= 0) {
550                do {
551                    scratch[count++] = buffer[i++];
552                } while ((i<numEvents) && (buffer[i].sensor == curr));
553            } else {
554                i++;
555            }
556        }
557    } else {
558        scratch = const_cast<sensors_event_t *>(buffer);
559        count = numEvents;
560    }
561
562    if (count == 0)
563        return 0;
564
565    ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
566    if (size == -EAGAIN) {
567        // the destination doesn't accept events anymore, it's probably
568        // full. For now, we just drop the events on the floor.
569        LOGW("dropping %d events on the floor", count);
570        return size;
571    }
572
573    LOGE_IF(size<0, "dropping %d events on the floor (%s)",
574            count, strerror(-size));
575
576    return size < 0 ? status_t(size) : status_t(NO_ERROR);
577}
578
579sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
580{
581    return mChannel;
582}
583
584status_t SensorService::SensorEventConnection::enableDisable(
585        int handle, bool enabled)
586{
587    status_t err;
588    if (enabled) {
589        err = mService->enable(this, handle);
590    } else {
591        err = mService->disable(this, handle);
592    }
593    return err;
594}
595
596status_t SensorService::SensorEventConnection::setEventRate(
597        int handle, nsecs_t ns)
598{
599    return mService->setEventRate(this, handle, ns);
600}
601
602// ---------------------------------------------------------------------------
603}; // namespace android
604
605