SensorService.cpp revision cdd7d8bc145bbbd21a1689ed87a381287aeec229
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#include <binder/PermissionCache.h>
35
36#include <gui/ISensorServer.h>
37#include <gui/ISensorEventConnection.h>
38#include <gui/SensorEventQueue.h>
39
40#include <hardware/sensors.h>
41#include <hardware_legacy/power.h>
42
43#include "BatteryService.h"
44#include "CorrectedGyroSensor.h"
45#include "GravitySensor.h"
46#include "LinearAccelerationSensor.h"
47#include "OrientationSensor.h"
48#include "RotationVectorSensor.h"
49#include "SensorFusion.h"
50#include "SensorService.h"
51
52namespace android {
53// ---------------------------------------------------------------------------
54
55/*
56 * Notes:
57 *
58 * - what about a gyro-corrected magnetic-field sensor?
59 * - run mag sensor from time to time to force calibration
60 * - gravity sensor length is wrong (=> drift in linear-acc sensor)
61 *
62 */
63
64const char* SensorService::WAKE_LOCK_NAME = "SensorService";
65
66SensorService::SensorService()
67    : mInitCheck(NO_INIT)
68{
69}
70
71void SensorService::onFirstRef()
72{
73    ALOGD("nuSensorService starting...");
74
75    SensorDevice& dev(SensorDevice::getInstance());
76
77    if (dev.initCheck() == NO_ERROR) {
78        sensor_t const* list;
79        ssize_t count = dev.getSensorList(&list);
80        if (count > 0) {
81            ssize_t orientationIndex = -1;
82            bool hasGyro = false;
83            uint32_t virtualSensorsNeeds =
84                    (1<<SENSOR_TYPE_GRAVITY) |
85                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
86                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
87
88            mLastEventSeen.setCapacity(count);
89            for (ssize_t i=0 ; i<count ; i++) {
90                registerSensor( new HardwareSensor(list[i]) );
91                switch (list[i].type) {
92                    case SENSOR_TYPE_ORIENTATION:
93                        orientationIndex = i;
94                        break;
95                    case SENSOR_TYPE_GYROSCOPE:
96                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
97                        hasGyro = true;
98                        break;
99                    case SENSOR_TYPE_GRAVITY:
100                    case SENSOR_TYPE_LINEAR_ACCELERATION:
101                    case SENSOR_TYPE_ROTATION_VECTOR:
102                        virtualSensorsNeeds &= ~(1<<list[i].type);
103                        break;
104                }
105            }
106
107            // it's safe to instantiate the SensorFusion object here
108            // (it wants to be instantiated after h/w sensors have been
109            // registered)
110            const SensorFusion& fusion(SensorFusion::getInstance());
111
112            // build the sensor list returned to users
113            mUserSensorList = mSensorList;
114
115            if (hasGyro) {
116                Sensor aSensor;
117
118                // Add Android virtual sensors if they're not already
119                // available in the HAL
120
121                aSensor = registerVirtualSensor( new RotationVectorSensor() );
122                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
123                    mUserSensorList.add(aSensor);
124                }
125
126                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
127                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
128                    mUserSensorList.add(aSensor);
129                }
130
131                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
132                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
133                    mUserSensorList.add(aSensor);
134                }
135
136                aSensor = registerVirtualSensor( new OrientationSensor() );
137                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
138                    // if we are doing our own rotation-vector, also add
139                    // the orientation sensor and remove the HAL provided one.
140                    mUserSensorList.replaceAt(aSensor, orientationIndex);
141                }
142
143                // virtual debugging sensors are not added to mUserSensorList
144                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
145                registerVirtualSensor( new GyroDriftSensor() );
146            }
147
148            // debugging sensor list
149            mUserSensorListDebug = mSensorList;
150
151            run("SensorService", PRIORITY_URGENT_DISPLAY);
152            mInitCheck = NO_ERROR;
153        }
154    }
155}
156
157Sensor SensorService::registerSensor(SensorInterface* s)
158{
159    sensors_event_t event;
160    memset(&event, 0, sizeof(event));
161
162    const Sensor sensor(s->getSensor());
163    // add to the sensor list (returned to clients)
164    mSensorList.add(sensor);
165    // add to our handle->SensorInterface mapping
166    mSensorMap.add(sensor.getHandle(), s);
167    // create an entry in the mLastEventSeen array
168    mLastEventSeen.add(sensor.getHandle(), event);
169
170    return sensor;
171}
172
173Sensor SensorService::registerVirtualSensor(SensorInterface* s)
174{
175    Sensor sensor = registerSensor(s);
176    mVirtualSensorList.add( s );
177    return sensor;
178}
179
180SensorService::~SensorService()
181{
182    for (size_t i=0 ; i<mSensorMap.size() ; i++)
183        delete mSensorMap.valueAt(i);
184}
185
186static const String16 sDump("android.permission.DUMP");
187
188status_t SensorService::dump(int fd, const Vector<String16>& args)
189{
190    String8 result;
191    if (!PermissionCache::checkCallingPermission(sDump)) {
192        result.appendFormat("Permission Denial: "
193                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
194                IPCThreadState::self()->getCallingPid(),
195                IPCThreadState::self()->getCallingUid());
196    } else {
197        Mutex::Autolock _l(mLock);
198        result.append("Sensor List:\n");
199        for (size_t i=0 ; i<mSensorList.size() ; i++) {
200            const Sensor& s(mSensorList[i]);
201            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
202            result.appendFormat(
203                    "%-48s| %-32s | 0x%08x | ",
204                    s.getName().string(),
205                    s.getVendor().string(),
206                    s.getHandle());
207
208            if (s.getMinDelay() > 0) {
209                result.appendFormat(
210                    "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
211            } else {
212                result.append(s.getMinDelay() == 0
213                        ? "on-demand         | "
214                        : "one-shot          | ");
215            }
216
217            switch (s.getType()) {
218                case SENSOR_TYPE_ROTATION_VECTOR:
219                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
220                    result.appendFormat(
221                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
222                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
223                    break;
224                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
225                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
226                    result.appendFormat(
227                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
228                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
229                    break;
230                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
231                    result.appendFormat(
232                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
233                            e.data[0], e.data[1], e.data[2], e.data[3]);
234                    break;
235                case SENSOR_TYPE_SIGNIFICANT_MOTION:
236                case SENSOR_TYPE_STEP_DETECTOR:
237                    result.appendFormat( "last=<%f>\n", e.data[0]);
238                    break;
239                case SENSOR_TYPE_STEP_COUNTER:
240                    result.appendFormat( "last=<%llu>\n", e.u64.step_counter);
241                    break;
242                default:
243                    // default to 3 values
244                    result.appendFormat(
245                            "last=<%5.1f,%5.1f,%5.1f>\n",
246                            e.data[0], e.data[1], e.data[2]);
247                    break;
248            }
249        }
250        SensorFusion::getInstance().dump(result);
251        SensorDevice::getInstance().dump(result);
252
253        result.appendFormat("%d active connections\n", mActiveConnections.size());
254        result.append("Active sensors:\n");
255        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
256            int handle = mActiveSensors.keyAt(i);
257            result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
258                    getSensorName(handle).string(),
259                    handle,
260                    mActiveSensors.valueAt(i)->getNumConnections());
261        }
262    }
263    write(fd, result.string(), result.size());
264    return NO_ERROR;
265}
266
267void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
268        sensors_event_t const* buffer, const int count) {
269    SensorInterface* sensor;
270    status_t err = NO_ERROR;
271    for (int i=0 ; i<count ; i++) {
272        int handle = buffer[i].sensor;
273        int type = buffer[i].type;
274        if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
275            if (connection->hasSensor(handle)) {
276                sensor = mSensorMap.valueFor(handle);
277                if (sensor != NULL) {
278                    sensor->autoDisable(connection.get(), handle);
279                }
280                cleanupWithoutDisable(connection, handle);
281            }
282        }
283    }
284}
285
286bool SensorService::threadLoop()
287{
288    ALOGD("nuSensorService thread starting...");
289
290    const size_t numEventMax = 16;
291    const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
292    sensors_event_t buffer[minBufferSize];
293    sensors_event_t scratch[minBufferSize];
294    SensorDevice& device(SensorDevice::getInstance());
295    const size_t vcount = mVirtualSensorList.size();
296
297    ssize_t count;
298    bool wakeLockAcquired = false;
299    const int halVersion = device.getHalDeviceVersion();
300    do {
301        count = device.poll(buffer, numEventMax);
302        if (count<0) {
303            ALOGE("sensor poll failed (%s)", strerror(-count));
304            break;
305        }
306
307        // Poll has returned. Hold a wakelock.
308        // Todo(): add a flag to the sensors definitions to indicate
309        // the sensors which can wake up the AP
310        for (int i = 0; i < count; i++) {
311            if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
312                 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
313                 wakeLockAcquired = true;
314                 break;
315            }
316        }
317
318        recordLastValue(buffer, count);
319
320        // handle virtual sensors
321        if (count && vcount) {
322            sensors_event_t const * const event = buffer;
323            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
324                    getActiveVirtualSensors());
325            const size_t activeVirtualSensorCount = virtualSensors.size();
326            if (activeVirtualSensorCount) {
327                size_t k = 0;
328                SensorFusion& fusion(SensorFusion::getInstance());
329                if (fusion.isEnabled()) {
330                    for (size_t i=0 ; i<size_t(count) ; i++) {
331                        fusion.process(event[i]);
332                    }
333                }
334                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
335                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
336                        if (count + k >= minBufferSize) {
337                            ALOGE("buffer too small to hold all events: "
338                                    "count=%u, k=%u, size=%u",
339                                    count, k, minBufferSize);
340                            break;
341                        }
342                        sensors_event_t out;
343                        SensorInterface* si = virtualSensors.valueAt(j);
344                        if (si->process(&out, event[i])) {
345                            buffer[count + k] = out;
346                            k++;
347                        }
348                    }
349                }
350                if (k) {
351                    // record the last synthesized values
352                    recordLastValue(&buffer[count], k);
353                    count += k;
354                    // sort the buffer by time-stamps
355                    sortEventBuffer(buffer, count);
356                }
357            }
358        }
359
360        // handle backward compatibility for RotationVector sensor
361        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
362            for (int i = 0; i < count; i++) {
363                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
364                    // All the 4 components of the quaternion should be available
365                    // No heading accuracy. Set it to -1
366                    buffer[i].data[4] = -1;
367                }
368            }
369        }
370
371        // send our events to clients...
372        const SortedVector< wp<SensorEventConnection> > activeConnections(
373                getActiveConnections());
374        size_t numConnections = activeConnections.size();
375        for (size_t i=0 ; i<numConnections ; i++) {
376            sp<SensorEventConnection> connection(
377                    activeConnections[i].promote());
378            if (connection != 0) {
379                connection->sendEvents(buffer, count, scratch);
380                // Some sensors need to be auto disabled after the trigger
381                cleanupAutoDisabledSensor(connection, buffer, count);
382            }
383        }
384
385        // We have read the data, upper layers should hold the wakelock.
386        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
387
388    } while (count >= 0 || Thread::exitPending());
389
390    ALOGW("Exiting SensorService::threadLoop => aborting...");
391    abort();
392    return false;
393}
394
395void SensorService::recordLastValue(
396        sensors_event_t const * buffer, size_t count)
397{
398    Mutex::Autolock _l(mLock);
399
400    // record the last event for each sensor
401    int32_t prev = buffer[0].sensor;
402    for (size_t i=1 ; i<count ; i++) {
403        // record the last event of each sensor type in this buffer
404        int32_t curr = buffer[i].sensor;
405        if (curr != prev) {
406            mLastEventSeen.editValueFor(prev) = buffer[i-1];
407            prev = curr;
408        }
409    }
410    mLastEventSeen.editValueFor(prev) = buffer[count-1];
411}
412
413void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
414{
415    struct compar {
416        static int cmp(void const* lhs, void const* rhs) {
417            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
418            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
419            return l->timestamp - r->timestamp;
420        }
421    };
422    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
423}
424
425SortedVector< wp<SensorService::SensorEventConnection> >
426SensorService::getActiveConnections() const
427{
428    Mutex::Autolock _l(mLock);
429    return mActiveConnections;
430}
431
432DefaultKeyedVector<int, SensorInterface*>
433SensorService::getActiveVirtualSensors() const
434{
435    Mutex::Autolock _l(mLock);
436    return mActiveVirtualSensors;
437}
438
439String8 SensorService::getSensorName(int handle) const {
440    size_t count = mUserSensorList.size();
441    for (size_t i=0 ; i<count ; i++) {
442        const Sensor& sensor(mUserSensorList[i]);
443        if (sensor.getHandle() == handle) {
444            return sensor.getName();
445        }
446    }
447    String8 result("unknown");
448    return result;
449}
450
451Vector<Sensor> SensorService::getSensorList()
452{
453    char value[PROPERTY_VALUE_MAX];
454    property_get("debug.sensors", value, "0");
455    if (atoi(value)) {
456        return mUserSensorListDebug;
457    }
458    return mUserSensorList;
459}
460
461sp<ISensorEventConnection> SensorService::createSensorEventConnection()
462{
463    uid_t uid = IPCThreadState::self()->getCallingUid();
464    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
465    return result;
466}
467
468void SensorService::cleanupConnection(SensorEventConnection* c)
469{
470    Mutex::Autolock _l(mLock);
471    const wp<SensorEventConnection> connection(c);
472    size_t size = mActiveSensors.size();
473    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
474    for (size_t i=0 ; i<size ; ) {
475        int handle = mActiveSensors.keyAt(i);
476        if (c->hasSensor(handle)) {
477            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
478            SensorInterface* sensor = mSensorMap.valueFor( handle );
479            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
480            if (sensor) {
481                sensor->activate(c, false);
482            }
483        }
484        SensorRecord* rec = mActiveSensors.valueAt(i);
485        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
486        ALOGD_IF(DEBUG_CONNECTIONS,
487                "removing connection %p for sensor[%d].handle=0x%08x",
488                c, i, handle);
489
490        if (rec && rec->removeConnection(connection)) {
491            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
492            mActiveSensors.removeItemsAt(i, 1);
493            mActiveVirtualSensors.removeItem(handle);
494            delete rec;
495            size--;
496        } else {
497            i++;
498        }
499    }
500    mActiveConnections.remove(connection);
501    BatteryService::cleanup(c->getUid());
502}
503
504status_t SensorService::enable(const sp<SensorEventConnection>& connection,
505        int handle)
506{
507    if (mInitCheck != NO_ERROR)
508        return mInitCheck;
509
510    SensorInterface* sensor = mSensorMap.valueFor(handle);
511    if (sensor == NULL) {
512        return BAD_VALUE;
513    }
514
515    Mutex::Autolock _l(mLock);
516    SensorRecord* rec = mActiveSensors.valueFor(handle);
517    if (rec == 0) {
518        rec = new SensorRecord(connection);
519        mActiveSensors.add(handle, rec);
520        if (sensor->isVirtual()) {
521            mActiveVirtualSensors.add(handle, sensor);
522        }
523    } else {
524        if (rec->addConnection(connection)) {
525            // this sensor is already activated, but we are adding a
526            // connection that uses it. Immediately send down the last
527            // known value of the requested sensor if it's not a
528            // "continuous" sensor.
529            if (sensor->getSensor().getMinDelay() == 0) {
530                sensors_event_t scratch;
531                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
532                if (event.version == sizeof(sensors_event_t)) {
533                    connection->sendEvents(&event, 1);
534                }
535            }
536        }
537    }
538
539    if (connection->addSensor(handle)) {
540        BatteryService::enableSensor(connection->getUid(), handle);
541        // the sensor was added (which means it wasn't already there)
542        // so, see if this connection becomes active
543        if (mActiveConnections.indexOf(connection) < 0) {
544            mActiveConnections.add(connection);
545        }
546    } else {
547        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
548            handle, connection.get());
549    }
550
551    // we are setup, now enable the sensor.
552    status_t err = sensor->activate(connection.get(), true);
553    if (err != NO_ERROR) {
554        // enable has failed, reset our state.
555        cleanupWithoutDisableLocked(connection, handle);
556    }
557    return err;
558}
559
560status_t SensorService::disable(const sp<SensorEventConnection>& connection,
561        int handle)
562{
563    if (mInitCheck != NO_ERROR)
564        return mInitCheck;
565
566    Mutex::Autolock _l(mLock);
567    status_t err = cleanupWithoutDisableLocked(connection, handle);
568    if (err == NO_ERROR) {
569        SensorInterface* sensor = mSensorMap.valueFor(handle);
570        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
571    }
572    return err;
573}
574
575status_t SensorService::cleanupWithoutDisable(
576        const sp<SensorEventConnection>& connection, int handle) {
577    Mutex::Autolock _l(mLock);
578    return cleanupWithoutDisableLocked(connection, handle);
579}
580
581status_t SensorService::cleanupWithoutDisableLocked(
582        const sp<SensorEventConnection>& connection, int handle) {
583    SensorRecord* rec = mActiveSensors.valueFor(handle);
584    if (rec) {
585        // see if this connection becomes inactive
586        if (connection->removeSensor(handle)) {
587            BatteryService::disableSensor(connection->getUid(), handle);
588        }
589        if (connection->hasAnySensor() == false) {
590            mActiveConnections.remove(connection);
591        }
592        // see if this sensor becomes inactive
593        if (rec->removeConnection(connection)) {
594            mActiveSensors.removeItem(handle);
595            mActiveVirtualSensors.removeItem(handle);
596            delete rec;
597        }
598        return NO_ERROR;
599    }
600    return BAD_VALUE;
601}
602
603status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
604        int handle, nsecs_t ns)
605{
606    if (mInitCheck != NO_ERROR)
607        return mInitCheck;
608
609    SensorInterface* sensor = mSensorMap.valueFor(handle);
610    if (!sensor)
611        return BAD_VALUE;
612
613    if (ns < 0)
614        return BAD_VALUE;
615
616    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
617    if (ns < minDelayNs) {
618        ns = minDelayNs;
619    }
620
621    if (ns < MINIMUM_EVENTS_PERIOD)
622        ns = MINIMUM_EVENTS_PERIOD;
623
624    return sensor->setDelay(connection.get(), handle, ns);
625}
626
627// ---------------------------------------------------------------------------
628
629SensorService::SensorRecord::SensorRecord(
630        const sp<SensorEventConnection>& connection)
631{
632    mConnections.add(connection);
633}
634
635bool SensorService::SensorRecord::addConnection(
636        const sp<SensorEventConnection>& connection)
637{
638    if (mConnections.indexOf(connection) < 0) {
639        mConnections.add(connection);
640        return true;
641    }
642    return false;
643}
644
645bool SensorService::SensorRecord::removeConnection(
646        const wp<SensorEventConnection>& connection)
647{
648    ssize_t index = mConnections.indexOf(connection);
649    if (index >= 0) {
650        mConnections.removeItemsAt(index, 1);
651    }
652    return mConnections.size() ? false : true;
653}
654
655// ---------------------------------------------------------------------------
656
657SensorService::SensorEventConnection::SensorEventConnection(
658        const sp<SensorService>& service, uid_t uid)
659    : mService(service), mChannel(new BitTube()), mUid(uid)
660{
661}
662
663SensorService::SensorEventConnection::~SensorEventConnection()
664{
665    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
666    mService->cleanupConnection(this);
667}
668
669void SensorService::SensorEventConnection::onFirstRef()
670{
671}
672
673bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
674    Mutex::Autolock _l(mConnectionLock);
675    if (mSensorInfo.indexOf(handle) < 0) {
676        mSensorInfo.add(handle);
677        return true;
678    }
679    return false;
680}
681
682bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
683    Mutex::Autolock _l(mConnectionLock);
684    if (mSensorInfo.remove(handle) >= 0) {
685        return true;
686    }
687    return false;
688}
689
690bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
691    Mutex::Autolock _l(mConnectionLock);
692    return mSensorInfo.indexOf(handle) >= 0;
693}
694
695bool SensorService::SensorEventConnection::hasAnySensor() const {
696    Mutex::Autolock _l(mConnectionLock);
697    return mSensorInfo.size() ? true : false;
698}
699
700status_t SensorService::SensorEventConnection::sendEvents(
701        sensors_event_t const* buffer, size_t numEvents,
702        sensors_event_t* scratch)
703{
704    // filter out events not for this connection
705    size_t count = 0;
706    if (scratch) {
707        Mutex::Autolock _l(mConnectionLock);
708        size_t i=0;
709        while (i<numEvents) {
710            const int32_t curr = buffer[i].sensor;
711            if (mSensorInfo.indexOf(curr) >= 0) {
712                do {
713                    scratch[count++] = buffer[i++];
714                } while ((i<numEvents) && (buffer[i].sensor == curr));
715            } else {
716                i++;
717            }
718        }
719    } else {
720        scratch = const_cast<sensors_event_t *>(buffer);
721        count = numEvents;
722    }
723
724    // NOTE: ASensorEvent and sensors_event_t are the same type
725    ssize_t size = SensorEventQueue::write(mChannel,
726            reinterpret_cast<ASensorEvent const*>(scratch), count);
727    if (size == -EAGAIN) {
728        // the destination doesn't accept events anymore, it's probably
729        // full. For now, we just drop the events on the floor.
730        //ALOGW("dropping %d events on the floor", count);
731        return size;
732    }
733
734    return size < 0 ? status_t(size) : status_t(NO_ERROR);
735}
736
737sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
738{
739    return mChannel;
740}
741
742status_t SensorService::SensorEventConnection::enableDisable(
743        int handle, bool enabled)
744{
745    status_t err;
746    if (enabled) {
747        err = mService->enable(this, handle);
748    } else {
749        err = mService->disable(this, handle);
750    }
751    return err;
752}
753
754status_t SensorService::SensorEventConnection::setEventRate(
755        int handle, nsecs_t ns)
756{
757    return mService->setEventRate(this, handle, ns);
758}
759
760// ---------------------------------------------------------------------------
761}; // namespace android
762
763