SensorService.cpp revision 0319306670b0344da99efa606b6f172dde575a39
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    const size_t SIZE = 1024;
191    char buffer[SIZE];
192    String8 result;
193    if (!PermissionCache::checkCallingPermission(sDump)) {
194        snprintf(buffer, SIZE, "Permission Denial: "
195                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
196                IPCThreadState::self()->getCallingPid(),
197                IPCThreadState::self()->getCallingUid());
198        result.append(buffer);
199    } else {
200        Mutex::Autolock _l(mLock);
201        snprintf(buffer, SIZE, "Sensor List:\n");
202        result.append(buffer);
203        for (size_t i=0 ; i<mSensorList.size() ; i++) {
204            const Sensor& s(mSensorList[i]);
205            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
206            snprintf(buffer, SIZE,
207                    "%-48s| %-32s | 0x%08x | maxRate=%7.2fHz | "
208                    "last=<%5.1f,%5.1f,%5.1f>\n",
209                    s.getName().string(),
210                    s.getVendor().string(),
211                    s.getHandle(),
212                    s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f,
213                    e.data[0], e.data[1], e.data[2]);
214            result.append(buffer);
215        }
216        SensorFusion::getInstance().dump(result, buffer, SIZE);
217        SensorDevice::getInstance().dump(result, buffer, SIZE);
218
219        snprintf(buffer, SIZE, "%d active connections\n",
220                mActiveConnections.size());
221        result.append(buffer);
222        snprintf(buffer, SIZE, "Active sensors:\n");
223        result.append(buffer);
224        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
225            int handle = mActiveSensors.keyAt(i);
226            snprintf(buffer, SIZE, "%s (handle=0x%08x, connections=%d)\n",
227                    getSensorName(handle).string(),
228                    handle,
229                    mActiveSensors.valueAt(i)->getNumConnections());
230            result.append(buffer);
231        }
232    }
233    write(fd, result.string(), result.size());
234    return NO_ERROR;
235}
236
237void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
238        sensors_event_t const* buffer, const int count) {
239    SensorInterface* sensor;
240    status_t err = NO_ERROR;
241    for (int i=0 ; i<count ; i++) {
242        int handle = buffer[i].sensor;
243        if (getSensorType(handle) == SENSOR_TYPE_SIGNIFICANT_MOTION) {
244            if (connection->hasSensor(handle)) {
245                sensor = mSensorMap.valueFor(handle);
246                err = sensor ?sensor->resetStateWithoutActuatingHardware(connection.get(), handle)
247                        : status_t(BAD_VALUE);
248                if (err != NO_ERROR) {
249                    ALOGE("Sensor Inteface: Resetting state failed with err: %d", err);
250                }
251                cleanupWithoutDisable(connection, handle);
252            }
253        }
254    }
255}
256
257bool SensorService::threadLoop()
258{
259    ALOGD("nuSensorService thread starting...");
260
261    const size_t numEventMax = 16;
262    const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
263    sensors_event_t buffer[minBufferSize];
264    sensors_event_t scratch[minBufferSize];
265    SensorDevice& device(SensorDevice::getInstance());
266    const size_t vcount = mVirtualSensorList.size();
267
268    ssize_t count;
269    bool wakeLockAcquired = false;
270    const int halVersion = device.getHalDeviceVersion();
271    do {
272        count = device.poll(buffer, numEventMax);
273        if (count<0) {
274            ALOGE("sensor poll failed (%s)", strerror(-count));
275            break;
276        }
277
278        // Poll has returned. Hold a wakelock.
279        // Todo(): add a flag to the sensors definitions to indicate
280        // the sensors which can wake up the AP
281        for (int i = 0; i < count; i++) {
282            if (getSensorType(buffer[i].sensor) == SENSOR_TYPE_SIGNIFICANT_MOTION) {
283                 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
284                 wakeLockAcquired = true;
285                 break;
286            }
287        }
288
289        recordLastValue(buffer, count);
290
291        // handle virtual sensors
292        if (count && vcount) {
293            sensors_event_t const * const event = buffer;
294            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
295                    getActiveVirtualSensors());
296            const size_t activeVirtualSensorCount = virtualSensors.size();
297            if (activeVirtualSensorCount) {
298                size_t k = 0;
299                SensorFusion& fusion(SensorFusion::getInstance());
300                if (fusion.isEnabled()) {
301                    for (size_t i=0 ; i<size_t(count) ; i++) {
302                        fusion.process(event[i]);
303                    }
304                }
305                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
306                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
307                        if (count + k >= minBufferSize) {
308                            ALOGE("buffer too small to hold all events: "
309                                    "count=%u, k=%u, size=%u",
310                                    count, k, minBufferSize);
311                            break;
312                        }
313                        sensors_event_t out;
314                        SensorInterface* si = virtualSensors.valueAt(j);
315                        if (si->process(&out, event[i])) {
316                            buffer[count + k] = out;
317                            k++;
318                        }
319                    }
320                }
321                if (k) {
322                    // record the last synthesized values
323                    recordLastValue(&buffer[count], k);
324                    count += k;
325                    // sort the buffer by time-stamps
326                    sortEventBuffer(buffer, count);
327                }
328            }
329        }
330
331        // handle backward compatibility for RotationVector sensor
332        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
333            for (int i = 0; i < count; i++) {
334                if (getSensorType(buffer[i].sensor) == SENSOR_TYPE_ROTATION_VECTOR) {
335                    // All the 4 components of the quaternion should be available
336                    // No heading accuracy. Set it to -1
337                    buffer[i].data[4] = -1;
338                }
339            }
340        }
341
342        // send our events to clients...
343        const SortedVector< wp<SensorEventConnection> > activeConnections(
344                getActiveConnections());
345        size_t numConnections = activeConnections.size();
346        for (size_t i=0 ; i<numConnections ; i++) {
347            sp<SensorEventConnection> connection(
348                    activeConnections[i].promote());
349            if (connection != 0) {
350                connection->sendEvents(buffer, count, scratch);
351                // Some sensors need to be auto disabled after the trigger
352                cleanupAutoDisabledSensor(connection, buffer, count);
353            }
354        }
355
356        // We have read the data, upper layers should hold the wakelock.
357        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
358
359    } while (count >= 0 || Thread::exitPending());
360
361    ALOGW("Exiting SensorService::threadLoop => aborting...");
362    abort();
363    return false;
364}
365
366void SensorService::recordLastValue(
367        sensors_event_t const * buffer, size_t count)
368{
369    Mutex::Autolock _l(mLock);
370
371    // record the last event for each sensor
372    int32_t prev = buffer[0].sensor;
373    for (size_t i=1 ; i<count ; i++) {
374        // record the last event of each sensor type in this buffer
375        int32_t curr = buffer[i].sensor;
376        if (curr != prev) {
377            mLastEventSeen.editValueFor(prev) = buffer[i-1];
378            prev = curr;
379        }
380    }
381    mLastEventSeen.editValueFor(prev) = buffer[count-1];
382}
383
384void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
385{
386    struct compar {
387        static int cmp(void const* lhs, void const* rhs) {
388            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
389            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
390            return l->timestamp - r->timestamp;
391        }
392    };
393    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
394}
395
396SortedVector< wp<SensorService::SensorEventConnection> >
397SensorService::getActiveConnections() const
398{
399    Mutex::Autolock _l(mLock);
400    return mActiveConnections;
401}
402
403DefaultKeyedVector<int, SensorInterface*>
404SensorService::getActiveVirtualSensors() const
405{
406    Mutex::Autolock _l(mLock);
407    return mActiveVirtualSensors;
408}
409
410String8 SensorService::getSensorName(int handle) const {
411    size_t count = mUserSensorList.size();
412    for (size_t i=0 ; i<count ; i++) {
413        const Sensor& sensor(mUserSensorList[i]);
414        if (sensor.getHandle() == handle) {
415            return sensor.getName();
416        }
417    }
418    String8 result("unknown");
419    return result;
420}
421
422int SensorService::getSensorType(int handle) const {
423    size_t count = mUserSensorList.size();
424    for (size_t i=0 ; i<count ; i++) {
425        const Sensor& sensor(mUserSensorList[i]);
426        if (sensor.getHandle() == handle) {
427            return sensor.getType();
428        }
429    }
430    return -1;
431}
432
433
434Vector<Sensor> SensorService::getSensorList()
435{
436    char value[PROPERTY_VALUE_MAX];
437    property_get("debug.sensors", value, "0");
438    if (atoi(value)) {
439        return mUserSensorListDebug;
440    }
441    return mUserSensorList;
442}
443
444sp<ISensorEventConnection> SensorService::createSensorEventConnection()
445{
446    uid_t uid = IPCThreadState::self()->getCallingUid();
447    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
448    return result;
449}
450
451void SensorService::cleanupConnection(SensorEventConnection* c)
452{
453    Mutex::Autolock _l(mLock);
454    const wp<SensorEventConnection> connection(c);
455    size_t size = mActiveSensors.size();
456    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
457    for (size_t i=0 ; i<size ; ) {
458        int handle = mActiveSensors.keyAt(i);
459        if (c->hasSensor(handle)) {
460            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
461            SensorInterface* sensor = mSensorMap.valueFor( handle );
462            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
463            if (sensor) {
464                sensor->activate(c, false);
465            }
466        }
467        SensorRecord* rec = mActiveSensors.valueAt(i);
468        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
469        ALOGD_IF(DEBUG_CONNECTIONS,
470                "removing connection %p for sensor[%d].handle=0x%08x",
471                c, i, handle);
472
473        if (rec && rec->removeConnection(connection)) {
474            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
475            mActiveSensors.removeItemsAt(i, 1);
476            mActiveVirtualSensors.removeItem(handle);
477            delete rec;
478            size--;
479        } else {
480            i++;
481        }
482    }
483    mActiveConnections.remove(connection);
484    BatteryService::cleanup(c->getUid());
485}
486
487status_t SensorService::enable(const sp<SensorEventConnection>& connection,
488        int handle)
489{
490    if (mInitCheck != NO_ERROR)
491        return mInitCheck;
492
493    Mutex::Autolock _l(mLock);
494    SensorInterface* sensor = mSensorMap.valueFor(handle);
495    SensorRecord* rec = mActiveSensors.valueFor(handle);
496    if (rec == 0) {
497        rec = new SensorRecord(connection);
498        mActiveSensors.add(handle, rec);
499        if (sensor->isVirtual()) {
500            mActiveVirtualSensors.add(handle, sensor);
501        }
502    } else {
503        if (rec->addConnection(connection)) {
504            // this sensor is already activated, but we are adding a
505            // connection that uses it. Immediately send down the last
506            // known value of the requested sensor if it's not a
507            // "continuous" sensor.
508            if (sensor->getSensor().getMinDelay() == 0) {
509                sensors_event_t scratch;
510                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
511                if (event.version == sizeof(sensors_event_t)) {
512                    connection->sendEvents(&event, 1);
513                }
514            }
515        }
516    }
517
518    if (connection->addSensor(handle)) {
519        BatteryService::enableSensor(connection->getUid(), handle);
520        // the sensor was added (which means it wasn't already there)
521        // so, see if this connection becomes active
522        if (mActiveConnections.indexOf(connection) < 0) {
523            mActiveConnections.add(connection);
524        }
525    } else {
526        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
527            handle, connection.get());
528    }
529
530
531    // we are setup, now enable the sensor.
532    status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE);
533
534    if (err != NO_ERROR) {
535        // enable has failed, reset state in SensorDevice.
536        status_t resetErr = sensor ? sensor->resetStateWithoutActuatingHardware(connection.get(),
537                handle) : status_t(BAD_VALUE);
538        // enable has failed, reset our state.
539        cleanupWithoutDisable(connection, handle);
540    }
541    return err;
542}
543
544status_t SensorService::disable(const sp<SensorEventConnection>& connection,
545        int handle)
546{
547    if (mInitCheck != NO_ERROR)
548        return mInitCheck;
549
550    status_t err = cleanupWithoutDisable(connection, handle);
551    if (err == NO_ERROR) {
552        SensorInterface* sensor = mSensorMap.valueFor(handle);
553        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
554    }
555    return err;
556}
557
558status_t SensorService::cleanupWithoutDisable(const sp<SensorEventConnection>& connection,
559        int handle) {
560    Mutex::Autolock _l(mLock);
561    SensorRecord* rec = mActiveSensors.valueFor(handle);
562    if (rec) {
563        // see if this connection becomes inactive
564        if (connection->removeSensor(handle)) {
565            BatteryService::disableSensor(connection->getUid(), handle);
566        }
567        if (connection->hasAnySensor() == false) {
568            mActiveConnections.remove(connection);
569        }
570        // see if this sensor becomes inactive
571        if (rec->removeConnection(connection)) {
572            mActiveSensors.removeItem(handle);
573            mActiveVirtualSensors.removeItem(handle);
574            delete rec;
575        }
576        return NO_ERROR;
577    }
578    return BAD_VALUE;
579}
580
581status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
582        int handle, nsecs_t ns)
583{
584    if (mInitCheck != NO_ERROR)
585        return mInitCheck;
586
587    SensorInterface* sensor = mSensorMap.valueFor(handle);
588    if (!sensor)
589        return BAD_VALUE;
590
591    if (ns < 0)
592        return BAD_VALUE;
593
594    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
595    if (ns < minDelayNs) {
596        ns = minDelayNs;
597    }
598
599    if (ns < MINIMUM_EVENTS_PERIOD)
600        ns = MINIMUM_EVENTS_PERIOD;
601
602    return sensor->setDelay(connection.get(), handle, ns);
603}
604
605// ---------------------------------------------------------------------------
606
607SensorService::SensorRecord::SensorRecord(
608        const sp<SensorEventConnection>& connection)
609{
610    mConnections.add(connection);
611}
612
613bool SensorService::SensorRecord::addConnection(
614        const sp<SensorEventConnection>& connection)
615{
616    if (mConnections.indexOf(connection) < 0) {
617        mConnections.add(connection);
618        return true;
619    }
620    return false;
621}
622
623bool SensorService::SensorRecord::removeConnection(
624        const wp<SensorEventConnection>& connection)
625{
626    ssize_t index = mConnections.indexOf(connection);
627    if (index >= 0) {
628        mConnections.removeItemsAt(index, 1);
629    }
630    return mConnections.size() ? false : true;
631}
632
633// ---------------------------------------------------------------------------
634
635SensorService::SensorEventConnection::SensorEventConnection(
636        const sp<SensorService>& service, uid_t uid)
637    : mService(service), mChannel(new BitTube()), mUid(uid)
638{
639}
640
641SensorService::SensorEventConnection::~SensorEventConnection()
642{
643    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
644    mService->cleanupConnection(this);
645}
646
647void SensorService::SensorEventConnection::onFirstRef()
648{
649}
650
651bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
652    Mutex::Autolock _l(mConnectionLock);
653    if (mSensorInfo.indexOf(handle) < 0) {
654        mSensorInfo.add(handle);
655        return true;
656    }
657    return false;
658}
659
660bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
661    Mutex::Autolock _l(mConnectionLock);
662    if (mSensorInfo.remove(handle) >= 0) {
663        return true;
664    }
665    return false;
666}
667
668bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
669    Mutex::Autolock _l(mConnectionLock);
670    return mSensorInfo.indexOf(handle) >= 0;
671}
672
673bool SensorService::SensorEventConnection::hasAnySensor() const {
674    Mutex::Autolock _l(mConnectionLock);
675    return mSensorInfo.size() ? true : false;
676}
677
678status_t SensorService::SensorEventConnection::sendEvents(
679        sensors_event_t const* buffer, size_t numEvents,
680        sensors_event_t* scratch)
681{
682    // filter out events not for this connection
683    size_t count = 0;
684    if (scratch) {
685        Mutex::Autolock _l(mConnectionLock);
686        size_t i=0;
687        while (i<numEvents) {
688            const int32_t curr = buffer[i].sensor;
689            if (mSensorInfo.indexOf(curr) >= 0) {
690                do {
691                    scratch[count++] = buffer[i++];
692                } while ((i<numEvents) && (buffer[i].sensor == curr));
693            } else {
694                i++;
695            }
696        }
697    } else {
698        scratch = const_cast<sensors_event_t *>(buffer);
699        count = numEvents;
700    }
701
702    // NOTE: ASensorEvent and sensors_event_t are the same type
703    ssize_t size = SensorEventQueue::write(mChannel,
704            reinterpret_cast<ASensorEvent const*>(scratch), count);
705    if (size == -EAGAIN) {
706        // the destination doesn't accept events anymore, it's probably
707        // full. For now, we just drop the events on the floor.
708        //ALOGW("dropping %d events on the floor", count);
709        return size;
710    }
711
712    return size < 0 ? status_t(size) : status_t(NO_ERROR);
713}
714
715sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
716{
717    return mChannel;
718}
719
720status_t SensorService::SensorEventConnection::enableDisable(
721        int handle, bool enabled)
722{
723    status_t err;
724    if (enabled) {
725        err = mService->enable(this, handle);
726    } else {
727        err = mService->disable(this, handle);
728    }
729    return err;
730}
731
732status_t SensorService::SensorEventConnection::setEventRate(
733        int handle, nsecs_t ns)
734{
735    return mService->setEventRate(this, handle, ns);
736}
737
738// ---------------------------------------------------------------------------
739}; // namespace android
740
741