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